commit:     360f49155a45c1590abbef293d9e13a2a0bf78dd
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Sep  4 13:52:11 2024 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Sep  4 13:52:11 2024 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=360f4915

Linux patch 6.1.108

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README              |    4 +
 1107_linux-6.1.108.patch | 2490 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2494 insertions(+)

diff --git a/0000_README b/0000_README
index 31e8b007..06b1b356 100644
--- a/0000_README
+++ b/0000_README
@@ -475,6 +475,10 @@ Patch:  1106_linux-6.1.107.patch
 From:   https://www.kernel.org
 Desc:   Linux 6.1.107
 
+Patch:  1107_linux-6.1.108.patch
+From:   https://www.kernel.org
+Desc:   Linux 6.1.108
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1107_linux-6.1.108.patch b/1107_linux-6.1.108.patch
new file mode 100644
index 00000000..13bca249
--- /dev/null
+++ b/1107_linux-6.1.108.patch
@@ -0,0 +1,2490 @@
+diff --git a/Makefile b/Makefile
+index 4c0fc0e5e002f..4813b751ccb0d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 1
+-SUBLEVEL = 107
++SUBLEVEL = 108
+ EXTRAVERSION =
+ NAME = Curry Ramen
+ 
+diff --git a/arch/loongarch/include/asm/dma-direct.h 
b/arch/loongarch/include/asm/dma-direct.h
+deleted file mode 100644
+index 75ccd808a2af3..0000000000000
+--- a/arch/loongarch/include/asm/dma-direct.h
++++ /dev/null
+@@ -1,11 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0 */
+-/*
+- * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
+- */
+-#ifndef _LOONGARCH_DMA_DIRECT_H
+-#define _LOONGARCH_DMA_DIRECT_H
+-
+-dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
+-phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
+-
+-#endif /* _LOONGARCH_DMA_DIRECT_H */
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 5a13630034ef7..826d9a102a51a 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -5471,6 +5471,9 @@ static void ata_host_release(struct kref *kref)
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+ 
++              if (!ap)
++                      continue;
++
+               kfree(ap->pmp_link);
+               kfree(ap->slave_link);
+               kfree(ap);
+diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
+index 97ba3bfc10b13..66c98676e66ad 100644
+--- a/drivers/dma/dw/core.c
++++ b/drivers/dma/dw/core.c
+@@ -16,6 +16,7 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/log2.h>
+ #include <linux/mm.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+@@ -621,12 +622,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct 
scatterlist *sgl,
+       struct dw_desc          *prev;
+       struct dw_desc          *first;
+       u32                     ctllo, ctlhi;
+-      u8                      m_master = dwc->dws.m_master;
+-      u8                      lms = DWC_LLP_LMS(m_master);
++      u8                      lms = DWC_LLP_LMS(dwc->dws.m_master);
+       dma_addr_t              reg;
+       unsigned int            reg_width;
+       unsigned int            mem_width;
+-      unsigned int            data_width = dw->pdata->data_width[m_master];
+       unsigned int            i;
+       struct scatterlist      *sg;
+       size_t                  total_len = 0;
+@@ -660,7 +659,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct 
scatterlist *sgl,
+                       mem = sg_dma_address(sg);
+                       len = sg_dma_len(sg);
+ 
+-                      mem_width = __ffs(data_width | mem | len);
++                      mem_width = __ffs(sconfig->src_addr_width | mem | len);
+ 
+ slave_sg_todev_fill_desc:
+                       desc = dwc_desc_get(dwc);
+@@ -720,7 +719,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct 
scatterlist *sgl,
+                       lli_write(desc, sar, reg);
+                       lli_write(desc, dar, mem);
+                       lli_write(desc, ctlhi, ctlhi);
+-                      mem_width = __ffs(data_width | mem);
++                      mem_width = __ffs(sconfig->dst_addr_width | mem);
+                       lli_write(desc, ctllo, ctllo | 
DWC_CTLL_DST_WIDTH(mem_width));
+                       desc->len = dlen;
+ 
+@@ -780,17 +779,93 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
+ }
+ EXPORT_SYMBOL_GPL(dw_dma_filter);
+ 
++static int dwc_verify_p_buswidth(struct dma_chan *chan)
++{
++      struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++      struct dw_dma *dw = to_dw_dma(chan->device);
++      u32 reg_width, max_width;
++
++      if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
++              reg_width = dwc->dma_sconfig.dst_addr_width;
++      else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM)
++              reg_width = dwc->dma_sconfig.src_addr_width;
++      else /* DMA_MEM_TO_MEM */
++              return 0;
++
++      max_width = dw->pdata->data_width[dwc->dws.p_master];
++
++      /* Fall-back to 1-byte transfer width if undefined */
++      if (reg_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
++              reg_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
++      else if (!is_power_of_2(reg_width) || reg_width > max_width)
++              return -EINVAL;
++      else /* bus width is valid */
++              return 0;
++
++      /* Update undefined addr width value */
++      if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
++              dwc->dma_sconfig.dst_addr_width = reg_width;
++      else /* DMA_DEV_TO_MEM */
++              dwc->dma_sconfig.src_addr_width = reg_width;
++
++      return 0;
++}
++
++static int dwc_verify_m_buswidth(struct dma_chan *chan)
++{
++      struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++      struct dw_dma *dw = to_dw_dma(chan->device);
++      u32 reg_width, reg_burst, mem_width;
++
++      mem_width = dw->pdata->data_width[dwc->dws.m_master];
++
++      /*
++       * It's possible to have a data portion locked in the DMA FIFO in case
++       * of the channel suspension. Subsequent channel disabling will cause
++       * that data silent loss. In order to prevent that maintain the src and
++       * dst transfer widths coherency by means of the relation:
++       * (CTLx.SRC_TR_WIDTH * CTLx.SRC_MSIZE >= CTLx.DST_TR_WIDTH)
++       * Look for the details in the commit message that brings this change.
++       *
++       * Note the DMA configs utilized in the calculations below must have
++       * been verified to have correct values by this method call.
++       */
++      if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) {
++              reg_width = dwc->dma_sconfig.dst_addr_width;
++              if (mem_width < reg_width)
++                      return -EINVAL;
++
++              dwc->dma_sconfig.src_addr_width = mem_width;
++      } else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) {
++              reg_width = dwc->dma_sconfig.src_addr_width;
++              reg_burst = rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst);
++
++              dwc->dma_sconfig.dst_addr_width = min(mem_width, reg_width * 
reg_burst);
++      }
++
++      return 0;
++}
++
+ static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
+ {
+       struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+       struct dw_dma *dw = to_dw_dma(chan->device);
++      int ret;
+ 
+       memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
+ 
+       dwc->dma_sconfig.src_maxburst =
+-              clamp(dwc->dma_sconfig.src_maxburst, 0U, dwc->max_burst);
++              clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst);
+       dwc->dma_sconfig.dst_maxburst =
+-              clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst);
++              clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst);
++
++      ret = dwc_verify_p_buswidth(chan);
++      if (ret)
++              return ret;
++
++      ret = dwc_verify_m_buswidth(chan);
++      if (ret)
++              return ret;
+ 
+       dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst);
+       dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+index 02cb3a12dd762..bc030588cd220 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+@@ -743,7 +743,8 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p,
+       uint32_t created = 0;
+       uint32_t allocated = 0;
+       uint32_t tmp, handle = 0;
+-      uint32_t *size = &tmp;
++      uint32_t dummy = 0xffffffff;
++      uint32_t *size = &dummy;
+       unsigned idx;
+       int i, r = 0;
+ 
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+index cd6e99cf74a06..08b10df93c317 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+@@ -28,6 +28,7 @@
+ #include <drm/drm_blend.h>
+ #include <drm/drm_gem_atomic_helper.h>
+ #include <drm/drm_plane_helper.h>
++#include <drm/drm_gem_framebuffer_helper.h>
+ #include <drm/drm_fourcc.h>
+ 
+ #include "amdgpu.h"
+@@ -848,10 +849,14 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
+       }
+ 
+       afb = to_amdgpu_framebuffer(new_state->fb);
+-      obj = new_state->fb->obj[0];
++      obj = drm_gem_fb_get_obj(new_state->fb, 0);
++      if (!obj) {
++              DRM_ERROR("Failed to get obj from framebuffer\n");
++              return -EINVAL;
++      }
++
+       rbo = gem_to_amdgpu_bo(obj);
+       adev = amdgpu_ttm_adev(rbo->tbo.bdev);
+-
+       r = amdgpu_bo_reserve(rbo, true);
+       if (r) {
+               dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 
b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+index 91f0646eb3ee0..5d193872fd1ad 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+@@ -1829,8 +1829,9 @@ static int smu_bump_power_profile_mode(struct 
smu_context *smu,
+ }
+ 
+ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
+-                                 enum amd_dpm_forced_level level,
+-                                 bool skip_display_settings)
++                                        enum amd_dpm_forced_level level,
++                                        bool skip_display_settings,
++                                        bool force_update)
+ {
+       int ret = 0;
+       int index = 0;
+@@ -1859,7 +1860,7 @@ static int smu_adjust_power_state_dynamic(struct 
smu_context *smu,
+               }
+       }
+ 
+-      if (smu_dpm_ctx->dpm_level != level) {
++      if (force_update || smu_dpm_ctx->dpm_level != level) {
+               ret = smu_asic_set_performance_level(smu, level);
+               if (ret) {
+                       dev_err(smu->adev->dev, "Failed to set performance 
level!");
+@@ -1870,13 +1871,12 @@ static int smu_adjust_power_state_dynamic(struct 
smu_context *smu,
+               smu_dpm_ctx->dpm_level = level;
+       }
+ 
+-      if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
+-              smu_dpm_ctx->dpm_level != 
AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
++      if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
+               index = fls(smu->workload_mask);
+               index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 
0;
+               workload[0] = smu->workload_setting[index];
+ 
+-              if (smu->power_profile_mode != workload[0])
++              if (force_update || smu->power_profile_mode != workload[0])
+                       smu_bump_power_profile_mode(smu, workload, 0);
+       }
+ 
+@@ -1897,11 +1897,13 @@ static int smu_handle_task(struct smu_context *smu,
+               ret = smu_pre_display_config_changed(smu);
+               if (ret)
+                       return ret;
+-              ret = smu_adjust_power_state_dynamic(smu, level, false);
++              ret = smu_adjust_power_state_dynamic(smu, level, false, false);
+               break;
+       case AMD_PP_TASK_COMPLETE_INIT:
++              ret = smu_adjust_power_state_dynamic(smu, level, true, true);
++              break;
+       case AMD_PP_TASK_READJUST_POWER_STATE:
+-              ret = smu_adjust_power_state_dynamic(smu, level, true);
++              ret = smu_adjust_power_state_dynamic(smu, level, true, false);
+               break;
+       default:
+               break;
+@@ -1948,8 +1950,7 @@ static int smu_switch_power_profile(void *handle,
+               workload[0] = smu->workload_setting[index];
+       }
+ 
+-      if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
+-              smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
++      if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
+               smu_bump_power_profile_mode(smu, workload, 0);
+ 
+       return 0;
+diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
+index ba3115fd0f86a..08ec39111e608 100644
+--- a/drivers/iommu/io-pgtable-arm-v7s.c
++++ b/drivers/iommu/io-pgtable-arm-v7s.c
+@@ -552,9 +552,8 @@ static int arm_v7s_map_pages(struct io_pgtable_ops *ops, 
unsigned long iova,
+                   paddr >= (1ULL << data->iop.cfg.oas)))
+               return -ERANGE;
+ 
+-      /* If no access, then nothing to do */
+       if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
+-              return 0;
++              return -EINVAL;
+ 
+       while (pgcount--) {
+               ret = __arm_v7s_map(data, iova, paddr, pgsize, prot, 1, 
data->pgd,
+diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
+index 0ba817e863465..1e38a24eb71cb 100644
+--- a/drivers/iommu/io-pgtable-arm.c
++++ b/drivers/iommu/io-pgtable-arm.c
+@@ -480,9 +480,8 @@ static int arm_lpae_map_pages(struct io_pgtable_ops *ops, 
unsigned long iova,
+       if (WARN_ON(iaext || paddr >> cfg->oas))
+               return -ERANGE;
+ 
+-      /* If no access, then nothing to do */
+       if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
+-              return 0;
++              return -EINVAL;
+ 
+       prot = arm_lpae_prot_to_pte(data, iommu_prot);
+       ret = __arm_lpae_map(data, iova, paddr, pgsize, pgcount, prot, lvl,
+diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c
+index 74b1ef2b96bee..10811e0b773d3 100644
+--- a/drivers/iommu/io-pgtable-dart.c
++++ b/drivers/iommu/io-pgtable-dart.c
+@@ -250,9 +250,8 @@ static int dart_map_pages(struct io_pgtable_ops *ops, 
unsigned long iova,
+       if (WARN_ON(paddr >> cfg->oas))
+               return -ERANGE;
+ 
+-      /* If no access, then nothing to do */
+       if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
+-              return 0;
++              return -EINVAL;
+ 
+       tbl = dart_get_table(data, iova);
+ 
+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..ba18e9fa64b15 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -1206,10 +1206,8 @@ 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))
++              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
+                        * may have alreay come when cmd19/cmd21 gets response
+@@ -1301,11 +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 &&
+-            (cmd->opcode == MMC_SEND_TUNING_BLOCK ||
+-             cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200 ||
+-             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)
+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;
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index c218352814430..375412ce1ea5f 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -577,12 +577,47 @@ static void bond_ipsec_del_sa_all(struct bonding *bond)
+                                  __func__);
+               } else {
+                       
slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
++                      if (slave->dev->xfrmdev_ops->xdo_dev_state_free)
++                              
slave->dev->xfrmdev_ops->xdo_dev_state_free(ipsec->xs);
+               }
+       }
+       spin_unlock_bh(&bond->ipsec_lock);
+       rcu_read_unlock();
+ }
+ 
++static void bond_ipsec_free_sa(struct xfrm_state *xs)
++{
++      struct net_device *bond_dev = xs->xso.dev;
++      struct net_device *real_dev;
++      netdevice_tracker tracker;
++      struct bonding *bond;
++      struct slave *slave;
++
++      if (!bond_dev)
++              return;
++
++      rcu_read_lock();
++      bond = netdev_priv(bond_dev);
++      slave = rcu_dereference(bond->curr_active_slave);
++      real_dev = slave ? slave->dev : NULL;
++      netdev_hold(real_dev, &tracker, GFP_ATOMIC);
++      rcu_read_unlock();
++
++      if (!slave)
++              goto out;
++
++      if (!xs->xso.real_dev)
++              goto out;
++
++      WARN_ON(xs->xso.real_dev != real_dev);
++
++      if (real_dev && real_dev->xfrmdev_ops &&
++          real_dev->xfrmdev_ops->xdo_dev_state_free)
++              real_dev->xfrmdev_ops->xdo_dev_state_free(xs);
++out:
++      netdev_put(real_dev, &tracker);
++}
++
+ /**
+  * bond_ipsec_offload_ok - can this packet use the xfrm hw offload
+  * @skb: current data packet
+@@ -623,6 +658,7 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, 
struct xfrm_state *xs)
+ static const struct xfrmdev_ops bond_xfrmdev_ops = {
+       .xdo_dev_state_add = bond_ipsec_add_sa,
+       .xdo_dev_state_delete = bond_ipsec_del_sa,
++      .xdo_dev_state_free = bond_ipsec_free_sa,
+       .xdo_dev_offload_ok = bond_ipsec_offload_ok,
+ };
+ #endif /* CONFIG_XFRM_OFFLOAD */
+diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c 
b/drivers/net/ethernet/intel/igc/igc_tsn.c
+index abdaaf7db4125..ad358c95c0a45 100644
+--- a/drivers/net/ethernet/intel/igc/igc_tsn.c
++++ b/drivers/net/ethernet/intel/igc/igc_tsn.c
+@@ -49,12 +49,19 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter 
*adapter)
+       return new_flags;
+ }
+ 
++static bool igc_tsn_is_tx_mode_in_tsn(struct igc_adapter *adapter)
++{
++      struct igc_hw *hw = &adapter->hw;
++
++      return !!(rd32(IGC_TQAVCTRL) & IGC_TQAVCTRL_TRANSMIT_MODE_TSN);
++}
++
+ void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter)
+ {
+       struct igc_hw *hw = &adapter->hw;
+       u16 txoffset;
+ 
+-      if (!is_any_launchtime(adapter))
++      if (!igc_tsn_is_tx_mode_in_tsn(adapter))
+               return;
+ 
+       switch (adapter->link_speed) {
+diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c 
b/drivers/net/ethernet/microsoft/mana/hw_channel.c
+index 543a5d5c304f3..66a0552fc8b3a 100644
+--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
++++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
+@@ -51,9 +51,33 @@ static int mana_hwc_verify_resp_msg(const struct 
hwc_caller_ctx *caller_ctx,
+       return 0;
+ }
+ 
++static int mana_hwc_post_rx_wqe(const struct hwc_wq *hwc_rxq,
++                              struct hwc_work_request *req)
++{
++      struct device *dev = hwc_rxq->hwc->dev;
++      struct gdma_sge *sge;
++      int err;
++
++      sge = &req->sge;
++      sge->address = (u64)req->buf_sge_addr;
++      sge->mem_key = hwc_rxq->msg_buf->gpa_mkey;
++      sge->size = req->buf_len;
++
++      memset(&req->wqe_req, 0, sizeof(struct gdma_wqe_request));
++      req->wqe_req.sgl = sge;
++      req->wqe_req.num_sge = 1;
++      req->wqe_req.client_data_unit = 0;
++
++      err = mana_gd_post_and_ring(hwc_rxq->gdma_wq, &req->wqe_req, NULL);
++      if (err)
++              dev_err(dev, "Failed to post WQE on HWC RQ: %d\n", err);
++      return err;
++}
++
+ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,
+-                               const struct gdma_resp_hdr *resp_msg)
++                               struct hwc_work_request *rx_req)
+ {
++      const struct gdma_resp_hdr *resp_msg = rx_req->buf_va;
+       struct hwc_caller_ctx *ctx;
+       int err;
+ 
+@@ -61,6 +85,7 @@ static void mana_hwc_handle_resp(struct hw_channel_context 
*hwc, u32 resp_len,
+                     hwc->inflight_msg_res.map)) {
+               dev_err(hwc->dev, "hwc_rx: invalid msg_id = %u\n",
+                       resp_msg->response.hwc_msg_id);
++              mana_hwc_post_rx_wqe(hwc->rxq, rx_req);
+               return;
+       }
+ 
+@@ -74,30 +99,13 @@ static void mana_hwc_handle_resp(struct hw_channel_context 
*hwc, u32 resp_len,
+       memcpy(ctx->output_buf, resp_msg, resp_len);
+ out:
+       ctx->error = err;
+-      complete(&ctx->comp_event);
+-}
+-
+-static int mana_hwc_post_rx_wqe(const struct hwc_wq *hwc_rxq,
+-                              struct hwc_work_request *req)
+-{
+-      struct device *dev = hwc_rxq->hwc->dev;
+-      struct gdma_sge *sge;
+-      int err;
+-
+-      sge = &req->sge;
+-      sge->address = (u64)req->buf_sge_addr;
+-      sge->mem_key = hwc_rxq->msg_buf->gpa_mkey;
+-      sge->size = req->buf_len;
+ 
+-      memset(&req->wqe_req, 0, sizeof(struct gdma_wqe_request));
+-      req->wqe_req.sgl = sge;
+-      req->wqe_req.num_sge = 1;
+-      req->wqe_req.client_data_unit = 0;
++      /* Must post rx wqe before complete(), otherwise the next rx may
++       * hit no_wqe error.
++       */
++      mana_hwc_post_rx_wqe(hwc->rxq, rx_req);
+ 
+-      err = mana_gd_post_and_ring(hwc_rxq->gdma_wq, &req->wqe_req, NULL);
+-      if (err)
+-              dev_err(dev, "Failed to post WQE on HWC RQ: %d\n", err);
+-      return err;
++      complete(&ctx->comp_event);
+ }
+ 
+ static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
+@@ -216,14 +224,12 @@ static void mana_hwc_rx_event_handler(void *ctx, u32 
gdma_rxq_id,
+               return;
+       }
+ 
+-      mana_hwc_handle_resp(hwc, rx_oob->tx_oob_data_size, resp);
++      mana_hwc_handle_resp(hwc, rx_oob->tx_oob_data_size, rx_req);
+ 
+-      /* Do no longer use 'resp', because the buffer is posted to the HW
+-       * in the below mana_hwc_post_rx_wqe().
++      /* Can no longer use 'resp', because the buffer is posted to the HW
++       * in mana_hwc_handle_resp() above.
+        */
+       resp = NULL;
+-
+-      mana_hwc_post_rx_wqe(hwc_rxq, rx_req);
+ }
+ 
+ static void mana_hwc_tx_event_handler(void *ctx, u32 gdma_txq_id,
+diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
+index 512daeb14e28b..bbe8d76b1595e 100644
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -1219,7 +1219,7 @@ static struct sock *gtp_encap_enable_socket(int fd, int 
type,
+       sock = sockfd_lookup(fd, &err);
+       if (!sock) {
+               pr_debug("gtp socket fd=%d not found\n", fd);
+-              return NULL;
++              return ERR_PTR(err);
+       }
+ 
+       sk = sock->sk;
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c 
b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+index 235963e1d7a9a..c96dfd7fd3dc8 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+@@ -825,22 +825,25 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
+                               entry = &wifi_pkg->package.elements[entry_idx];
+                               entry_idx++;
+                               if (entry->type != ACPI_TYPE_INTEGER ||
+-                                  entry->integer.value > num_profiles) {
++                                  entry->integer.value > num_profiles ||
++                                  entry->integer.value <
++                                      rev_data[idx].min_profiles) {
+                                       ret = -EINVAL;
+                                       goto out_free;
+                               }
+-                              num_profiles = entry->integer.value;
+ 
+                               /*
+-                               * this also validates >= min_profiles since we
+-                               * otherwise wouldn't have gotten the data when
+-                               * looking up in ACPI
++                               * Check to see if we received package count
++                               * same as max # of profiles
+                                */
+                               if (wifi_pkg->package.count !=
+                                   hdr_size + profile_size * num_profiles) {
+                                       ret = -EINVAL;
+                                       goto out_free;
+                               }
++
++                              /* Number of valid profiles */
++                              num_profiles = entry->integer.value;
+                       }
+                       goto read_table;
+               }
+diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c 
b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+index d1b23dba5ad50..3cde6fc3bb813 100644
+--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+@@ -4362,11 +4362,27 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter 
*adapter)
+       if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info))
+               wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
+ 
+-      wiphy->bands[NL80211_BAND_2GHZ] = &mwifiex_band_2ghz;
+-      if (adapter->config_bands & BAND_A)
+-              wiphy->bands[NL80211_BAND_5GHZ] = &mwifiex_band_5ghz;
+-      else
++      wiphy->bands[NL80211_BAND_2GHZ] = devm_kmemdup(adapter->dev,
++                                                     &mwifiex_band_2ghz,
++                                                     
sizeof(mwifiex_band_2ghz),
++                                                     GFP_KERNEL);
++      if (!wiphy->bands[NL80211_BAND_2GHZ]) {
++              ret = -ENOMEM;
++              goto err;
++      }
++
++      if (adapter->config_bands & BAND_A) {
++              wiphy->bands[NL80211_BAND_5GHZ] = devm_kmemdup(adapter->dev,
++                                                             
&mwifiex_band_5ghz,
++                                                             
sizeof(mwifiex_band_5ghz),
++                                                             GFP_KERNEL);
++              if (!wiphy->bands[NL80211_BAND_5GHZ]) {
++                      ret = -ENOMEM;
++                      goto err;
++              }
++      } else {
+               wiphy->bands[NL80211_BAND_5GHZ] = NULL;
++      }
+ 
+       if (adapter->drcs_enabled && ISSUPP_DRCS_ENABLED(adapter->fw_cap_info))
+               wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_drcs;
+@@ -4459,8 +4475,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter 
*adapter)
+       if (ret < 0) {
+               mwifiex_dbg(adapter, ERROR,
+                           "%s: wiphy_register failed: %d\n", __func__, ret);
+-              wiphy_free(wiphy);
+-              return ret;
++              goto err;
+       }
+ 
+       if (!adapter->regd) {
+@@ -4502,4 +4517,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter 
*adapter)
+ 
+       adapter->wiphy = wiphy;
+       return ret;
++
++err:
++      wiphy_free(wiphy);
++
++      return ret;
+ }
+diff --git a/drivers/net/wireless/silabs/wfx/sta.c 
b/drivers/net/wireless/silabs/wfx/sta.c
+index 871667650dbef..048a552e9da1d 100644
+--- a/drivers/net/wireless/silabs/wfx/sta.c
++++ b/drivers/net/wireless/silabs/wfx/sta.c
+@@ -370,8 +370,11 @@ static int wfx_set_mfp_ap(struct wfx_vif *wvif)
+ 
+       ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset,
+                                     skb->len - ieoffset);
+-      if (unlikely(!ptr))
++      if (!ptr) {
++              /* No RSN IE is fine in open networks */
++              ret = 0;
+               goto free_skb;
++      }
+ 
+       ptr += pairwise_cipher_suite_count_offset;
+       if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
+diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c
+index f0cac19005527..2e0871409926b 100644
+--- a/drivers/nfc/pn533/pn533.c
++++ b/drivers/nfc/pn533/pn533.c
+@@ -1723,6 +1723,11 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev,
+       }
+ 
+       pn533_poll_create_mod_list(dev, im_protocols, tm_protocols);
++      if (!dev->poll_mod_count) {
++              nfc_err(dev->dev,
++                      "Poll mod list is empty\n");
++              return -EINVAL;
++      }
+ 
+       /* Do not always start polling from the same modulation */
+       get_random_bytes(&rand_mod, sizeof(rand_mod));
+diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c
+index 9be9535ad7ab7..ac9a9124a36de 100644
+--- a/drivers/phy/xilinx/phy-zynqmp.c
++++ b/drivers/phy/xilinx/phy-zynqmp.c
+@@ -21,6 +21,7 @@
+ #include <linux/of.h>
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+ 
+ #include <dt-bindings/phy/phy.h>
+@@ -80,7 +81,8 @@
+ 
+ /* Reference clock selection parameters */
+ #define L0_Ln_REF_CLK_SEL(n)          (0x2860 + (n) * 4)
+-#define L0_REF_CLK_SEL_MASK           0x8f
++#define L0_REF_CLK_LCL_SEL            BIT(7)
++#define L0_REF_CLK_SEL_MASK           0x9f
+ 
+ /* Calibration digital logic parameters */
+ #define L3_TM_CALIB_DIG19             0xec4c
+@@ -165,6 +167,24 @@
+ /* Timeout values */
+ #define TIMEOUT_US                    1000
+ 
++/* Lane 0/1/2/3 offset */
++#define DIG_8(n)              ((0x4000 * (n)) + 0x1074)
++#define ILL13(n)              ((0x4000 * (n)) + 0x1994)
++#define DIG_10(n)             ((0x4000 * (n)) + 0x107c)
++#define RST_DLY(n)            ((0x4000 * (n)) + 0x19a4)
++#define BYP_15(n)             ((0x4000 * (n)) + 0x1038)
++#define BYP_12(n)             ((0x4000 * (n)) + 0x102c)
++#define MISC3(n)              ((0x4000 * (n)) + 0x19ac)
++#define EQ11(n)                       ((0x4000 * (n)) + 0x1978)
++
++static u32 save_reg_address[] = {
++      /* Lane 0/1/2/3 Register */
++      DIG_8(0), ILL13(0), DIG_10(0), RST_DLY(0), BYP_15(0), BYP_12(0), 
MISC3(0), EQ11(0),
++      DIG_8(1), ILL13(1), DIG_10(1), RST_DLY(1), BYP_15(1), BYP_12(1), 
MISC3(1), EQ11(1),
++      DIG_8(2), ILL13(2), DIG_10(2), RST_DLY(2), BYP_15(2), BYP_12(2), 
MISC3(2), EQ11(2),
++      DIG_8(3), ILL13(3), DIG_10(3), RST_DLY(3), BYP_15(3), BYP_12(3), 
MISC3(3), EQ11(3),
++};
++
+ struct xpsgtr_dev;
+ 
+ /**
+@@ -213,6 +233,7 @@ struct xpsgtr_phy {
+  * @tx_term_fix: fix for GT issue
+  * @saved_icm_cfg0: stored value of ICM CFG0 register
+  * @saved_icm_cfg1: stored value of ICM CFG1 register
++ * @saved_regs: registers to be saved/restored during suspend/resume
+  */
+ struct xpsgtr_dev {
+       struct device *dev;
+@@ -225,6 +246,7 @@ struct xpsgtr_dev {
+       bool tx_term_fix;
+       unsigned int saved_icm_cfg0;
+       unsigned int saved_icm_cfg1;
++      u32 *saved_regs;
+ };
+ 
+ /*
+@@ -298,6 +320,32 @@ static inline void xpsgtr_clr_set_phy(struct xpsgtr_phy 
*gtr_phy,
+       writel((readl(addr) & ~clr) | set, addr);
+ }
+ 
++/**
++ * xpsgtr_save_lane_regs - Saves registers on suspend
++ * @gtr_dev: pointer to phy controller context structure
++ */
++static void xpsgtr_save_lane_regs(struct xpsgtr_dev *gtr_dev)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(save_reg_address); i++)
++              gtr_dev->saved_regs[i] = xpsgtr_read(gtr_dev,
++                                                   save_reg_address[i]);
++}
++
++/**
++ * xpsgtr_restore_lane_regs - Restores registers on resume
++ * @gtr_dev: pointer to phy controller context structure
++ */
++static void xpsgtr_restore_lane_regs(struct xpsgtr_dev *gtr_dev)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(save_reg_address); i++)
++              xpsgtr_write(gtr_dev, save_reg_address[i],
++                           gtr_dev->saved_regs[i]);
++}
++
+ /*
+  * Hardware Configuration
+  */
+@@ -349,11 +397,12 @@ static void xpsgtr_configure_pll(struct xpsgtr_phy 
*gtr_phy)
+                      PLL_FREQ_MASK, ssc->pll_ref_clk);
+ 
+       /* Enable lane clock sharing, if required */
+-      if (gtr_phy->refclk != gtr_phy->lane) {
+-              /* Lane3 Ref Clock Selection Register */
++      if (gtr_phy->refclk == gtr_phy->lane)
++              xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
++                             L0_REF_CLK_SEL_MASK, L0_REF_CLK_LCL_SEL);
++      else
+               xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
+                              L0_REF_CLK_SEL_MASK, 1 << gtr_phy->refclk);
+-      }
+ 
+       /* SSC step size [7:0] */
+       xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_0_LSB,
+@@ -572,6 +621,10 @@ static int xpsgtr_phy_init(struct phy *phy)
+ 
+       mutex_lock(&gtr_dev->gtr_mutex);
+ 
++      /* Configure and enable the clock when peripheral phy_init call */
++      if (clk_prepare_enable(gtr_dev->clk[gtr_phy->refclk]))
++              goto out;
++
+       /* Skip initialization if not required. */
+       if (!xpsgtr_phy_init_required(gtr_phy))
+               goto out;
+@@ -616,9 +669,13 @@ static int xpsgtr_phy_init(struct phy *phy)
+ static int xpsgtr_phy_exit(struct phy *phy)
+ {
+       struct xpsgtr_phy *gtr_phy = phy_get_drvdata(phy);
++      struct xpsgtr_dev *gtr_dev = gtr_phy->dev;
+ 
+       gtr_phy->skip_phy_init = false;
+ 
++      /* Ensure that disable clock only, which configure for lane */
++      clk_disable_unprepare(gtr_dev->clk[gtr_phy->refclk]);
++
+       return 0;
+ }
+ 
+@@ -821,34 +878,27 @@ static struct phy *xpsgtr_xlate(struct device *dev,
+  * Power Management
+  */
+ 
+-static int __maybe_unused xpsgtr_suspend(struct device *dev)
++static int xpsgtr_runtime_suspend(struct device *dev)
+ {
+       struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev);
+-      unsigned int i;
+ 
+       /* Save the snapshot ICM_CFG registers. */
+       gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0);
+       gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1);
+ 
+-      for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++)
+-              clk_disable_unprepare(gtr_dev->clk[i]);
++      xpsgtr_save_lane_regs(gtr_dev);
+ 
+       return 0;
+ }
+ 
+-static int __maybe_unused xpsgtr_resume(struct device *dev)
++static int xpsgtr_runtime_resume(struct device *dev)
+ {
+       struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev);
+       unsigned int icm_cfg0, icm_cfg1;
+       unsigned int i;
+       bool skip_phy_init;
+-      int err;
+ 
+-      for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) {
+-              err = clk_prepare_enable(gtr_dev->clk[i]);
+-              if (err)
+-                      goto err_clk_put;
+-      }
++      xpsgtr_restore_lane_regs(gtr_dev);
+ 
+       icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0);
+       icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1);
+@@ -869,18 +919,10 @@ static int __maybe_unused xpsgtr_resume(struct device 
*dev)
+               gtr_dev->phys[i].skip_phy_init = skip_phy_init;
+ 
+       return 0;
+-
+-err_clk_put:
+-      while (i--)
+-              clk_disable_unprepare(gtr_dev->clk[i]);
+-
+-      return err;
+ }
+ 
+-static const struct dev_pm_ops xpsgtr_pm_ops = {
+-      SET_SYSTEM_SLEEP_PM_OPS(xpsgtr_suspend, xpsgtr_resume)
+-};
+-
++static DEFINE_RUNTIME_DEV_PM_OPS(xpsgtr_pm_ops, xpsgtr_runtime_suspend,
++                               xpsgtr_runtime_resume, NULL);
+ /*
+  * Probe & Platform Driver
+  */
+@@ -888,7 +930,6 @@ static const struct dev_pm_ops xpsgtr_pm_ops = {
+ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev)
+ {
+       unsigned int refclk;
+-      int ret;
+ 
+       for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) {
+               unsigned long rate;
+@@ -899,19 +940,14 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev 
*gtr_dev)
+               snprintf(name, sizeof(name), "ref%u", refclk);
+               clk = devm_clk_get_optional(gtr_dev->dev, name);
+               if (IS_ERR(clk)) {
+-                      ret = dev_err_probe(gtr_dev->dev, PTR_ERR(clk),
+-                                          "Failed to get reference clock 
%u\n",
+-                                          refclk);
+-                      goto err_clk_put;
++                      return dev_err_probe(gtr_dev->dev, PTR_ERR(clk),
++                                           "Failed to get ref clock %u\n",
++                                           refclk);
+               }
+ 
+               if (!clk)
+                       continue;
+ 
+-              ret = clk_prepare_enable(clk);
+-              if (ret)
+-                      goto err_clk_put;
+-
+               gtr_dev->clk[refclk] = clk;
+ 
+               /*
+@@ -931,18 +967,11 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev 
*gtr_dev)
+                       dev_err(gtr_dev->dev,
+                               "Invalid rate %lu for reference clock %u\n",
+                               rate, refclk);
+-                      ret = -EINVAL;
+-                      goto err_clk_put;
++                      return -EINVAL;
+               }
+       }
+ 
+       return 0;
+-
+-err_clk_put:
+-      while (refclk--)
+-              clk_disable_unprepare(gtr_dev->clk[refclk]);
+-
+-      return ret;
+ }
+ 
+ static int xpsgtr_probe(struct platform_device *pdev)
+@@ -951,7 +980,6 @@ static int xpsgtr_probe(struct platform_device *pdev)
+       struct xpsgtr_dev *gtr_dev;
+       struct phy_provider *provider;
+       unsigned int port;
+-      unsigned int i;
+       int ret;
+ 
+       gtr_dev = devm_kzalloc(&pdev->dev, sizeof(*gtr_dev), GFP_KERNEL);
+@@ -991,8 +1019,7 @@ static int xpsgtr_probe(struct platform_device *pdev)
+               phy = devm_phy_create(&pdev->dev, np, &xpsgtr_phyops);
+               if (IS_ERR(phy)) {
+                       dev_err(&pdev->dev, "failed to create PHY\n");
+-                      ret = PTR_ERR(phy);
+-                      goto err_clk_put;
++                      return PTR_ERR(phy);
+               }
+ 
+               gtr_phy->phy = phy;
+@@ -1003,16 +1030,36 @@ static int xpsgtr_probe(struct platform_device *pdev)
+       provider = devm_of_phy_provider_register(&pdev->dev, xpsgtr_xlate);
+       if (IS_ERR(provider)) {
+               dev_err(&pdev->dev, "registering provider failed\n");
+-              ret = PTR_ERR(provider);
+-              goto err_clk_put;
++              return PTR_ERR(provider);
+       }
++
++      pm_runtime_set_active(gtr_dev->dev);
++      pm_runtime_enable(gtr_dev->dev);
++
++      ret = pm_runtime_resume_and_get(gtr_dev->dev);
++      if (ret < 0) {
++              pm_runtime_disable(gtr_dev->dev);
++              return ret;
++      }
++
++      gtr_dev->saved_regs = devm_kmalloc(gtr_dev->dev,
++                                         sizeof(save_reg_address),
++                                         GFP_KERNEL);
++      if (!gtr_dev->saved_regs)
++              return -ENOMEM;
++
+       return 0;
++}
+ 
+-err_clk_put:
+-      for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++)
+-              clk_disable_unprepare(gtr_dev->clk[i]);
++static int xpsgtr_remove(struct platform_device *pdev)
++{
++      struct xpsgtr_dev *gtr_dev = platform_get_drvdata(pdev);
+ 
+-      return ret;
++      pm_runtime_disable(gtr_dev->dev);
++      pm_runtime_put_noidle(gtr_dev->dev);
++      pm_runtime_set_suspended(gtr_dev->dev);
++
++      return 0;
+ }
+ 
+ static const struct of_device_id xpsgtr_of_match[] = {
+@@ -1024,10 +1071,11 @@ MODULE_DEVICE_TABLE(of, xpsgtr_of_match);
+ 
+ static struct platform_driver xpsgtr_driver = {
+       .probe = xpsgtr_probe,
++      .remove = xpsgtr_remove,
+       .driver = {
+               .name = "xilinx-psgtr",
+               .of_match_table = xpsgtr_of_match,
+-              .pm =  &xpsgtr_pm_ops,
++              .pm =  pm_ptr(&xpsgtr_pm_ops),
+       },
+ };
+ 
+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)
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
+index 6d140a60888c2..ca5a01c11ce60 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -3803,7 +3803,7 @@ static struct rockchip_pin_bank rk3328_pin_banks[] = {
+       PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0),
+       PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
+       PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0,
+-                           0,
++                           IOMUX_WIDTH_2BIT,
+                            IOMUX_WIDTH_3BIT,
+                            0),
+       PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
+diff --git a/drivers/pinctrl/pinctrl-single.c 
b/drivers/pinctrl/pinctrl-single.c
+index cd23479f352a2..d32d5c5e99bcd 100644
+--- a/drivers/pinctrl/pinctrl-single.c
++++ b/drivers/pinctrl/pinctrl-single.c
+@@ -350,6 +350,8 @@ static int pcs_get_function(struct pinctrl_dev *pctldev, 
unsigned pin,
+               return -ENOTSUPP;
+       fselector = setting->func;
+       function = pinmux_generic_get_function(pctldev, fselector);
++      if (!function)
++              return -EINVAL;
+       *func = function->data;
+       if (!(*func)) {
+               dev_err(pcs->dev, "%s could not find function%i\n",
+diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
+index bd99c5492b7d4..0f64b02443037 100644
+--- a/drivers/scsi/aacraid/comminit.c
++++ b/drivers/scsi/aacraid/comminit.c
+@@ -642,6 +642,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
+ 
+       if (aac_comm_init(dev)<0){
+               kfree(dev->queues);
++              dev->queues = NULL;
+               return NULL;
+       }
+       /*
+@@ -649,6 +650,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
+        */
+       if (aac_fib_setup(dev) < 0) {
+               kfree(dev->queues);
++              dev->queues = NULL;
+               return NULL;
+       }
+               
+diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
+index 2a7d089ec7270..81ddbcd253d92 100644
+--- a/drivers/soc/qcom/cmd-db.c
++++ b/drivers/soc/qcom/cmd-db.c
+@@ -354,7 +354,7 @@ static int cmd_db_dev_probe(struct platform_device *pdev)
+               return -EINVAL;
+       }
+ 
+-      cmd_db_header = memremap(rmem->base, rmem->size, MEMREMAP_WB);
++      cmd_db_header = memremap(rmem->base, rmem->size, MEMREMAP_WC);
+       if (!cmd_db_header) {
+               ret = -ENOMEM;
+               cmd_db_header = NULL;
+diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
+index 2624441d2fa92..2a245f3b7738f 100644
+--- a/drivers/soundwire/stream.c
++++ b/drivers/soundwire/stream.c
+@@ -1272,18 +1272,18 @@ struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct 
sdw_slave *slave,
+                                           unsigned int port_num)
+ {
+       struct sdw_dpn_prop *dpn_prop;
+-      u8 num_ports;
++      unsigned long mask;
+       int i;
+ 
+       if (direction == SDW_DATA_DIR_TX) {
+-              num_ports = hweight32(slave->prop.source_ports);
++              mask = slave->prop.source_ports;
+               dpn_prop = slave->prop.src_dpn_prop;
+       } else {
+-              num_ports = hweight32(slave->prop.sink_ports);
++              mask = slave->prop.sink_ports;
+               dpn_prop = slave->prop.sink_dpn_prop;
+       }
+ 
+-      for (i = 0; i < num_ports; i++) {
++      for_each_set_bit(i, &mask, 32) {
+               if (dpn_prop[i].num == port_num)
+                       return &dpn_prop[i];
+       }
+diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
+index 202dce0d2e309..323c8cd171485 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;
+@@ -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;
+                       }
+               }
+diff --git a/drivers/usb/cdns3/cdnsp-gadget.h 
b/drivers/usb/cdns3/cdnsp-gadget.h
+index f740fa6089d85..a61aef0dc273c 100644
+--- a/drivers/usb/cdns3/cdnsp-gadget.h
++++ b/drivers/usb/cdns3/cdnsp-gadget.h
+@@ -811,6 +811,7 @@ struct cdnsp_stream_info {
+  *        generate Missed Service Error Event.
+  *        Set skip flag when receive a Missed Service Error Event and
+  *        process the missed tds on the endpoint ring.
++ * @wa1_nop_trb: hold pointer to NOP trb.
+  */
+ struct cdnsp_ep {
+       struct usb_ep endpoint;
+@@ -838,6 +839,8 @@ struct cdnsp_ep {
+ #define EP_UNCONFIGURED               BIT(7)
+ 
+       bool skip;
++      union cdnsp_trb  *wa1_nop_trb;
++
+ };
+ 
+ /**
+diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c
+index 8a2cc0405a4ad..04e8db773a825 100644
+--- a/drivers/usb/cdns3/cdnsp-ring.c
++++ b/drivers/usb/cdns3/cdnsp-ring.c
+@@ -402,7 +402,7 @@ static u64 cdnsp_get_hw_deq(struct cdnsp_device *pdev,
+       struct cdnsp_stream_ctx *st_ctx;
+       struct cdnsp_ep *pep;
+ 
+-      pep = &pdev->eps[stream_id];
++      pep = &pdev->eps[ep_index];
+ 
+       if (pep->ep_state & EP_HAS_STREAMS) {
+               st_ctx = &pep->stream_info.stream_ctx_array[stream_id];
+@@ -1902,6 +1902,23 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, 
struct cdnsp_request *preq)
+       if (ret)
+               return ret;
+ 
++      /*
++       * workaround 1: STOP EP command on LINK TRB with TC bit set to 1
++       * causes that internal cycle bit can have incorrect state after
++       * command complete. In consequence empty transfer ring can be
++       * incorrectly detected when EP is resumed.
++       * NOP TRB before LINK TRB avoid such scenario. STOP EP command is
++       * then on NOP TRB and internal cycle bit is not changed and have
++       * correct value.
++       */
++      if (pep->wa1_nop_trb) {
++              field = le32_to_cpu(pep->wa1_nop_trb->trans_event.flags);
++              field ^= TRB_CYCLE;
++
++              pep->wa1_nop_trb->trans_event.flags = cpu_to_le32(field);
++              pep->wa1_nop_trb = NULL;
++      }
++
+       /*
+        * Don't give the first TRB to the hardware (by toggling the cycle bit)
+        * until we've finished creating all the other TRBs. The ring's cycle
+@@ -1997,6 +2014,17 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, 
struct cdnsp_request *preq)
+               send_addr = addr;
+       }
+ 
++      if (cdnsp_trb_is_link(ring->enqueue + 1)) {
++              field = TRB_TYPE(TRB_TR_NOOP) | TRB_IOC;
++              if (!ring->cycle_state)
++                      field |= TRB_CYCLE;
++
++              pep->wa1_nop_trb = ring->enqueue;
++
++              cdnsp_queue_trb(pdev, ring, 0, 0x0, 0x0,
++                              TRB_INTR_TARGET(0), field);
++      }
++
+       cdnsp_check_trb_math(preq, enqd_len);
+       ret = cdnsp_giveback_first_trb(pdev, pep, preq->request.stream_id,
+                                      start_cycle, start_trb);
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 2a7eea4e251a1..98511acfffe4e 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1737,6 +1737,9 @@ static const struct usb_device_id acm_ids[] = {
+       { USB_DEVICE(0x11ca, 0x0201), /* VeriFone Mx870 Gadget Serial */
+       .driver_info = SINGLE_RX_URB,
+       },
++      { USB_DEVICE(0x1901, 0x0006), /* GE Healthcare Patient Monitor UI 
Controller */
++      .driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */
++      },
+       { USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */
+       .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+       },
+diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
+index 5f1e07341f363..4fd1bfd524490 100644
+--- a/drivers/usb/core/sysfs.c
++++ b/drivers/usb/core/sysfs.c
+@@ -670,6 +670,7 @@ static int add_power_attributes(struct device *dev)
+ 
+ static void remove_power_attributes(struct device *dev)
+ {
++      sysfs_unmerge_group(&dev->kobj, &usb3_hardware_lpm_attr_group);
+       sysfs_unmerge_group(&dev->kobj, &usb2_hardware_lpm_attr_group);
+       sysfs_unmerge_group(&dev->kobj, &power_attr_group);
+ }
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 4964fa7419efa..5b761a2a87a7f 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -553,9 +553,17 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
+ void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
+ {
+       struct dwc3_event_buffer        *evt;
++      u32                             reg;
+ 
+       if (!dwc->ev_buf)
+               return;
++      /*
++       * Exynos platforms may not be able to access event buffer if the
++       * controller failed to halt on dwc3_core_exit().
++       */
++      reg = dwc3_readl(dwc->regs, DWC3_DSTS);
++      if (!(reg & DWC3_DSTS_DEVCTRLHLT))
++              return;
+ 
+       evt = dwc->ev_buf;
+ 
+diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
+index efaf0db595f46..6b59bbb22da49 100644
+--- a/drivers/usb/dwc3/dwc3-omap.c
++++ b/drivers/usb/dwc3/dwc3-omap.c
+@@ -522,11 +522,13 @@ static int dwc3_omap_probe(struct platform_device *pdev)
+       if (ret) {
+               dev_err(dev, "failed to request IRQ #%d --> %d\n",
+                       omap->irq, ret);
+-              goto err1;
++              goto err2;
+       }
+       dwc3_omap_enable_irqs(omap);
+       return 0;
+ 
++err2:
++      of_platform_depopulate(dev);
+ err1:
+       pm_runtime_put_sync(dev);
+       pm_runtime_disable(dev);
+diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
+index fea5290de83fb..20133fbb91473 100644
+--- a/drivers/usb/dwc3/dwc3-st.c
++++ b/drivers/usb/dwc3/dwc3-st.c
+@@ -219,10 +219,8 @@ static int st_dwc3_probe(struct platform_device *pdev)
+       dwc3_data->regmap = regmap;
+ 
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "syscfg-reg");
+-      if (!res) {
+-              ret = -ENXIO;
+-              goto undo_platform_dev_alloc;
+-      }
++      if (!res)
++              return -ENXIO;
+ 
+       dwc3_data->syscfg_reg_off = res->start;
+ 
+@@ -233,8 +231,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
+               devm_reset_control_get_exclusive(dev, "powerdown");
+       if (IS_ERR(dwc3_data->rstc_pwrdn)) {
+               dev_err(&pdev->dev, "could not get power controller\n");
+-              ret = PTR_ERR(dwc3_data->rstc_pwrdn);
+-              goto undo_platform_dev_alloc;
++              return PTR_ERR(dwc3_data->rstc_pwrdn);
+       }
+ 
+       /* Manage PowerDown */
+@@ -269,7 +266,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
+       if (!child_pdev) {
+               dev_err(dev, "failed to find dwc3 core device\n");
+               ret = -ENODEV;
+-              goto err_node_put;
++              goto depopulate;
+       }
+ 
+       dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev);
+@@ -285,6 +282,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
+       ret = st_dwc3_drd_init(dwc3_data);
+       if (ret) {
+               dev_err(dev, "drd initialisation failed\n");
++              of_platform_depopulate(dev);
+               goto undo_softreset;
+       }
+ 
+@@ -294,14 +292,14 @@ static int st_dwc3_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, dwc3_data);
+       return 0;
+ 
++depopulate:
++      of_platform_depopulate(dev);
+ err_node_put:
+       of_node_put(child);
+ undo_softreset:
+       reset_control_assert(dwc3_data->rstc_rst);
+ undo_powerdown:
+       reset_control_assert(dwc3_data->rstc_pwrdn);
+-undo_platform_dev_alloc:
+-      platform_device_put(pdev);
+       return ret;
+ }
+ 
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index cb0eb7fd25426..d34458f11d825 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -619,6 +619,8 @@ static void option_instat_callback(struct urb *urb);
+ 
+ /* MeiG Smart Technology products */
+ #define MEIGSMART_VENDOR_ID                   0x2dee
++/* MeiG Smart SRM825L based on Qualcomm 315 */
++#define MEIGSMART_PRODUCT_SRM825L             0x4d22
+ /* MeiG Smart SLM320 based on UNISOC UIS8910 */
+ #define MEIGSMART_PRODUCT_SLM320              0x4d41
+ 
+@@ -2366,6 +2368,9 @@ static const struct usb_device_id option_ids[] = {
+       { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 
0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 
0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, 
MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
++      { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, 
MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) },
++      { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, 
MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) },
++      { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, 
MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) },
+       { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
+index bb77f646366a5..013f61bbf28f8 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -2397,7 +2397,7 @@ static int tcpm_register_source_caps(struct tcpm_port 
*port)
+ {
+       struct usb_power_delivery_desc desc = { port->negotiated_rev };
+       struct usb_power_delivery_capabilities_desc caps = { };
+-      struct usb_power_delivery_capabilities *cap;
++      struct usb_power_delivery_capabilities *cap = port->partner_source_caps;
+ 
+       if (!port->partner_pd)
+               port->partner_pd = usb_power_delivery_register(NULL, &desc);
+@@ -2407,6 +2407,11 @@ static int tcpm_register_source_caps(struct tcpm_port 
*port)
+       memcpy(caps.pdo, port->source_caps, sizeof(u32) * port->nr_source_caps);
+       caps.role = TYPEC_SOURCE;
+ 
++      if (cap) {
++              usb_power_delivery_unregister_capabilities(cap);
++              port->partner_source_caps = NULL;
++      }
++
+       cap = usb_power_delivery_register_capabilities(port->partner_pd, &caps);
+       if (IS_ERR(cap))
+               return PTR_ERR(cap);
+@@ -2420,7 +2425,7 @@ static int tcpm_register_sink_caps(struct tcpm_port 
*port)
+ {
+       struct usb_power_delivery_desc desc = { port->negotiated_rev };
+       struct usb_power_delivery_capabilities_desc caps = { };
+-      struct usb_power_delivery_capabilities *cap = port->partner_source_caps;
++      struct usb_power_delivery_capabilities *cap;
+ 
+       if (!port->partner_pd)
+               port->partner_pd = usb_power_delivery_register(NULL, &desc);
+@@ -2430,11 +2435,6 @@ static int tcpm_register_sink_caps(struct tcpm_port 
*port)
+       memcpy(caps.pdo, port->sink_caps, sizeof(u32) * port->nr_sink_caps);
+       caps.role = TYPEC_SINK;
+ 
+-      if (cap) {
+-              usb_power_delivery_unregister_capabilities(cap);
+-              port->partner_source_caps = NULL;
+-      }
+-
+       cap = usb_power_delivery_register_capabilities(port->partner_pd, &caps);
+       if (IS_ERR(cap))
+               return PTR_ERR(cap);
+diff --git a/drivers/video/fbdev/offb.c b/drivers/video/fbdev/offb.c
+index 6f0a9851b0924..ea232395e226f 100644
+--- a/drivers/video/fbdev/offb.c
++++ b/drivers/video/fbdev/offb.c
+@@ -27,6 +27,7 @@
+ #include <linux/ioport.h>
+ #include <linux/pci.h>
+ #include <linux/platform_device.h>
++#include <linux/cleanup.h>
+ #include <asm/io.h>
+ 
+ #ifdef CONFIG_PPC32
+diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
+index e6635fe700678..cb56ac8b925e6 100644
+--- a/fs/btrfs/compression.c
++++ b/fs/btrfs/compression.c
+@@ -613,6 +613,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
+                       put_page(page);
+                       break;
+               }
++              add_size = min(em->start + em->len, page_end + 1) - cur;
+               free_extent_map(em);
+ 
+               if (page->index == end_index) {
+@@ -625,7 +626,6 @@ static noinline int add_ra_bio_pages(struct inode *inode,
+                       }
+               }
+ 
+-              add_size = min(em->start + em->len, page_end + 1) - cur;
+               ret = bio_add_page(cb->orig_bio, page, add_size, 
offset_in_page(cur));
+               if (ret != add_size) {
+                       unlock_extent(tree, cur, page_end, NULL);
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index f3b066b442807..59bb9653615e8 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -3745,6 +3745,8 @@ static int try_flush_qgroup(struct btrfs_root *root)
+               return 0;
+       }
+ 
++      btrfs_run_delayed_iputs(root->fs_info);
++      btrfs_wait_on_delayed_iputs(root->fs_info);
+       ret = btrfs_start_delalloc_snapshot(root, true);
+       if (ret < 0)
+               goto out;
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index fad4b5dcfbd5a..992ac7d20e5eb 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -4184,7 +4184,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
+        * If we want to do a RDMA write, fill in and append
+        * smbd_buffer_descriptor_v1 to the end of read request
+        */
+-      if (smb3_use_rdma_offload(io_parms)) {
++      if (rdata && smb3_use_rdma_offload(io_parms)) {
+               struct smbd_buffer_descriptor_v1 *v1;
+               bool need_invalidate = server->dialect == SMB30_PROT_ID;
+ 
+diff --git a/include/linux/of.h b/include/linux/of.h
+index 1c5301e10442f..2960e609ca05e 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -13,6 +13,7 @@
+  */
+ #include <linux/types.h>
+ #include <linux/bitops.h>
++#include <linux/cleanup.h>
+ #include <linux/errno.h>
+ #include <linux/kobject.h>
+ #include <linux/mod_devicetable.h>
+@@ -128,6 +129,7 @@ static inline struct device_node *of_node_get(struct 
device_node *node)
+ }
+ static inline void of_node_put(struct device_node *node) { }
+ #endif /* !CONFIG_OF_DYNAMIC */
++DEFINE_FREE(device_node, struct device_node *, if (_T) of_node_put(_T))
+ 
+ /* Pointer for first entry in chain of all nodes. */
+ extern struct device_node *of_root;
+@@ -1371,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))
+diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h
+index f90f0021f5f2d..5387e1daa5a8b 100644
+--- a/include/net/busy_poll.h
++++ b/include/net/busy_poll.h
+@@ -63,7 +63,7 @@ static inline bool sk_can_busy_loop(struct sock *sk)
+ static inline unsigned long busy_loop_current_time(void)
+ {
+ #ifdef CONFIG_NET_RX_BUSY_POLL
+-      return (unsigned long)(local_clock() >> 10);
++      return (unsigned long)(ktime_get_ns() >> 10);
+ #else
+       return 0;
+ #endif
+diff --git a/include/net/netfilter/nf_tables_ipv4.h 
b/include/net/netfilter/nf_tables_ipv4.h
+index 5225d2bd1a6e9..10b0a7c9e721f 100644
+--- a/include/net/netfilter/nf_tables_ipv4.h
++++ b/include/net/netfilter/nf_tables_ipv4.h
+@@ -19,7 +19,7 @@ static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo 
*pkt)
+ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
+ {
+       struct iphdr *iph, _iph;
+-      u32 len, thoff;
++      u32 len, thoff, skb_len;
+ 
+       iph = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb),
+                                sizeof(*iph), &_iph);
+@@ -30,15 +30,17 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct 
nft_pktinfo *pkt)
+               return -1;
+ 
+       len = iph_totlen(pkt->skb, iph);
+-      thoff = skb_network_offset(pkt->skb) + (iph->ihl * 4);
+-      if (pkt->skb->len < len)
++      thoff = iph->ihl * 4;
++      skb_len = pkt->skb->len - skb_network_offset(pkt->skb);
++
++      if (skb_len < len)
+               return -1;
+       else if (len < thoff)
+               return -1;
+ 
+       pkt->flags = NFT_PKTINFO_L4PROTO;
+       pkt->tprot = iph->protocol;
+-      pkt->thoff = thoff;
++      pkt->thoff = skb_network_offset(pkt->skb) + thoff;
+       pkt->fragoff = ntohs(iph->frag_off) & IP_OFFSET;
+ 
+       return 0;
+diff --git a/include/net/netfilter/nf_tables_ipv6.h 
b/include/net/netfilter/nf_tables_ipv6.h
+index ec7eaeaf4f04c..f1d6a65280475 100644
+--- a/include/net/netfilter/nf_tables_ipv6.h
++++ b/include/net/netfilter/nf_tables_ipv6.h
+@@ -31,8 +31,8 @@ static inline int __nft_set_pktinfo_ipv6_validate(struct 
nft_pktinfo *pkt)
+       struct ipv6hdr *ip6h, _ip6h;
+       unsigned int thoff = 0;
+       unsigned short frag_off;
++      u32 pkt_len, skb_len;
+       int protohdr;
+-      u32 pkt_len;
+ 
+       ip6h = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb),
+                                 sizeof(*ip6h), &_ip6h);
+@@ -43,7 +43,8 @@ static inline int __nft_set_pktinfo_ipv6_validate(struct 
nft_pktinfo *pkt)
+               return -1;
+ 
+       pkt_len = ntohs(ip6h->payload_len);
+-      if (pkt_len + sizeof(*ip6h) > pkt->skb->len)
++      skb_len = pkt->skb->len - skb_network_offset(pkt->skb);
++      if (pkt_len + sizeof(*ip6h) > skb_len)
+               return -1;
+ 
+       protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);
+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;
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 210e03a3609d4..dc19a0b1a2f6d 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2405,10 +2405,16 @@ static int hci_suspend_notifier(struct notifier_block 
*nb, unsigned long action,
+       /* To avoid a potential race with hci_unregister_dev. */
+       hci_dev_hold(hdev);
+ 
+-      if (action == PM_SUSPEND_PREPARE)
++      switch (action) {
++      case PM_HIBERNATION_PREPARE:
++      case PM_SUSPEND_PREPARE:
+               ret = hci_suspend_dev(hdev);
+-      else if (action == PM_POST_SUSPEND)
++              break;
++      case PM_POST_HIBERNATION:
++      case PM_POST_SUSPEND:
+               ret = hci_resume_dev(hdev);
++              break;
++      }
+ 
+       if (ret)
+               bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
+diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
+index fdf3308b03350..8a06f97320e04 100644
+--- a/net/core/net-sysfs.c
++++ b/net/core/net-sysfs.c
+@@ -215,7 +215,7 @@ static ssize_t speed_show(struct device *dev,
+       if (!rtnl_trylock())
+               return restart_syscall();
+ 
+-      if (netif_running(netdev) && netif_device_present(netdev)) {
++      if (netif_running(netdev)) {
+               struct ethtool_link_ksettings cmd;
+ 
+               if (!__ethtool_get_link_ksettings(netdev, &cmd))
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index e31d1247b9f08..442c4c343e155 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -445,6 +445,9 @@ int __ethtool_get_link_ksettings(struct net_device *dev,
+       if (!dev->ethtool_ops->get_link_ksettings)
+               return -EOPNOTSUPP;
+ 
++      if (!netif_device_present(dev))
++              return -ENODEV;
++
+       memset(link_ksettings, 0, sizeof(*link_ksettings));
+       return dev->ethtool_ops->get_link_ksettings(dev, link_ksettings);
+ }
+diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
+index a27ee627addef..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)
+@@ -235,7 +225,9 @@ void mptcp_pm_add_addr_received(const struct sock *ssk,
+               } else {
+                       __MPTCP_INC_STATS(sock_net((struct sock *)msk), 
MPTCP_MIB_ADDADDRDROP);
+               }
+-      } else if (!READ_ONCE(pm->accept_addr)) {
++      /* id0 should not have a different address */
++      } else if ((addr->id == 0 && !mptcp_pm_nl_is_init_remote_addr(msk, 
addr)) ||
++                 (addr->id > 0 && !READ_ONCE(pm->accept_addr))) {
+               mptcp_pm_announce_addr(msk, addr, true);
+               mptcp_pm_add_addr_send_ack(msk);
+       } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) {
+@@ -413,7 +405,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 2bce3a32bd881..9e16ae1b23fc7 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -134,12 +134,15 @@ static bool lookup_subflow_by_daddr(const struct 
list_head *list,
+ {
+       struct mptcp_subflow_context *subflow;
+       struct mptcp_addr_info cur;
+-      struct sock_common *skc;
+ 
+       list_for_each_entry(subflow, list, node) {
+-              skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);
++              struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
++
++              if (!((1 << inet_sk_state_load(ssk)) &
++                    (TCPF_ESTABLISHED | TCPF_SYN_SENT | TCPF_SYN_RECV)))
++                      continue;
+ 
+-              remote_address(skc, &cur);
++              remote_address((struct sock_common *)ssk, &cur);
+               if (mptcp_addresses_equal(&cur, daddr, daddr->port))
+                       return true;
+       }
+@@ -736,6 +739,15 @@ static void mptcp_pm_nl_add_addr_received(struct 
mptcp_sock *msk)
+       }
+ }
+ 
++bool mptcp_pm_nl_is_init_remote_addr(struct mptcp_sock *msk,
++                                   const struct mptcp_addr_info *remote)
++{
++      struct mptcp_addr_info mpc_remote;
++
++      remote_address((struct sock_common *)msk, &mpc_remote);
++      return mptcp_addresses_equal(&mpc_remote, remote, remote->port);
++}
++
+ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
+ {
+       struct mptcp_subflow_context *subflow;
+@@ -747,9 +759,12 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
+           !mptcp_pm_should_rm_signal(msk))
+               return;
+ 
+-      subflow = list_first_entry_or_null(&msk->conn_list, typeof(*subflow), 
node);
+-      if (subflow)
+-              mptcp_pm_send_ack(msk, subflow, false, false);
++      mptcp_for_each_subflow(msk, subflow) {
++              if (__mptcp_subflow_active(subflow)) {
++                      mptcp_pm_send_ack(msk, subflow, false, false);
++                      break;
++              }
++      }
+ }
+ 
+ int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
+@@ -819,6 +834,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct 
mptcp_sock *msk,
+                       int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
+                       u8 id = subflow_get_local_id(subflow);
+ 
++                      if (inet_sk_state_load(ssk) == TCP_CLOSE)
++                              continue;
+                       if (rm_type == MPTCP_MIB_RMADDR && remote_id != rm_id)
+                               continue;
+                       if (rm_type == MPTCP_MIB_RMSUBFLOW && 
!mptcp_local_id_match(msk, id, rm_id))
+@@ -838,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;
+ 
+@@ -853,10 +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);
+-              } else if (rm_type == MPTCP_MIB_RMSUBFLOW) {
+-                      msk->pm.local_addr_used--;
++                      if (--msk->pm.add_addr_accepted < 
mptcp_pm_get_add_addr_accept_max(msk))
++                              WRITE_ONCE(msk->pm.accept_addr, true);
+               }
+       }
+ }
+@@ -866,8 +881,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);
+ }
+@@ -1074,33 +1089,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;
+               }
+@@ -1114,7 +1113,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;
+@@ -1328,20 +1327,27 @@ static struct pm_nl_pernet *genl_info_pm_nl(struct 
genl_info *info)
+       return pm_nl_get_pernet(genl_info_net(info));
+ }
+ 
+-static int mptcp_nl_add_subflow_or_signal_addr(struct net *net)
++static int mptcp_nl_add_subflow_or_signal_addr(struct net *net,
++                                             struct mptcp_addr_info *addr)
+ {
+       struct mptcp_sock *msk;
+       long s_slot = 0, s_num = 0;
+ 
+       while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
+               struct sock *sk = (struct sock *)msk;
++              struct mptcp_addr_info mpc_addr;
+ 
+               if (!READ_ONCE(msk->fully_established) ||
+                   mptcp_pm_is_userspace(msk))
+                       goto next;
+ 
++              /* if the endp linked to the init sf is re-added with a != ID */
++              mptcp_local_address((struct sock_common *)msk, &mpc_addr);
++
+               lock_sock(sk);
+               spin_lock_bh(&msk->pm.lock);
++              if (mptcp_addresses_equal(addr, &mpc_addr, addr->port))
++                      msk->mpc_endpoint_id = addr->id;
+               mptcp_pm_create_subflow_or_signal_addr(msk);
+               spin_unlock_bh(&msk->pm.lock);
+               release_sock(sk);
+@@ -1414,7 +1420,7 @@ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, 
struct genl_info *info)
+               goto out_free;
+       }
+ 
+-      mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk));
++      mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk), &entry->addr);
+       return 0;
+ 
+ out_free:
+@@ -1488,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)
+ {
+@@ -1518,15 +1532,19 @@ 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);
+-              } else if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
+-                      /* If the subflow has been used, but now closed */
+                       spin_lock_bh(&msk->pm.lock);
+-                      if (!__test_and_set_bit(entry->addr.id, 
msk->pm.id_avail_bitmap))
+-                              msk->pm.local_addr_used--;
++                      mptcp_pm_nl_rm_subflow_received(msk, &list);
++                      spin_unlock_bh(&msk->pm.lock);
++              }
++
++              if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
++                      spin_lock_bh(&msk->pm.lock);
++                      __mark_subflow_endp_available(msk, list.ids[0]);
+                       spin_unlock_bh(&msk->pm.lock);
+               }
+ 
++              if (msk->mpc_endpoint_id == entry->addr.id)
++                      msk->mpc_endpoint_id = 0;
+               release_sock(sk);
+ 
+ next:
+@@ -1561,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);
+ 
+@@ -1664,18 +1683,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);
+@@ -1957,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);
+ }
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index 75ae91c931294..258dbfe9fad30 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2309,7 +2309,7 @@ static struct sock *mptcp_subflow_get_retrans(struct 
mptcp_sock *msk)
+                       continue;
+               }
+ 
+-              if (subflow->backup) {
++              if (subflow->backup || subflow->request_bkup) {
+                       if (!backup)
+                               backup = ssk;
+                       continue;
+@@ -2528,8 +2528,11 @@ static void __mptcp_close_subflow(struct sock *sk)
+ 
+       mptcp_for_each_subflow_safe(msk, subflow, tmp) {
+               struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
++              int ssk_state = inet_sk_state_load(ssk);
+ 
+-              if (inet_sk_state_load(ssk) != TCP_CLOSE)
++              if (ssk_state != TCP_CLOSE &&
++                  (ssk_state != TCP_CLOSE_WAIT ||
++                   inet_sk_state_load(sk) != TCP_ESTABLISHED))
+                       continue;
+ 
+               /* 'subflow_data_ready' will re-sched once rx queue is empty */
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index 4515cc6b649fc..c3cd68edab779 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -802,6 +802,8 @@ void mptcp_pm_add_addr_received(const struct sock *ssk,
+ void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk,
+                             const struct mptcp_addr_info *addr);
+ void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk);
++bool mptcp_pm_nl_is_init_remote_addr(struct mptcp_sock *msk,
++                                   const struct mptcp_addr_info *remote);
+ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk);
+ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
+                              const struct mptcp_rm_list *rm_list);
+@@ -834,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);
+@@ -912,6 +913,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);
+@@ -928,9 +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);
+-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);
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index b47673b370279..1a92c8edd0a0e 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1137,12 +1137,16 @@ static void mptcp_subflow_discard_data(struct sock 
*ssk, struct sk_buff *skb,
+ /* sched mptcp worker to remove the subflow if no more data is pending */
+ static void subflow_sched_work_if_closed(struct mptcp_sock *msk, struct sock 
*ssk)
+ {
+-      if (likely(ssk->sk_state != TCP_CLOSE))
++      struct sock *sk = (struct sock *)msk;
++
++      if (likely(ssk->sk_state != TCP_CLOSE &&
++                 (ssk->sk_state != TCP_CLOSE_WAIT ||
++                  inet_sk_state_load(sk) != TCP_ESTABLISHED)))
+               return;
+ 
+       if (skb_queue_empty(&ssk->sk_receive_queue) &&
+           !test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
+-              mptcp_schedule_work((struct sock *)msk);
++              mptcp_schedule_work(sk);
+ }
+ 
+ static bool subflow_can_fallback(struct mptcp_subflow_context *subflow)
+diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
+index 5383b6a9da61c..a56749a50e5c5 100644
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -2261,12 +2261,6 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
+               }
+       }
+ 
+-      /* Update socket peer label if first association. */
+-      if (security_sctp_assoc_request(new_asoc, chunk->head_skb ?: 
chunk->skb)) {
+-              sctp_association_free(new_asoc);
+-              return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+-      }
+-
+       /* Set temp so that it won't be added into hashtable */
+       new_asoc->temp = 1;
+ 
+@@ -2275,6 +2269,22 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
+        */
+       action = sctp_tietags_compare(new_asoc, asoc);
+ 
++      /* In cases C and E the association doesn't enter the ESTABLISHED
++       * state, so there is no need to call security_sctp_assoc_request().
++       */
++      switch (action) {
++      case 'A': /* Association restart. */
++      case 'B': /* Collision case B. */
++      case 'D': /* Collision case D. */
++              /* Update socket peer label if first association. */
++              if (security_sctp_assoc_request((struct sctp_association *)asoc,
++                                              chunk->head_skb ?: chunk->skb)) 
{
++                      sctp_association_free(new_asoc);
++                      return sctp_sf_pdiscard(net, ep, asoc, type, arg, 
commands);
++              }
++              break;
++      }
++
+       switch (action) {
+       case 'A': /* Association restart. */
+               retval = sctp_sf_do_dupcook_a(net, ep, asoc, chunk, commands,
+diff --git a/security/apparmor/policy_unpack_test.c 
b/security/apparmor/policy_unpack_test.c
+index f25cf2a023d57..0711a0305df34 100644
+--- a/security/apparmor/policy_unpack_test.c
++++ b/security/apparmor/policy_unpack_test.c
+@@ -81,14 +81,14 @@ static struct aa_ext *build_aa_ext_struct(struct 
policy_unpack_fixture *puf,
+       *(buf + 1) = strlen(TEST_U32_NAME) + 1;
+       strcpy(buf + 3, TEST_U32_NAME);
+       *(buf + 3 + strlen(TEST_U32_NAME) + 1) = AA_U32;
+-      *((u32 *)(buf + 3 + strlen(TEST_U32_NAME) + 2)) = TEST_U32_DATA;
++      *((__le32 *)(buf + 3 + strlen(TEST_U32_NAME) + 2)) = 
cpu_to_le32(TEST_U32_DATA);
+ 
+       buf = e->start + TEST_NAMED_U64_BUF_OFFSET;
+       *buf = AA_NAME;
+       *(buf + 1) = strlen(TEST_U64_NAME) + 1;
+       strcpy(buf + 3, TEST_U64_NAME);
+       *(buf + 3 + strlen(TEST_U64_NAME) + 1) = AA_U64;
+-      *((u64 *)(buf + 3 + strlen(TEST_U64_NAME) + 2)) = TEST_U64_DATA;
++      *((__le64 *)(buf + 3 + strlen(TEST_U64_NAME) + 2)) = 
cpu_to_le64(TEST_U64_DATA);
+ 
+       buf = e->start + TEST_NAMED_BLOB_BUF_OFFSET;
+       *buf = AA_NAME;
+@@ -104,7 +104,7 @@ static struct aa_ext *build_aa_ext_struct(struct 
policy_unpack_fixture *puf,
+       *(buf + 1) = strlen(TEST_ARRAY_NAME) + 1;
+       strcpy(buf + 3, TEST_ARRAY_NAME);
+       *(buf + 3 + strlen(TEST_ARRAY_NAME) + 1) = AA_ARRAY;
+-      *((u16 *)(buf + 3 + strlen(TEST_ARRAY_NAME) + 2)) = TEST_ARRAY_SIZE;
++      *((__le16 *)(buf + 3 + strlen(TEST_ARRAY_NAME) + 2)) = 
cpu_to_le16(TEST_ARRAY_SIZE);
+ 
+       return e;
+ }
+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,
+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
+diff --git a/tools/testing/selftests/net/forwarding/local_termination.sh 
b/tools/testing/selftests/net/forwarding/local_termination.sh
+index c5b0cbc85b3e0..9b5a63519b949 100755
+--- a/tools/testing/selftests/net/forwarding/local_termination.sh
++++ b/tools/testing/selftests/net/forwarding/local_termination.sh
+@@ -278,6 +278,10 @@ bridge()
+ cleanup()
+ {
+       pre_cleanup
++
++      ip link set $h2 down
++      ip link set $h1 down
++
+       vrf_cleanup
+ }
+ 
+diff --git a/tools/testing/selftests/net/forwarding/no_forwarding.sh 
b/tools/testing/selftests/net/forwarding/no_forwarding.sh
+index af3b398d13f01..9e677aa64a06a 100755
+--- a/tools/testing/selftests/net/forwarding/no_forwarding.sh
++++ b/tools/testing/selftests/net/forwarding/no_forwarding.sh
+@@ -233,6 +233,9 @@ cleanup()
+ {
+       pre_cleanup
+ 
++      ip link set dev $swp2 down
++      ip link set dev $swp1 down
++
+       h2_destroy
+       h1_destroy
+ 


Reply via email to