]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Fri, 30 Aug 2024 18:38:33 +0000 (14:38 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 30 Aug 2024 18:38:33 +0000 (14:38 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
15 files changed:
queue-6.1/asoc-amd-acp-fix-module-autoloading.patch [new file with mode: 0644]
queue-6.1/asoc-sof-amd-fix-for-acp-init-sequence.patch [new file with mode: 0644]
queue-6.1/cifs-fix-falloc_fl_punch_hole-support.patch [new file with mode: 0644]
queue-6.1/mm-fix-missing-folio-invalidation-calls-during-trunc.patch [new file with mode: 0644]
queue-6.1/mmc-avoid-open-coding-by-using-mmc_op_tuning.patch [new file with mode: 0644]
queue-6.1/mmc-mtk-sd-receive-cmd8-data-when-hs400-tuning-fail.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-check-add_addr_accept_max-before-accepting-.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-only-mark-subflow-endp-as-available.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-remove-mptcp_pm_remove_subflow.patch [new file with mode: 0644]
queue-6.1/mptcp-unify-pm-get_local_id-interfaces.patch [new file with mode: 0644]
queue-6.1/of-introduce-for_each_-_child_of_node_scoped-to-auto.patch [new file with mode: 0644]
queue-6.1/pinctrl-mediatek-common-v2-fix-broken-bias-disable-f.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/thermal-of-fix-of-node-leak-in-of_thermal_zone_find-.patch [new file with mode: 0644]
queue-6.1/thermal-of-fix-of-node-leak-in-thermal_of_trips_init.patch [new file with mode: 0644]

diff --git a/queue-6.1/asoc-amd-acp-fix-module-autoloading.patch b/queue-6.1/asoc-amd-acp-fix-module-autoloading.patch
new file mode 100644 (file)
index 0000000..ac8f4f8
--- /dev/null
@@ -0,0 +1,37 @@
+From 3883d83874a301ffa3ade80ac02bf55ef0ae4582 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Aug 2024 08:49:23 +0000
+Subject: ASoC: amd: acp: fix module autoloading
+
+From: Yuntao Liu <liuyuntao12@huawei.com>
+
+[ Upstream commit 164199615ae230ace4519141285f06766d6d8036 ]
+
+Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded
+based on the alias from platform_device_id table.
+
+Fixes: 9d8a7be88b336 ("ASoC: amd: acp: Add legacy sound card support for Chrome audio")
+Signed-off-by: Yuntao Liu <liuyuntao12@huawei.com>
+Link: https://patch.msgid.link/20240815084923.756476-1-liuyuntao12@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/acp/acp-legacy-mach.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/amd/acp/acp-legacy-mach.c b/sound/soc/amd/acp/acp-legacy-mach.c
+index 1f4878ff7d372..2f98f3da0ad0b 100644
+--- a/sound/soc/amd/acp/acp-legacy-mach.c
++++ b/sound/soc/amd/acp/acp-legacy-mach.c
+@@ -144,6 +144,8 @@ static const struct platform_device_id board_ids[] = {
+       },
+       { }
+ };
++MODULE_DEVICE_TABLE(platform, board_ids);
++
+ static struct platform_driver acp_asoc_audio = {
+       .driver = {
+               .pm = &snd_soc_pm_ops,
+-- 
+2.43.0
+
diff --git a/queue-6.1/asoc-sof-amd-fix-for-acp-init-sequence.patch b/queue-6.1/asoc-sof-amd-fix-for-acp-init-sequence.patch
new file mode 100644 (file)
index 0000000..8584dc1
--- /dev/null
@@ -0,0 +1,86 @@
+From 4f8c77a098731def9cd5d3eb4d240eab32e71182 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Aug 2024 12:33:28 +0530
+Subject: ASoC: SOF: amd: Fix for acp init sequence
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit a42db293e5983aa1508d12644f23d73f0553b32c ]
+
+When ACP is not powered on by default, acp power on sequence explicitly
+invoked by programming pgfsm control mask. The existing implementation
+checks the same PGFSM status mask and programs the same PGFSM control mask
+in all ACP variants which breaks acp power on sequence for ACP6.0 and
+ACP6.3 variants. So to fix this issue, update ACP pgfsm control mask and
+status mask based on acp descriptor rev field, which will vary based on
+acp variant.
+
+Fixes: 846aef1d7cc0 ("ASoC: SOF: amd: Add Renoir ACP HW support")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Link: https://patch.msgid.link/20240816070328.610360-1-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/amd/acp.c | 19 +++++++++++++++++--
+ sound/soc/sof/amd/acp.h |  7 +++++--
+ 2 files changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
+index f8d2372a758f4..e4e046d4778e2 100644
+--- a/sound/soc/sof/amd/acp.c
++++ b/sound/soc/sof/amd/acp.c
+@@ -363,6 +363,7 @@ static int acp_power_on(struct snd_sof_dev *sdev)
+       const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
+       unsigned int base = desc->pgfsm_base;
+       unsigned int val;
++      unsigned int acp_pgfsm_status_mask, acp_pgfsm_cntl_mask;
+       int ret;
+       val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + PGFSM_STATUS_OFFSET);
+@@ -370,9 +371,23 @@ static int acp_power_on(struct snd_sof_dev *sdev)
+       if (val == ACP_POWERED_ON)
+               return 0;
+-      if (val & ACP_PGFSM_STATUS_MASK)
++      switch (desc->rev) {
++      case 3:
++      case 5:
++              acp_pgfsm_status_mask = ACP3X_PGFSM_STATUS_MASK;
++              acp_pgfsm_cntl_mask = ACP3X_PGFSM_CNTL_POWER_ON_MASK;
++              break;
++      case 6:
++              acp_pgfsm_status_mask = ACP6X_PGFSM_STATUS_MASK;
++              acp_pgfsm_cntl_mask = ACP6X_PGFSM_CNTL_POWER_ON_MASK;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      if (val & acp_pgfsm_status_mask)
+               snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + PGFSM_CONTROL_OFFSET,
+-                                ACP_PGFSM_CNTL_POWER_ON_MASK);
++                                acp_pgfsm_cntl_mask);
+       ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, base + PGFSM_STATUS_OFFSET, val,
+                                           !val, ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
+diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
+index 14148c311f504..b1414ac1ea985 100644
+--- a/sound/soc/sof/amd/acp.h
++++ b/sound/soc/sof/amd/acp.h
+@@ -22,8 +22,11 @@
+ #define ACP_REG_POLL_TIMEOUT_US                 2000
+ #define ACP_DMA_COMPLETE_TIMEOUT_US           5000
+-#define ACP_PGFSM_CNTL_POWER_ON_MASK          0x01
+-#define ACP_PGFSM_STATUS_MASK                 0x03
++#define ACP3X_PGFSM_CNTL_POWER_ON_MASK                0x01
++#define ACP3X_PGFSM_STATUS_MASK                       0x03
++#define ACP6X_PGFSM_CNTL_POWER_ON_MASK                0x07
++#define ACP6X_PGFSM_STATUS_MASK                       0x0F
++
+ #define ACP_POWERED_ON                                0x00
+ #define ACP_ASSERT_RESET                      0x01
+ #define ACP_RELEASE_RESET                     0x00
+-- 
+2.43.0
+
diff --git a/queue-6.1/cifs-fix-falloc_fl_punch_hole-support.patch b/queue-6.1/cifs-fix-falloc_fl_punch_hole-support.patch
new file mode 100644 (file)
index 0000000..5b95269
--- /dev/null
@@ -0,0 +1,105 @@
+From eb9c3d155197ad243b223f434bd2019955cde685 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Aug 2024 14:22:42 +0100
+Subject: cifs: Fix FALLOC_FL_PUNCH_HOLE support
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 416871f4fb84bc96822562e654941d5625a25bf8 ]
+
+The cifs filesystem doesn't quite emulate FALLOC_FL_PUNCH_HOLE correctly
+(note that due to lack of protocol support, it can't actually implement it
+directly).  Whilst it will (partially) invalidate dirty folios in the
+pagecache, it doesn't write them back first, and so the EOF marker on the
+server may be lower than inode->i_size.
+
+This presents a problem, however, as if the punched hole invalidates the
+tail of the locally cached dirty data, writeback won't know it needs to
+move the EOF over to account for the hole punch (which isn't supposed to
+move the EOF).  We could just write zeroes over the punched out region of
+the pagecache and write that back - but this is supposed to be a
+deallocatory operation.
+
+Fix this by manually moving the EOF over on the server after the operation
+if the hole punched would corrupt it.
+
+Note that the FSCTL_SET_ZERO_DATA RPC and the setting of the EOF should
+probably be compounded to stop a third party interfering (or, at least,
+massively reduce the chance).
+
+This was reproducible occasionally by using fsx with the following script:
+
+       truncate 0x0 0x375e2 0x0
+       punch_hole 0x2f6d3 0x6ab5 0x375e2
+       truncate 0x0 0x3a71f 0x375e2
+       mapread 0xee05 0xcf12 0x3a71f
+       write 0x2078e 0x5604 0x3a71f
+       write 0x3ebdf 0x1421 0x3a71f *
+       punch_hole 0x379d0 0x8630 0x40000 *
+       mapread 0x2aaa2 0x85b 0x40000
+       fallocate 0x1b401 0x9ada 0x40000
+       read 0x15f2 0x7d32 0x40000
+       read 0x32f37 0x7a3b 0x40000 *
+
+The second "write" should extend the EOF to 0x40000, and the "punch_hole"
+should operate inside of that - but that depends on whether the VM gets in
+and writes back the data first.  If it doesn't, the file ends up 0x3a71f in
+size, not 0x40000.
+
+Fixes: 31742c5a3317 ("enable fallocate punch hole ("fallocate -p") for SMB3")
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Steve French <sfrench@samba.org>
+cc: Paulo Alcantara <pc@manguebit.com>
+cc: Shyam Prasad N <nspmangalore@gmail.com>
+cc: Jeff Layton <jlayton@kernel.org>
+cc: linux-cifs@vger.kernel.org
+cc: netfs@lists.linux.dev
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2ops.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index 2291081653a85..a3c4af2fb6897 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -3510,6 +3510,7 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
+       struct inode *inode = file_inode(file);
+       struct cifsFileInfo *cfile = file->private_data;
+       struct file_zero_data_information fsctl_buf;
++      unsigned long long end = offset + len, i_size, remote_i_size;
+       long rc;
+       unsigned int xid;
+       __u8 set_sparse = 1;
+@@ -3541,6 +3542,27 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
+                       (char *)&fsctl_buf,
+                       sizeof(struct file_zero_data_information),
+                       CIFSMaxBufSize, NULL, NULL);
++
++      if (rc)
++              goto unlock;
++
++      /* If there's dirty data in the buffer that would extend the EOF if it
++       * were written, then we need to move the EOF marker over to the lower
++       * of the high end of the hole and the proposed EOF.  The problem is
++       * that we locally hole-punch the tail of the dirty data, the proposed
++       * EOF update will end up in the wrong place.
++       */
++      i_size = i_size_read(inode);
++      remote_i_size = netfs_inode(inode)->remote_i_size;
++      if (end > remote_i_size && i_size > remote_i_size) {
++              unsigned long long extend_to = umin(end, i_size);
++              rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
++                                cfile->fid.volatile_fid, cfile->pid, extend_to);
++              if (rc >= 0)
++                      netfs_inode(inode)->remote_i_size = extend_to;
++      }
++
++unlock:
+       filemap_invalidate_unlock(inode->i_mapping);
+ out:
+       inode_unlock(inode);
+-- 
+2.43.0
+
diff --git a/queue-6.1/mm-fix-missing-folio-invalidation-calls-during-trunc.patch b/queue-6.1/mm-fix-missing-folio-invalidation-calls-during-trunc.patch
new file mode 100644 (file)
index 0000000..7205091
--- /dev/null
@@ -0,0 +1,66 @@
+From 6d54b7804999c9b9f69f8ad3b53b4842b2fd0871 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Aug 2024 21:08:09 +0100
+Subject: mm: Fix missing folio invalidation calls during truncation
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 0aa2e1b2fb7a75aa4b5b4347055ccfea6f091769 ]
+
+When AS_RELEASE_ALWAYS is set on a mapping, the ->release_folio() and
+->invalidate_folio() calls should be invoked even if PG_private and
+PG_private_2 aren't set.  This is used by netfslib to keep track of the
+point above which reads can be skipped in favour of just zeroing pagecache
+locally.
+
+There are a couple of places in truncation in which invalidation is only
+called when folio_has_private() is true.  Fix these to check
+folio_needs_release() instead.
+
+Without this, the generic/075 and generic/112 xfstests (both fsx-based
+tests) fail with minimum folio size patches applied[1].
+
+Fixes: b4fa966f03b7 ("mm, netfs, fscache: stop read optimisation when folio removed from pagecache")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Link: https://lore.kernel.org/r/20240815090849.972355-1-kernel@pankajraghav.com/ [1]
+Link: https://lore.kernel.org/r/20240823200819.532106-2-dhowells@redhat.com
+Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+cc: Pankaj Raghav <p.raghav@samsung.com>
+cc: Jeff Layton <jlayton@kernel.org>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+cc: netfs@lists.linux.dev
+cc: linux-mm@kvack.org
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/truncate.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/truncate.c b/mm/truncate.c
+index 0d4dd233f5187..96e9812667db2 100644
+--- a/mm/truncate.c
++++ b/mm/truncate.c
+@@ -174,7 +174,7 @@ static void truncate_cleanup_folio(struct folio *folio)
+       if (folio_mapped(folio))
+               unmap_mapping_folio(folio);
+-      if (folio_has_private(folio))
++      if (folio_needs_release(folio))
+               folio_invalidate(folio, 0, folio_size(folio));
+       /*
+@@ -235,7 +235,7 @@ bool truncate_inode_partial_folio(struct folio *folio, loff_t start, loff_t end)
+        */
+       folio_zero_range(folio, offset, length);
+-      if (folio_has_private(folio))
++      if (folio_needs_release(folio))
+               folio_invalidate(folio, offset, length);
+       if (!folio_test_large(folio))
+               return true;
+-- 
+2.43.0
+
diff --git a/queue-6.1/mmc-avoid-open-coding-by-using-mmc_op_tuning.patch b/queue-6.1/mmc-avoid-open-coding-by-using-mmc_op_tuning.patch
new file mode 100644 (file)
index 0000000..8da41bc
--- /dev/null
@@ -0,0 +1,166 @@
+From 667834acbf2eb7f97dbe320c33cbd067cdf09a89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Nov 2022 17:00:31 +0900
+Subject: mmc: Avoid open coding by using mmc_op_tuning()
+
+From: ChanWoo Lee <cw9316.lee@samsung.com>
+
+[ Upstream commit b98e7e8daf0ebab9dcc36812378a71e1be0b5089 ]
+
+Replace code with the already defined function. No functional changes.
+
+Signed-off-by: ChanWoo Lee <cw9316.lee@samsung.com>
+Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20221124080031.14690-1-cw9316.lee@samsung.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 9374ae912dbb ("mmc: mtk-sd: receive cmd8 data when hs400 tuning fail")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/core.c              | 3 +--
+ drivers/mmc/host/dw_mmc.c            | 3 +--
+ drivers/mmc/host/mtk-sd.c            | 8 ++------
+ drivers/mmc/host/sdhci-msm.c         | 3 +--
+ drivers/mmc/host/sdhci-pci-o2micro.c | 3 +--
+ drivers/mmc/host/sdhci-tegra.c       | 8 ++------
+ drivers/mmc/host/sdhci.c             | 9 ++-------
+ 7 files changed, 10 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index df85c35a86a3b..fc2fca5325ba5 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -142,8 +142,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
+       int err = cmd->error;
+       /* Flag re-tuning needed on CRC errors */
+-      if (cmd->opcode != MMC_SEND_TUNING_BLOCK &&
+-          cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
++      if (!mmc_op_tuning(cmd->opcode) &&
+           !host->retune_crc_disable &&
+           (err == -EILSEQ || (mrq->sbc && mrq->sbc->error == -EILSEQ) ||
+           (mrq->data && mrq->data->error == -EILSEQ) ||
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index a0ccf88876f98..d0da4573b38cd 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -334,8 +334,7 @@ static u32 dw_mci_prep_stop_abort(struct dw_mci *host, struct mmc_command *cmd)
+           cmdr == MMC_READ_MULTIPLE_BLOCK ||
+           cmdr == MMC_WRITE_BLOCK ||
+           cmdr == MMC_WRITE_MULTIPLE_BLOCK ||
+-          cmdr == MMC_SEND_TUNING_BLOCK ||
+-          cmdr == MMC_SEND_TUNING_BLOCK_HS200 ||
++          mmc_op_tuning(cmdr) ||
+           cmdr == MMC_GEN_CMD) {
+               stop->opcode = MMC_STOP_TRANSMISSION;
+               stop->arg = 0;
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 70e414027155d..efd2af2d36862 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -1207,9 +1207,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
+       if (!sbc_error && !(events & MSDC_INT_CMDRDY)) {
+               if (events & MSDC_INT_CMDTMO ||
+-                  (cmd->opcode != MMC_SEND_TUNING_BLOCK &&
+-                   cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
+-                   !host->hs400_tuning))
++                  (!mmc_op_tuning(cmd->opcode) && !host->hs400_tuning))
+                       /*
+                        * should not clear fifo/interrupt as the tune data
+                        * may have alreay come when cmd19/cmd21 gets response
+@@ -1303,9 +1301,7 @@ static void msdc_cmd_next(struct msdc_host *host,
+ {
+       if ((cmd->error &&
+           !(cmd->error == -EILSEQ &&
+-            (cmd->opcode == MMC_SEND_TUNING_BLOCK ||
+-             cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200 ||
+-             host->hs400_tuning))) ||
++            (mmc_op_tuning(cmd->opcode) || host->hs400_tuning))) ||
+           (mrq->sbc && mrq->sbc->error))
+               msdc_request_done(host, mrq);
+       else if (cmd == mrq->sbc)
+diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
+index e37fb25577c0f..28bd562c439ef 100644
+--- a/drivers/mmc/host/sdhci-msm.c
++++ b/drivers/mmc/host/sdhci-msm.c
+@@ -2218,8 +2218,7 @@ static int __sdhci_msm_check_write(struct sdhci_host *host, u16 val, int reg)
+               if (!msm_host->use_cdr)
+                       break;
+               if ((msm_host->transfer_mode & SDHCI_TRNS_READ) &&
+-                  SDHCI_GET_CMD(val) != MMC_SEND_TUNING_BLOCK_HS200 &&
+-                  SDHCI_GET_CMD(val) != MMC_SEND_TUNING_BLOCK)
++                  !mmc_op_tuning(SDHCI_GET_CMD(val)))
+                       sdhci_msm_set_cdr(host, true);
+               else
+                       sdhci_msm_set_cdr(host, false);
+diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c
+index 24bb0e9809e76..cfa0956e7d72a 100644
+--- a/drivers/mmc/host/sdhci-pci-o2micro.c
++++ b/drivers/mmc/host/sdhci-pci-o2micro.c
+@@ -326,8 +326,7 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
+               (host->timing != MMC_TIMING_UHS_SDR50))
+               return sdhci_execute_tuning(mmc, opcode);
+-      if (WARN_ON((opcode != MMC_SEND_TUNING_BLOCK_HS200) &&
+-                      (opcode != MMC_SEND_TUNING_BLOCK)))
++      if (WARN_ON(!mmc_op_tuning(opcode)))
+               return -EINVAL;
+       /* Force power mode enter L0 */
+diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
+index 1adaa94c31aca..62d236bfe9377 100644
+--- a/drivers/mmc/host/sdhci-tegra.c
++++ b/drivers/mmc/host/sdhci-tegra.c
+@@ -268,13 +268,9 @@ static void tegra210_sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+ {
+       bool is_tuning_cmd = 0;
+       bool clk_enabled;
+-      u8 cmd;
+-      if (reg == SDHCI_COMMAND) {
+-              cmd = SDHCI_GET_CMD(val);
+-              is_tuning_cmd = cmd == MMC_SEND_TUNING_BLOCK ||
+-                              cmd == MMC_SEND_TUNING_BLOCK_HS200;
+-      }
++      if (reg == SDHCI_COMMAND)
++              is_tuning_cmd = mmc_op_tuning(SDHCI_GET_CMD(val));
+       if (is_tuning_cmd)
+               clk_enabled = tegra_sdhci_configure_card_clk(host, 0);
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 4237d8ae878c1..536d21028a116 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1712,8 +1712,7 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
+               flags |= SDHCI_CMD_INDEX;
+       /* CMD19 is special in that the Data Present Select should be set */
+-      if (cmd->data || cmd->opcode == MMC_SEND_TUNING_BLOCK ||
+-          cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200)
++      if (cmd->data || mmc_op_tuning(cmd->opcode))
+               flags |= SDHCI_CMD_DATA;
+       timeout = jiffies;
+@@ -3396,8 +3395,6 @@ static void sdhci_adma_show_error(struct sdhci_host *host)
+ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+ {
+-      u32 command;
+-
+       /*
+        * CMD19 generates _only_ Buffer Read Ready interrupt if
+        * use sdhci_send_tuning.
+@@ -3406,9 +3403,7 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+        * SDHCI_INT_DATA_AVAIL always there, stuck in irq storm.
+        */
+       if (intmask & SDHCI_INT_DATA_AVAIL && !host->data) {
+-              command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND));
+-              if (command == MMC_SEND_TUNING_BLOCK ||
+-                  command == MMC_SEND_TUNING_BLOCK_HS200) {
++              if (mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)))) {
+                       host->tuning_done = 1;
+                       wake_up(&host->buf_ready_int);
+                       return;
+-- 
+2.43.0
+
diff --git a/queue-6.1/mmc-mtk-sd-receive-cmd8-data-when-hs400-tuning-fail.patch b/queue-6.1/mmc-mtk-sd-receive-cmd8-data-when-hs400-tuning-fail.patch
new file mode 100644 (file)
index 0000000..57b559b
--- /dev/null
@@ -0,0 +1,54 @@
+From 06c238db53c5a3e926c248c7817c3041e7cf36a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Jul 2024 09:37:04 +0800
+Subject: mmc: mtk-sd: receive cmd8 data when hs400 tuning fail
+
+From: Mengqi Zhang <mengqi.zhang@mediatek.com>
+
+[ Upstream commit 9374ae912dbb1eed8139ed75fd2c0f1b30ca454d ]
+
+When we use cmd8 as the tuning command in hs400 mode, the command
+response sent back by some eMMC devices cannot be correctly sampled
+by MTK eMMC controller at some weak sample timing. In this case,
+command timeout error may occur. So we must receive the following
+data to make sure the next cmd8 send correctly.
+
+Signed-off-by: Mengqi Zhang <mengqi.zhang@mediatek.com>
+Fixes: c4ac38c6539b ("mmc: mtk-sd: Add HS400 online tuning support")
+Cc: stable@vger.stable.com
+Link: https://lore.kernel.org/r/20240716013704.10578-1-mengqi.zhang@mediatek.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/mtk-sd.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index efd2af2d36862..ba18e9fa64b15 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -1206,7 +1206,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
+       }
+       if (!sbc_error && !(events & MSDC_INT_CMDRDY)) {
+-              if (events & MSDC_INT_CMDTMO ||
++              if ((events & MSDC_INT_CMDTMO && !host->hs400_tuning) ||
+                   (!mmc_op_tuning(cmd->opcode) && !host->hs400_tuning))
+                       /*
+                        * should not clear fifo/interrupt as the tune data
+@@ -1299,9 +1299,9 @@ static void msdc_start_command(struct msdc_host *host,
+ static void msdc_cmd_next(struct msdc_host *host,
+               struct mmc_request *mrq, struct mmc_command *cmd)
+ {
+-      if ((cmd->error &&
+-          !(cmd->error == -EILSEQ &&
+-            (mmc_op_tuning(cmd->opcode) || host->hs400_tuning))) ||
++      if ((cmd->error && !host->hs400_tuning &&
++           !(cmd->error == -EILSEQ &&
++           mmc_op_tuning(cmd->opcode))) ||
+           (mrq->sbc && mrq->sbc->error))
+               msdc_request_done(host, mrq);
+       else if (cmd == mrq->sbc)
+-- 
+2.43.0
+
diff --git a/queue-6.1/mptcp-pm-check-add_addr_accept_max-before-accepting-.patch b/queue-6.1/mptcp-pm-check-add_addr_accept_max-before-accepting-.patch
new file mode 100644 (file)
index 0000000..e046ccd
--- /dev/null
@@ -0,0 +1,41 @@
+From d1c5f7b0694f3daf21351597a8f311400f8bee9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 21:45:28 +0200
+Subject: mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR
+
+From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+
+[ Upstream commit 0137a3c7c2ea3f9df8ebfc65d78b4ba712a187bb ]
+
+The limits might have changed in between, it is best to check them
+before accepting new ADD_ADDR.
+
+Fixes: d0876b2284cf ("mptcp: add the incoming RM_ADDR support")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20240819-net-mptcp-pm-reusing-id-v1-10-38035d40de5b@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/pm_netlink.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
+index d546e17063f75..9e16ae1b23fc7 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -870,8 +870,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
+                       /* Note: if the subflow has been closed before, this
+                        * add_addr_accepted counter will not be decremented.
+                        */
+-                      msk->pm.add_addr_accepted--;
+-                      WRITE_ONCE(msk->pm.accept_addr, true);
++                      if (--msk->pm.add_addr_accepted < mptcp_pm_get_add_addr_accept_max(msk))
++                              WRITE_ONCE(msk->pm.accept_addr, true);
+               }
+       }
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.1/mptcp-pm-only-mark-subflow-endp-as-available.patch b/queue-6.1/mptcp-pm-only-mark-subflow-endp-as-available.patch
new file mode 100644 (file)
index 0000000..49a797a
--- /dev/null
@@ -0,0 +1,119 @@
+From 02f8f54a5939e411f888b6c2e3dbd40fad7bc428 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 21:45:26 +0200
+Subject: mptcp: pm: only mark 'subflow' endp as available
+
+From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+
+[ Upstream commit 322ea3778965da72862cca2a0c50253aacf65fe6 ]
+
+Adding the following warning ...
+
+  WARN_ON_ONCE(msk->pm.local_addr_used == 0)
+
+... before decrementing the local_addr_used counter helped to find a bug
+when running the "remove single address" subtest from the mptcp_join.sh
+selftests.
+
+Removing a 'signal' endpoint will trigger the removal of all subflows
+linked to this endpoint via mptcp_pm_nl_rm_addr_or_subflow() with
+rm_type == MPTCP_MIB_RMSUBFLOW. This will decrement the local_addr_used
+counter, which is wrong in this case because this counter is linked to
+'subflow' endpoints, and here it is a 'signal' endpoint that is being
+removed.
+
+Now, the counter is decremented, only if the ID is being used outside
+of mptcp_pm_nl_rm_addr_or_subflow(), only for 'subflow' endpoints, and
+if the ID is not 0 -- local_addr_used is not taking into account these
+ones. This marking of the ID as being available, and the decrement is
+done no matter if a subflow using this ID is currently available,
+because the subflow could have been closed before.
+
+Fixes: 06faa2271034 ("mptcp: remove multi addresses and subflows in PM")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20240819-net-mptcp-pm-reusing-id-v1-8-38035d40de5b@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/pm_netlink.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
+index 3b3e656a2ab09..d546e17063f75 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -855,10 +855,10 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
+                       if (rm_type == MPTCP_MIB_RMSUBFLOW)
+                               __MPTCP_INC_STATS(sock_net(sk), rm_type);
+               }
+-              if (rm_type == MPTCP_MIB_RMSUBFLOW)
+-                      __set_bit(rm_id ? rm_id : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap);
+-              else if (rm_type == MPTCP_MIB_RMADDR)
++
++              if (rm_type == MPTCP_MIB_RMADDR)
+                       __MPTCP_INC_STATS(sock_net(sk), rm_type);
++
+               if (!removed)
+                       continue;
+@@ -872,8 +872,6 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
+                        */
+                       msk->pm.add_addr_accepted--;
+                       WRITE_ONCE(msk->pm.accept_addr, true);
+-              } else if (rm_type == MPTCP_MIB_RMSUBFLOW) {
+-                      msk->pm.local_addr_used--;
+               }
+       }
+ }
+@@ -1496,6 +1494,14 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
+       return ret;
+ }
++static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id)
++{
++      /* If it was marked as used, and not ID 0, decrement local_addr_used */
++      if (!__test_and_set_bit(id ? : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap) &&
++          id && !WARN_ON_ONCE(msk->pm.local_addr_used == 0))
++              msk->pm.local_addr_used--;
++}
++
+ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
+                                                  const struct mptcp_pm_addr_entry *entry)
+ {
+@@ -1529,11 +1535,11 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
+                       spin_lock_bh(&msk->pm.lock);
+                       mptcp_pm_nl_rm_subflow_received(msk, &list);
+                       spin_unlock_bh(&msk->pm.lock);
+-              } else if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
+-                      /* If the subflow has been used, but now closed */
++              }
++
++              if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
+                       spin_lock_bh(&msk->pm.lock);
+-                      if (!__test_and_set_bit(entry->addr.id, msk->pm.id_avail_bitmap))
+-                              msk->pm.local_addr_used--;
++                      __mark_subflow_endp_available(msk, list.ids[0]);
+                       spin_unlock_bh(&msk->pm.lock);
+               }
+@@ -1573,6 +1579,7 @@ static int mptcp_nl_remove_id_zero_address(struct net *net,
+               spin_lock_bh(&msk->pm.lock);
+               mptcp_pm_remove_addr(msk, &list);
+               mptcp_pm_nl_rm_subflow_received(msk, &list);
++              __mark_subflow_endp_available(msk, 0);
+               spin_unlock_bh(&msk->pm.lock);
+               release_sock(sk);
+@@ -1965,6 +1972,7 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
+       spin_lock_bh(&msk->pm.lock);
+       mptcp_pm_nl_rm_subflow_received(msk, &list);
++      __mark_subflow_endp_available(msk, list.ids[0]);
+       mptcp_pm_create_subflow_or_signal_addr(msk);
+       spin_unlock_bh(&msk->pm.lock);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.1/mptcp-pm-remove-mptcp_pm_remove_subflow.patch b/queue-6.1/mptcp-pm-remove-mptcp_pm_remove_subflow.patch
new file mode 100644 (file)
index 0000000..bfffbab
--- /dev/null
@@ -0,0 +1,130 @@
+From b72fcbd3560ae7ba22c21f721bc98baa8053cd51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 21:45:25 +0200
+Subject: mptcp: pm: remove mptcp_pm_remove_subflow()
+
+From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+
+[ Upstream commit f448451aa62d54be16acb0034223c17e0d12bc69 ]
+
+This helper is confusing. It is in pm.c, but it is specific to the
+in-kernel PM and it cannot be used by the userspace one. Also, it simply
+calls one in-kernel specific function with the PM lock, while the
+similar mptcp_pm_remove_addr() helper requires the PM lock.
+
+What's left is the pr_debug(), which is not that useful, because a
+similar one is present in the only function called by this helper:
+
+  mptcp_pm_nl_rm_subflow_received()
+
+After these modifications, this helper can be marked as 'static', and
+the lock can be taken only once in mptcp_pm_flush_addrs_and_subflows().
+
+Note that it is not a bug fix, but it will help backporting the
+following commits.
+
+Fixes: 0ee4261a3681 ("mptcp: implement mptcp_pm_remove_subflow")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20240819-net-mptcp-pm-reusing-id-v1-7-38035d40de5b@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/pm.c         | 10 ----------
+ net/mptcp/pm_netlink.c | 16 +++++++---------
+ net/mptcp/protocol.h   |  3 ---
+ 3 files changed, 7 insertions(+), 22 deletions(-)
+
+diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
+index 5d9baade5c3b4..5646c7275a92d 100644
+--- a/net/mptcp/pm.c
++++ b/net/mptcp/pm.c
+@@ -59,16 +59,6 @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_
+       return 0;
+ }
+-int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list)
+-{
+-      pr_debug("msk=%p, rm_list_nr=%d", msk, rm_list->nr);
+-
+-      spin_lock_bh(&msk->pm.lock);
+-      mptcp_pm_nl_rm_subflow_received(msk, rm_list);
+-      spin_unlock_bh(&msk->pm.lock);
+-      return 0;
+-}
+-
+ /* path manager event handlers */
+ void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side)
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
+index 6a85e9665080c..3b3e656a2ab09 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -883,8 +883,8 @@ static void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
+       mptcp_pm_nl_rm_addr_or_subflow(msk, &msk->pm.rm_list_rx, MPTCP_MIB_RMADDR);
+ }
+-void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
+-                                   const struct mptcp_rm_list *rm_list)
++static void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
++                                          const struct mptcp_rm_list *rm_list)
+ {
+       mptcp_pm_nl_rm_addr_or_subflow(msk, rm_list, MPTCP_MIB_RMSUBFLOW);
+ }
+@@ -1526,7 +1526,9 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
+                                         !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
+               if (remove_subflow) {
+-                      mptcp_pm_remove_subflow(msk, &list);
++                      spin_lock_bh(&msk->pm.lock);
++                      mptcp_pm_nl_rm_subflow_received(msk, &list);
++                      spin_unlock_bh(&msk->pm.lock);
+               } else if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
+                       /* If the subflow has been used, but now closed */
+                       spin_lock_bh(&msk->pm.lock);
+@@ -1674,18 +1676,14 @@ void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
+                       alist.ids[alist.nr++] = entry->addr.id;
+       }
++      spin_lock_bh(&msk->pm.lock);
+       if (alist.nr) {
+-              spin_lock_bh(&msk->pm.lock);
+               msk->pm.add_addr_signaled -= alist.nr;
+               mptcp_pm_remove_addr(msk, &alist);
+-              spin_unlock_bh(&msk->pm.lock);
+       }
+-
+       if (slist.nr)
+-              mptcp_pm_remove_subflow(msk, &slist);
+-
++              mptcp_pm_nl_rm_subflow_received(msk, &slist);
+       /* Reset counters: maybe some subflows have been removed before */
+-      spin_lock_bh(&msk->pm.lock);
+       bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+       msk->pm.local_addr_used = 0;
+       spin_unlock_bh(&msk->pm.lock);
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index b4d6710e6ca3a..c3cd68edab779 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -836,7 +836,6 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
+                          const struct mptcp_addr_info *addr,
+                          bool echo);
+ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
+-int mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
+ void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list);
+ void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
+                                       struct list_head *rm_list);
+@@ -931,8 +930,6 @@ static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflo
+ void __init mptcp_pm_nl_init(void);
+ void mptcp_pm_nl_work(struct mptcp_sock *msk);
+-void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
+-                                   const struct mptcp_rm_list *rm_list);
+ unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk);
+ unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk);
+ unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk);
+-- 
+2.43.0
+
diff --git a/queue-6.1/mptcp-unify-pm-get_local_id-interfaces.patch b/queue-6.1/mptcp-unify-pm-get_local_id-interfaces.patch
new file mode 100644 (file)
index 0000000..5b884b9
--- /dev/null
@@ -0,0 +1,134 @@
+From 664976ecba213942418060fc1dc468c1a158baf2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Jun 2023 15:20:50 +0200
+Subject: mptcp: unify pm get_local_id interfaces
+
+From: Geliang Tang <geliang.tang@suse.com>
+
+[ Upstream commit 9bbec87ecfe8a5c06710100a93e6b7e66f2cbbaf ]
+
+This patch unifies the three PM get_local_id() interfaces:
+
+mptcp_pm_nl_get_local_id() in mptcp/pm_netlink.c for the in-kernel PM and
+mptcp_userspace_pm_get_local_id() in mptcp/pm_userspace.c for the
+userspace PM.
+
+They'll be switched in the common PM infterface mptcp_pm_get_local_id()
+in mptcp/pm.c based on whether mptcp_pm_is_userspace() or not.
+
+Also put together the declarations of these three functions in protocol.h.
+
+Signed-off-by: Geliang Tang <geliang.tang@suse.com>
+Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Reviewed-by: Larysa Zaremba <larysa.zaremba@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: f448451aa62d ("mptcp: pm: remove mptcp_pm_remove_subflow()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/pm.c         | 18 +++++++++++++++++-
+ net/mptcp/pm_netlink.c | 22 +++-------------------
+ net/mptcp/protocol.h   |  2 +-
+ 3 files changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
+index 323fc823069ba..5d9baade5c3b4 100644
+--- a/net/mptcp/pm.c
++++ b/net/mptcp/pm.c
+@@ -415,7 +415,23 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
+ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
+ {
+-      return mptcp_pm_nl_get_local_id(msk, skc);
++      struct mptcp_addr_info skc_local;
++      struct mptcp_addr_info msk_local;
++
++      if (WARN_ON_ONCE(!msk))
++              return -1;
++
++      /* The 0 ID mapping is defined by the first subflow, copied into the msk
++       * addr
++       */
++      mptcp_local_address((struct sock_common *)msk, &msk_local);
++      mptcp_local_address((struct sock_common *)skc, &skc_local);
++      if (mptcp_addresses_equal(&msk_local, &skc_local, false))
++              return 0;
++
++      if (mptcp_pm_is_userspace(msk))
++              return mptcp_userspace_pm_get_local_id(msk, &skc_local);
++      return mptcp_pm_nl_get_local_id(msk, &skc_local);
+ }
+ bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc)
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
+index 6fb01e9768476..6a85e9665080c 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -1091,33 +1091,17 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
+       return 0;
+ }
+-int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
++int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
+ {
+       struct mptcp_pm_addr_entry *entry;
+-      struct mptcp_addr_info skc_local;
+-      struct mptcp_addr_info msk_local;
+       struct pm_nl_pernet *pernet;
+       int ret = -1;
+-      if (WARN_ON_ONCE(!msk))
+-              return -1;
+-
+-      /* The 0 ID mapping is defined by the first subflow, copied into the msk
+-       * addr
+-       */
+-      mptcp_local_address((struct sock_common *)msk, &msk_local);
+-      mptcp_local_address((struct sock_common *)skc, &skc_local);
+-      if (mptcp_addresses_equal(&msk_local, &skc_local, false))
+-              return 0;
+-
+-      if (mptcp_pm_is_userspace(msk))
+-              return mptcp_userspace_pm_get_local_id(msk, &skc_local);
+-
+       pernet = pm_nl_get_pernet_from_msk(msk);
+       rcu_read_lock();
+       list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
+-              if (mptcp_addresses_equal(&entry->addr, &skc_local, entry->addr.port)) {
++              if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) {
+                       ret = entry->addr.id;
+                       break;
+               }
+@@ -1131,7 +1115,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
+       if (!entry)
+               return -ENOMEM;
+-      entry->addr = skc_local;
++      entry->addr = *skc;
+       entry->addr.id = 0;
+       entry->addr.port = 0;
+       entry->ifindex = 0;
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index f6ec1e0bf6a99..b4d6710e6ca3a 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -914,6 +914,7 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
+ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
+                            struct mptcp_rm_list *rm_list);
+ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
++int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
+ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
+ bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc);
+ bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
+@@ -932,7 +933,6 @@ void __init mptcp_pm_nl_init(void);
+ void mptcp_pm_nl_work(struct mptcp_sock *msk);
+ void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
+                                    const struct mptcp_rm_list *rm_list);
+-int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
+ unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk);
+ unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk);
+ unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk);
+-- 
+2.43.0
+
diff --git a/queue-6.1/of-introduce-for_each_-_child_of_node_scoped-to-auto.patch b/queue-6.1/of-introduce-for_each_-_child_of_node_scoped-to-auto.patch
new file mode 100644 (file)
index 0000000..813a825
--- /dev/null
@@ -0,0 +1,65 @@
+From 939e15092e5fc17c7ce793f075caf8fdfaccd93c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Feb 2024 14:27:12 +0000
+Subject: of: Introduce for_each_*_child_of_node_scoped() to automate
+ of_node_put() handling
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 34af4554fb0ce164e2c4876683619eb1e23848d4 ]
+
+To avoid issues with out of order cleanup, or ambiguity about when the
+auto freed data is first instantiated, do it within the for loop definition.
+
+The disadvantage is that the struct device_node *child variable creation
+is not immediately obvious where this is used.
+However, in many cases, if there is another definition of
+struct device_node *child; the compiler / static analysers will notify us
+that it is unused, or uninitialized.
+
+Note that, in the vast majority of cases, the _available_ form should be
+used and as code is converted to these scoped handers, we should confirm
+that any cases that do not check for available have a good reason not
+to.
+
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20240225142714.286440-3-jic23@kernel.org
+Signed-off-by: Rob Herring <robh@kernel.org>
+Stable-dep-of: afc954fd223d ("thermal: of: Fix OF node leak in thermal_of_trips_init() error path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/of.h | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/include/linux/of.h b/include/linux/of.h
+index 506e30e4c959c..2960e609ca05e 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -1373,10 +1373,23 @@ static inline int of_property_read_s32(const struct device_node *np,
+ #define for_each_child_of_node(parent, child) \
+       for (child = of_get_next_child(parent, NULL); child != NULL; \
+            child = of_get_next_child(parent, child))
++
++#define for_each_child_of_node_scoped(parent, child) \
++      for (struct device_node *child __free(device_node) =            \
++           of_get_next_child(parent, NULL);                           \
++           child != NULL;                                             \
++           child = of_get_next_child(parent, child))
++
+ #define for_each_available_child_of_node(parent, child) \
+       for (child = of_get_next_available_child(parent, NULL); child != NULL; \
+            child = of_get_next_available_child(parent, child))
++#define for_each_available_child_of_node_scoped(parent, child) \
++      for (struct device_node *child __free(device_node) =            \
++           of_get_next_available_child(parent, NULL);                 \
++           child != NULL;                                             \
++           child = of_get_next_available_child(parent, child))
++
+ #define for_each_of_cpu_node(cpu) \
+       for (cpu = of_get_next_cpu_node(NULL); cpu != NULL; \
+            cpu = of_get_next_cpu_node(cpu))
+-- 
+2.43.0
+
diff --git a/queue-6.1/pinctrl-mediatek-common-v2-fix-broken-bias-disable-f.patch b/queue-6.1/pinctrl-mediatek-common-v2-fix-broken-bias-disable-f.patch
new file mode 100644 (file)
index 0000000..0b6189c
--- /dev/null
@@ -0,0 +1,184 @@
+From 76ce9b0c4f122986db788de37f2eb65b4652ec1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2024 19:27:09 -0400
+Subject: pinctrl: mediatek: common-v2: Fix broken bias-disable for
+ PULL_PU_PD_RSEL_TYPE
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: NĂ­colas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 166bf8af91225576f85208a31eaedbadd182d1ea ]
+
+Despite its name, commit fed74d75277d ("pinctrl: mediatek: common-v2:
+Fix bias-disable for PULL_PU_PD_RSEL_TYPE") actually broke bias-disable
+for PULL_PU_PD_RSEL_TYPE.
+
+mtk_pinconf_bias_set_combo() tries every bias method supported by the
+pin until one succeeds. For PULL_PU_PD_RSEL_TYPE pins, before the
+breaking commit, mtk_pinconf_bias_set_rsel() would be called first to
+try and set the RSEL value (as well as PU and PD), and if that failed,
+the only other valid option was that bias-disable was specified, which
+would then be handled by calling mtk_pinconf_bias_set_pu_pd() and
+disabling both PU and PD.
+
+The breaking commit misunderstood this logic and added an early "return
+0" in mtk_pinconf_bias_set_rsel(). The result was that in the
+bias-disable case, the bias was left unchanged, since by returning
+success, mtk_pinconf_bias_set_combo() no longer tried calling
+mtk_pinconf_bias_set_pu_pd() to disable the bias.
+
+Since the logic for configuring bias-disable on PULL_PU_PD_RSEL_TYPE
+pins required mtk_pinconf_bias_set_rsel() to fail first, in that case,
+an error was printed to the log, eg:
+
+  mt8195-pinctrl 10005000.pinctrl: Not support rsel value 0 Ohm for pin = 29 (GPIO29)
+
+This is what the breaking commit actually got rid of, and likely part of
+the reason why that commit was thought to be fixing functionality, while
+in reality it was breaking it.
+
+Instead of simply reverting that commit, restore the functionality but
+in a way that avoids the error from being printed and makes the code
+less confusing:
+* Return 0 explicitly if a bias method was successful
+* Introduce an extra function mtk_pinconf_bias_set_pu_pd_rsel() that
+  calls both mtk_pinconf_bias_set_rsel() (only if needed) and
+  mtk_pinconf_bias_set_pu_pd()
+  * And analogously for the corresponding getters
+
+Fixes: fed74d75277d ("pinctrl: mediatek: common-v2: Fix bias-disable for PULL_PU_PD_RSEL_TYPE")
+Signed-off-by: NĂ­colas F. R. A. Prado <nfraprado@collabora.com>
+Link: https://lore.kernel.org/20240808-mtk-rsel-bias-disable-fix-v1-1-1b4e85bf596c@collabora.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  | 55 ++++++++++---------
+ 1 file changed, 29 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+index b7921b59eb7b1..54301fbba524a 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -709,32 +709,35 @@ static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw,
+ {
+       int err, rsel_val;
+-      if (!pullup && arg == MTK_DISABLE)
+-              return 0;
+-
+       if (hw->rsel_si_unit) {
+               /* find pin rsel_index from pin_rsel array*/
+               err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val);
+               if (err)
+-                      goto out;
++                      return err;
+       } else {
+-              if (arg < MTK_PULL_SET_RSEL_000 ||
+-                  arg > MTK_PULL_SET_RSEL_111) {
+-                      err = -EINVAL;
+-                      goto out;
+-              }
++              if (arg < MTK_PULL_SET_RSEL_000 || arg > MTK_PULL_SET_RSEL_111)
++                      return -EINVAL;
+               rsel_val = arg - MTK_PULL_SET_RSEL_000;
+       }
+-      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
+-      if (err)
+-              goto out;
++      return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
++}
+-      err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, MTK_ENABLE);
++static int mtk_pinconf_bias_set_pu_pd_rsel(struct mtk_pinctrl *hw,
++                                         const struct mtk_pin_desc *desc,
++                                         u32 pullup, u32 arg)
++{
++      u32 enable = arg == MTK_DISABLE ? MTK_DISABLE : MTK_ENABLE;
++      int err;
+-out:
+-      return err;
++      if (arg != MTK_DISABLE) {
++              err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
++              if (err)
++                      return err;
++      }
++
++      return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable);
+ }
+ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+@@ -750,22 +753,22 @@ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+               try_all_type = MTK_PULL_TYPE_MASK;
+       if (try_all_type & MTK_PULL_RSEL_TYPE) {
+-              err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
++              err = mtk_pinconf_bias_set_pu_pd_rsel(hw, desc, pullup, arg);
+               if (!err)
+-                      return err;
++                      return 0;
+       }
+       if (try_all_type & MTK_PULL_PU_PD_TYPE) {
+               err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+               if (!err)
+-                      return err;
++                      return 0;
+       }
+       if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
+               err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc,
+                                                         pullup, arg);
+               if (!err)
+-                      return err;
++                      return 0;
+       }
+       if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
+@@ -803,9 +806,9 @@ static int mtk_rsel_get_si_unit(struct mtk_pinctrl *hw,
+       return 0;
+ }
+-static int mtk_pinconf_bias_get_rsel(struct mtk_pinctrl *hw,
+-                                   const struct mtk_pin_desc *desc,
+-                                   u32 *pullup, u32 *enable)
++static int mtk_pinconf_bias_get_pu_pd_rsel(struct mtk_pinctrl *hw,
++                                         const struct mtk_pin_desc *desc,
++                                         u32 *pullup, u32 *enable)
+ {
+       int pu, pd, rsel, err;
+@@ -939,22 +942,22 @@ int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
+               try_all_type = MTK_PULL_TYPE_MASK;
+       if (try_all_type & MTK_PULL_RSEL_TYPE) {
+-              err = mtk_pinconf_bias_get_rsel(hw, desc, pullup, enable);
++              err = mtk_pinconf_bias_get_pu_pd_rsel(hw, desc, pullup, enable);
+               if (!err)
+-                      return err;
++                      return 0;
+       }
+       if (try_all_type & MTK_PULL_PU_PD_TYPE) {
+               err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
+               if (!err)
+-                      return err;
++                      return 0;
+       }
+       if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
+               err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc,
+                                                         pullup, enable);
+               if (!err)
+-                      return err;
++                      return 0;
+       }
+       if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
+-- 
+2.43.0
+
index 5c35c9cddc85922a90c0ee04ca3272e45bbc51e5..fc9724ad64f8001d0fb2fdacbe90d1298c7fa7bf 100644 (file)
@@ -19,3 +19,17 @@ drm-amdgpu-align-pp_power_profile_mode-with-kernel-docs.patch
 drm-amdgpu-swsmu-always-force-a-state-reprogram-on-init.patch
 ata-libata-core-fix-null-pointer-dereference-on-error.patch
 usb-typec-fix-up-incorrectly-backported-usb-typec-tcpm-unregister-existing-source-caps-before-re-registration.patch
+mmc-avoid-open-coding-by-using-mmc_op_tuning.patch
+mmc-mtk-sd-receive-cmd8-data-when-hs400-tuning-fail.patch
+mptcp-unify-pm-get_local_id-interfaces.patch
+mptcp-pm-remove-mptcp_pm_remove_subflow.patch
+mptcp-pm-only-mark-subflow-endp-as-available.patch
+mptcp-pm-check-add_addr_accept_max-before-accepting-.patch
+of-introduce-for_each_-_child_of_node_scoped-to-auto.patch
+thermal-of-fix-of-node-leak-in-thermal_of_trips_init.patch
+thermal-of-fix-of-node-leak-in-of_thermal_zone_find-.patch
+asoc-amd-acp-fix-module-autoloading.patch
+asoc-sof-amd-fix-for-acp-init-sequence.patch
+pinctrl-mediatek-common-v2-fix-broken-bias-disable-f.patch
+mm-fix-missing-folio-invalidation-calls-during-trunc.patch
+cifs-fix-falloc_fl_punch_hole-support.patch
diff --git a/queue-6.1/thermal-of-fix-of-node-leak-in-of_thermal_zone_find-.patch b/queue-6.1/thermal-of-fix-of-node-leak-in-of_thermal_zone_find-.patch
new file mode 100644 (file)
index 0000000..4470b5b
--- /dev/null
@@ -0,0 +1,73 @@
+From a681aeeb8c085c30b8f7d8a38926b8a6930d6be5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Aug 2024 21:58:23 +0200
+Subject: thermal: of: Fix OF node leak in of_thermal_zone_find() error paths
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit c0a1ef9c5be72ff28a5413deb1b3e1a066593c13 ]
+
+Terminating for_each_available_child_of_node() loop requires dropping OF
+node reference, so bailing out on errors misses this.  Solve the OF node
+reference leak with scoped for_each_available_child_of_node_scoped().
+
+Fixes: 3fd6d6e2b4e8 ("thermal/of: Rework the thermal device tree initialization")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://patch.msgid.link/20240814195823.437597-3-krzysztof.kozlowski@linaro.org
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_of.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
+index 62099ffcd9721..323c8cd171485 100644
+--- a/drivers/thermal/thermal_of.c
++++ b/drivers/thermal/thermal_of.c
+@@ -294,14 +294,14 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int
+        * Search for each thermal zone, a defined sensor
+        * corresponding to the one passed as parameter
+        */
+-      for_each_available_child_of_node(np, tz) {
++      for_each_available_child_of_node_scoped(np, child) {
+               int count, i;
+-              count = of_count_phandle_with_args(tz, "thermal-sensors",
++              count = of_count_phandle_with_args(child, "thermal-sensors",
+                                                  "#thermal-sensor-cells");
+               if (count <= 0) {
+-                      pr_err("%pOFn: missing thermal sensor\n", tz);
++                      pr_err("%pOFn: missing thermal sensor\n", child);
+                       tz = ERR_PTR(-EINVAL);
+                       goto out;
+               }
+@@ -310,18 +310,19 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int
+                       int ret;
+-                      ret = of_parse_phandle_with_args(tz, "thermal-sensors",
++                      ret = of_parse_phandle_with_args(child, "thermal-sensors",
+                                                        "#thermal-sensor-cells",
+                                                        i, &sensor_specs);
+                       if (ret < 0) {
+-                              pr_err("%pOFn: Failed to read thermal-sensors cells: %d\n", tz, ret);
++                              pr_err("%pOFn: Failed to read thermal-sensors cells: %d\n", child, ret);
+                               tz = ERR_PTR(ret);
+                               goto out;
+                       }
+                       if ((sensor == sensor_specs.np) && id == (sensor_specs.args_count ?
+                                                                 sensor_specs.args[0] : 0)) {
+-                              pr_debug("sensor %pOFn id=%d belongs to %pOFn\n", sensor, id, tz);
++                              pr_debug("sensor %pOFn id=%d belongs to %pOFn\n", sensor, id, child);
++                              tz = no_free_ptr(child);
+                               goto out;
+                       }
+               }
+-- 
+2.43.0
+
diff --git a/queue-6.1/thermal-of-fix-of-node-leak-in-thermal_of_trips_init.patch b/queue-6.1/thermal-of-fix-of-node-leak-in-thermal_of_trips_init.patch
new file mode 100644 (file)
index 0000000..323a705
--- /dev/null
@@ -0,0 +1,51 @@
+From ceb030130f9202d1dfdd665f70e1a7ab8a2c9b9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Aug 2024 21:58:21 +0200
+Subject: thermal: of: Fix OF node leak in thermal_of_trips_init() error path
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit afc954fd223ded70b1fa000767e2531db55cce58 ]
+
+Terminating for_each_child_of_node() loop requires dropping OF node
+reference, so bailing out after thermal_of_populate_trip() error misses
+this.  Solve the OF node reference leak with scoped
+for_each_child_of_node_scoped().
+
+Fixes: d0c75fa2c17f ("thermal/of: Initialize trip points separately")
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://patch.msgid.link/20240814195823.437597-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_of.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
+index 202dce0d2e309..62099ffcd9721 100644
+--- a/drivers/thermal/thermal_of.c
++++ b/drivers/thermal/thermal_of.c
+@@ -235,7 +235,7 @@ static int thermal_of_populate_trip(struct device_node *np,
+ static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *ntrips)
+ {
+       struct thermal_trip *tt;
+-      struct device_node *trips, *trip;
++      struct device_node *trips;
+       int ret, count;
+       trips = of_get_child_by_name(np, "trips");
+@@ -260,7 +260,7 @@ static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *n
+       *ntrips = count;
+       count = 0;
+-      for_each_child_of_node(trips, trip) {
++      for_each_child_of_node_scoped(trips, trip) {
+               ret = thermal_of_populate_trip(trip, &tt[count++]);
+               if (ret)
+                       goto out_kfree;
+-- 
+2.43.0
+