--- /dev/null
+From 86152fef52cac15cd662ed3bfc7604fbfef378f0 Mon Sep 17 00:00:00 2001
+From: Ao Sun <ao.sun@transsion.com>
+Date: Mon, 6 Jul 2026 11:43:00 +0000
+Subject: mmc: block: fix RPMB device unregister ordering
+
+From: Ao Sun <ao.sun@transsion.com>
+
+commit 86152fef52cac15cd662ed3bfc7604fbfef378f0 upstream.
+
+Since commit 7852028a35f0 ("mmc: block: register RPMB partition with
+the RPMB subsystem"), each mmc RPMB partition is represented by two
+device objects:
+ - the mmc-owned device (`rpmb->dev`, backing the legacy /dev/mmcblkXrpmb
+ char device) and
+ - the rpmb-core device (`rdev`, backing /dev/rpmbN).
+
+The child RPMB device holds a reference to its parent, so the
+parent's release callback cannot be invoked if the child device
+is still registered.
+
+Remove rpmb_dev_unregister() from the parent release handler and
+unregister the child RPMB device in the remove path before tearing
+down the parent device.
+
+Also delete the extra blank line between mmc_blk_remove_rpmb_part()
+and {.
+
+Fixes: 7852028a35f0 ("mmc: block: register RPMB partition with the RPMB subsystem")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jiazi Li <jiazi.li@transsion.com>
+Signed-off-by: Ao Sun <ao.sun@transsion.com>
+Reviewed-by: Avri Altman <avri.altman@sandisk.com>
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/core/block.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -2715,7 +2715,6 @@ static void mmc_blk_rpmb_device_release(
+ {
+ struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev);
+
+- rpmb_dev_unregister(rpmb->rdev);
+ mmc_blk_put(rpmb->md);
+ ida_free(&mmc_rpmb_ida, rpmb->id);
+ kfree(rpmb);
+@@ -2930,8 +2929,8 @@ out_put_device:
+ }
+
+ static void mmc_blk_remove_rpmb_part(struct mmc_rpmb_data *rpmb)
+-
+ {
++ rpmb_dev_unregister(rpmb->rdev);
+ cdev_device_del(&rpmb->chrdev, &rpmb->dev);
+ put_device(&rpmb->dev);
+ }
--- /dev/null
+From c35fac6481a1dbb2d114dd337b54a40799437546 Mon Sep 17 00:00:00 2001
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Date: Tue, 2 Jun 2026 21:13:44 +0100
+Subject: mmc: mmc_test: Fix __counted_by handling after kzalloc_flex() conversion
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+commit c35fac6481a1dbb2d114dd337b54a40799437546 upstream.
+
+Fix logic issues introduced by the kzalloc_flex() conversion in
+mmc_test_alloc_mem() due to interaction with the __counted_by
+annotation on the flexible array.
+
+Bounds-checking sanitizers rely on the counter field reflecting the
+allocated array size before any array access occurs. However, use
+mem->cnt both as the allocation size and as the runtime insertion
+index, causing incorrect indexing and potentially invalid bounds
+tracking.
+
+Initialize mem->cnt to the maximum allocated number of segments
+immediately after kzalloc_flex(), then use a separate local index
+variable to track successfully allocated entries. Update mem->cnt to
+the actual number of initialized elements before returning or entering
+the cleanup path.
+
+Also rewrite mmc_test_free_mem() to use a forward for-loop, improving
+readability and ensuring only initialized entries are freed.
+
+Fixes: c3126dccfd7b ("mmc: mmc_test: use kzalloc_flex")
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/core/mmc_test.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c
+index ab38e4c45a8d..4dc16649e61d 100644
+--- a/drivers/mmc/core/mmc_test.c
++++ b/drivers/mmc/core/mmc_test.c
+@@ -318,9 +318,9 @@ static void mmc_test_free_mem(struct mmc_test_mem *mem)
+ {
+ if (!mem)
+ return;
+- while (mem->cnt--)
+- __free_pages(mem->arr[mem->cnt].page,
+- mem->arr[mem->cnt].order);
++ for (unsigned int i = 0; i < mem->cnt; i++)
++ __free_pages(mem->arr[i].page,
++ mem->arr[i].order);
+ kfree(mem);
+ }
+
+@@ -341,6 +341,7 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
+ unsigned long page_cnt = 0;
+ unsigned long limit = nr_free_buffer_pages() >> 4;
+ struct mmc_test_mem *mem;
++ unsigned int idx = 0;
+
+ if (max_page_cnt > limit)
+ max_page_cnt = limit;
+@@ -375,23 +376,26 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
+ goto out_free;
+ break;
+ }
+- mem->arr[mem->cnt].page = page;
+- mem->arr[mem->cnt].order = order;
+- mem->cnt += 1;
++ mem->arr[idx].page = page;
++ mem->arr[idx].order = order;
++ idx += 1;
+ if (max_page_cnt <= (1UL << order))
+ break;
+ max_page_cnt -= 1UL << order;
+ page_cnt += 1UL << order;
+- if (mem->cnt >= max_segs) {
++ if (idx >= mem->cnt) {
+ if (page_cnt < min_page_cnt)
+ goto out_free;
+ break;
+ }
+ }
+
++ mem->cnt = idx;
++
+ return mem;
+
+ out_free:
++ mem->cnt = idx;
+ mmc_test_free_mem(mem);
+ return NULL;
+ }
+--
+2.55.0
+
--- /dev/null
+From 9d87eaf985cef9581b6ed99b461b38e8cd666480 Mon Sep 17 00:00:00 2001
+From: Luke Wang <ziniu.wang_1@nxp.com>
+Date: Wed, 15 Jul 2026 15:18:15 +0800
+Subject: mmc: sdhci-esdhc-imx: disable irq during suspend to fix unhandled interrupt
+
+From: Luke Wang <ziniu.wang_1@nxp.com>
+
+commit 9d87eaf985cef9581b6ed99b461b38e8cd666480 upstream.
+
+When using WIFI out-of-band wakeup, an "irq xxx: nobody cared" warning
+occurs. This happens because the usdhc interrupt is not disabled during
+system suspend when device_may_wakeup() returns false.
+
+The sequence of events leading to this issue:
+1. System enters suspend without disabling usdhc interrupt
+(because device_may_wakeup() returns false for usdhc device)
+2. WIFI out-of-band wakeup triggers system resume via GPIO interrupt
+3. WIFI sends a Card interrupt before usdhc has fully resumed
+4. usdhc is still in runtime suspend state and cannot handle the
+interrupt properly
+5. The unhandled interrupt triggers "nobody cared" warning
+
+Fix this by unconditionally disabling the usdhc interrupt during suspend
+and re-enabling it during resume, regardless of the wakeup capability.
+This ensures no interrupts are processed during the suspend/resume
+transition.
+
+Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic")
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
+Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -2077,9 +2077,10 @@ static int sdhci_esdhc_suspend(struct de
+ if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data))
+ sdhc_esdhc_tuning_save(host);
+
++ /* The irqs of imx are not shared. It is safe to disable */
++ disable_irq(host->irq);
++
+ if (device_may_wakeup(dev)) {
+- /* The irqs of imx are not shared. It is safe to disable */
+- disable_irq(host->irq);
+ ret = sdhci_enable_irq_wakeups(host);
+ if (!ret)
+ dev_warn(dev, "Failed to enable irq wakeup\n");
+@@ -2130,10 +2131,10 @@ static int sdhci_esdhc_resume(struct dev
+ /* re-initialize hw state in case it's lost in low power mode */
+ sdhci_esdhc_imx_hwinit(host);
+
+- if (host->irq_wake_enabled) {
++ if (host->irq_wake_enabled)
+ sdhci_disable_irq_wakeups(host);
+- enable_irq(host->irq);
+- }
++
++ enable_irq(host->irq);
+
+ /*
+ * restore the saved tuning delay value for the device which keep
--- /dev/null
+From 5adc14cd4b905629d5b9163b3a416dcab24c7ce2 Mon Sep 17 00:00:00 2001
+From: Luke Wang <ziniu.wang_1@nxp.com>
+Date: Wed, 15 Jul 2026 15:18:13 +0800
+Subject: mmc: sdhci-esdhc-imx: fix esdhc_change_pinstate() to allow default state restore
+
+From: Luke Wang <ziniu.wang_1@nxp.com>
+
+commit 5adc14cd4b905629d5b9163b3a416dcab24c7ce2 upstream.
+
+esdhc_change_pinstate() checks for pins_100mhz and pins_200mhz at the
+top of the function and returns -EINVAL if either is not defined. This
+prevents the default case from ever being reached, which means devices
+with a sleep pinctrl state but without high-speed pin states (100mhz/
+200mhz) can never restore their default pin configuration.
+
+Move the IS_ERR checks for pins_100mhz and pins_200mhz into their
+respective switch cases.
+
+Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic")
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -1326,19 +1326,21 @@ static int esdhc_change_pinstate(struct
+
+ dev_dbg(mmc_dev(host->mmc), "change pinctrl state for uhs %d\n", uhs);
+
+- if (IS_ERR(imx_data->pinctrl) ||
+- IS_ERR(imx_data->pins_100mhz) ||
+- IS_ERR(imx_data->pins_200mhz))
++ if (IS_ERR(imx_data->pinctrl))
+ return -EINVAL;
+
+ switch (uhs) {
+ case MMC_TIMING_UHS_SDR50:
+ case MMC_TIMING_UHS_DDR50:
++ if (IS_ERR(imx_data->pins_100mhz))
++ return -EINVAL;
+ pinctrl = imx_data->pins_100mhz;
+ break;
+ case MMC_TIMING_UHS_SDR104:
+ case MMC_TIMING_MMC_HS200:
+ case MMC_TIMING_MMC_HS400:
++ if (IS_ERR(imx_data->pins_200mhz))
++ return -EINVAL;
+ pinctrl = imx_data->pins_200mhz;
+ break;
+ default:
--- /dev/null
+From e27c946b589c53520409a0956b33d52ef7a0898f Mon Sep 17 00:00:00 2001
+From: Luke Wang <ziniu.wang_1@nxp.com>
+Date: Wed, 15 Jul 2026 15:18:18 +0800
+Subject: mmc: sdhci-esdhc-imx: fix resume error handling
+
+From: Luke Wang <ziniu.wang_1@nxp.com>
+
+commit e27c946b589c53520409a0956b33d52ef7a0898f upstream.
+
+Check pm_runtime_force_resume() return value in resume. If it fails
+(clock enable failure), return immediately since accessing hardware
+registers on an unclocked device would cause a kernel panic.
+
+The early return intentionally skips enable_irq() and
+sdhci_disable_irq_wakeups() because the IRQ handler reads
+SDHCI_INT_STATUS, which would also fault without clocks. The PM runtime
+usage counter leak only affects this already-broken device instance and
+is an acceptable tradeoff to preserve system stability.
+
+Remove the return value check for mmc_gpio_set_cd_wake(host->mmc, false)
+since disable_irq_wake() called internally always returns 0.
+
+Also return 0 explicitly on the success path instead of propagating
+stale return values.
+
+Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic")
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -2123,12 +2123,12 @@ static int sdhci_esdhc_resume(struct dev
+ dev_warn(dev, "Failed to restore pinctrl state\n");
+ }
+
+- pm_runtime_force_resume(dev);
+-
+- ret = mmc_gpio_set_cd_wake(host->mmc, false);
++ ret = pm_runtime_force_resume(dev);
+ if (ret)
+ return ret;
+
++ mmc_gpio_set_cd_wake(host->mmc, false);
++
+ /* re-initialize hw state in case it's lost in low power mode */
+ sdhci_esdhc_imx_hwinit(host);
+
+@@ -2155,7 +2155,7 @@ static int sdhci_esdhc_resume(struct dev
+
+ pm_runtime_put_autosuspend(dev);
+
+- return ret;
++ return 0;
+ }
+
+ static int sdhci_esdhc_runtime_suspend(struct device *dev)
--- /dev/null
+From 6aa00a43bbd3d994558a55586351757cebbff236 Mon Sep 17 00:00:00 2001
+From: Luke Wang <ziniu.wang_1@nxp.com>
+Date: Wed, 15 Jul 2026 15:18:17 +0800
+Subject: mmc: sdhci-esdhc-imx: make non-fatal errors non-blocking in suspend
+
+From: Luke Wang <ziniu.wang_1@nxp.com>
+
+commit 6aa00a43bbd3d994558a55586351757cebbff236 upstream.
+
+Make pinctrl_pm_select_sleep_state() and mmc_gpio_set_cd_wake() failures
+non-fatal in the suspend path. These failures only mean slightly higher
+power consumption or missing CD wakeup capability, but should not block
+system suspend.
+
+Also change the function to always return 0 on the success path instead
+of propagating non-fatal warning return values.
+
+Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic")
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -2083,8 +2083,7 @@ static int sdhci_esdhc_suspend(struct de
+ disable_irq(host->irq);
+
+ if (device_may_wakeup(dev)) {
+- ret = sdhci_enable_irq_wakeups(host);
+- if (!ret)
++ if (!sdhci_enable_irq_wakeups(host))
+ dev_warn(dev, "Failed to enable irq wakeup\n");
+ } else {
+ /*
+@@ -2095,12 +2094,12 @@ static int sdhci_esdhc_suspend(struct de
+ * other function like GPIO function to save power in PM,
+ * which finally block the SDIO wakeup function.
+ */
+- ret = pinctrl_pm_select_sleep_state(dev);
+- if (ret)
+- return ret;
++ if (pinctrl_pm_select_sleep_state(dev))
++ dev_warn(dev, "Failed to select sleep pinctrl state\n");
+ }
+
+- ret = mmc_gpio_set_cd_wake(host->mmc, true);
++ if (mmc_gpio_set_cd_wake(host->mmc, true))
++ dev_warn(dev, "Failed to enable cd wake\n");
+
+ /*
+ * Make sure invoke runtime_suspend to gate off clock.
+@@ -2108,7 +2107,7 @@ static int sdhci_esdhc_suspend(struct de
+ */
+ pm_runtime_force_suspend(dev);
+
+- return ret;
++ return 0;
+ }
+
+ static int sdhci_esdhc_resume(struct device *dev)
--- /dev/null
+From 899160e2774d9952e9f2770b38f701ff1906c0b2 Mon Sep 17 00:00:00 2001
+From: Luke Wang <ziniu.wang_1@nxp.com>
+Date: Wed, 15 Jul 2026 15:18:11 +0800
+Subject: mmc: sdhci-esdhc-imx: remove unnecessary mmc_card_wake_sdio_irq check for tuning save/restore
+
+From: Luke Wang <ziniu.wang_1@nxp.com>
+
+commit 899160e2774d9952e9f2770b38f701ff1906c0b2 upstream.
+
+The tuning save/restore during system PM is conditioned on
+mmc_card_wake_sdio_irq(), but this check is unrelated to whether
+tuning values need to be preserved. The actual requirement is that
+the card keeps power during suspend and the controller is a uSDHC.
+
+SDIO devices using out-of-band GPIO wakeup maintain power during
+suspend but do not set the SDIO IRQ wake flag. In this case the
+tuning delay values are not saved/restored.
+
+Remove the unnecessary mmc_card_wake_sdio_irq() condition from both
+the suspend save and resume restore paths.
+
+Fixes: c63d25cdc59a ("mmc: sdhci-esdhc-imx: Save tuning value when card stays powered in suspend")
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
+Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -2064,8 +2064,7 @@ static int sdhci_esdhc_suspend(struct de
+ * to save the tuning delay value just in case the usdhc
+ * lost power during system PM.
+ */
+- if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) &&
+- esdhc_is_usdhc(imx_data))
++ if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data))
+ sdhc_esdhc_tuning_save(host);
+
+ if (device_may_wakeup(dev)) {
+@@ -2130,8 +2129,7 @@ static int sdhci_esdhc_resume(struct dev
+ * restore the saved tuning delay value for the device which keep
+ * power during system PM.
+ */
+- if (mmc_card_keep_power(host->mmc) && mmc_card_wake_sdio_irq(host->mmc) &&
+- esdhc_is_usdhc(imx_data))
++ if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data))
+ sdhc_esdhc_tuning_restore(host);
+
+ pm_runtime_put_autosuspend(dev);
--- /dev/null
+From 2439becd91bad6883b135044f85f83a0538b96a6 Mon Sep 17 00:00:00 2001
+From: Luke Wang <ziniu.wang_1@nxp.com>
+Date: Wed, 15 Jul 2026 15:18:12 +0800
+Subject: mmc: sdhci-esdhc-imx: restore DLL override for DDR modes on resume
+
+From: Luke Wang <ziniu.wang_1@nxp.com>
+
+commit 2439becd91bad6883b135044f85f83a0538b96a6 upstream.
+
+sdhci_esdhc_imx_hwinit() unconditionally clears ESDHC_DLL_CTRL by
+writing zero. For SDIO devices that keep power during system suspend
+and operate in DDR mode, the card remains in DDR timing while the host
+DLL override configuration is lost.
+
+Extract the DLL override setup from esdhc_set_uhs_signaling() into
+a helper esdhc_set_dll_override(), and call it on the resume path
+when the card kept power and is using a DDR timing mode.
+
+Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic")
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
+Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 39 ++++++++++++++++++++++++++-----------
+ 1 file changed, 28 insertions(+), 11 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -1349,6 +1349,23 @@ static int esdhc_change_pinstate(struct
+ return pinctrl_select_state(imx_data->pinctrl, pinctrl);
+ }
+
++static void esdhc_set_dll_override(struct sdhci_host *host)
++{
++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++ struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
++ struct esdhc_platform_data *boarddata = &imx_data->boarddata;
++ u32 v;
++
++ if (!boarddata->delay_line)
++ return;
++
++ v = boarddata->delay_line << ESDHC_DLL_OVERRIDE_VAL_SHIFT |
++ (1 << ESDHC_DLL_OVERRIDE_EN_SHIFT);
++ if (is_imx53_esdhc(imx_data))
++ v <<= 1;
++ writel(v, host->ioaddr + ESDHC_DLL_CTRL);
++}
++
+ /*
+ * For HS400 eMMC, there is a data_strobe line. This signal is generated
+ * by the device and used for data output and CRC status response output
+@@ -1404,7 +1421,6 @@ static void esdhc_set_uhs_signaling(stru
+ u32 m;
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
+- struct esdhc_platform_data *boarddata = &imx_data->boarddata;
+
+ /* disable ddr mode and disable HS400 mode */
+ m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+@@ -1425,15 +1441,7 @@ static void esdhc_set_uhs_signaling(stru
+ m |= ESDHC_MIX_CTRL_DDREN;
+ writel(m, host->ioaddr + ESDHC_MIX_CTRL);
+ imx_data->is_ddr = 1;
+- if (boarddata->delay_line) {
+- u32 v;
+- v = boarddata->delay_line <<
+- ESDHC_DLL_OVERRIDE_VAL_SHIFT |
+- (1 << ESDHC_DLL_OVERRIDE_EN_SHIFT);
+- if (is_imx53_esdhc(imx_data))
+- v <<= 1;
+- writel(v, host->ioaddr + ESDHC_DLL_CTRL);
+- }
++ esdhc_set_dll_override(host);
+ break;
+ case MMC_TIMING_MMC_HS400:
+ m |= ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN;
+@@ -2129,9 +2137,18 @@ static int sdhci_esdhc_resume(struct dev
+ * restore the saved tuning delay value for the device which keep
+ * power during system PM.
+ */
+- if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data))
++ if (mmc_card_keep_power(host->mmc) && esdhc_is_usdhc(imx_data)) {
+ sdhc_esdhc_tuning_restore(host);
+
++ /*
++ * Restore DLL override for DDR modes. hwinit unconditionally
++ * clears ESDHC_DLL_CTRL, but the card is still in DDR mode.
++ */
++ if (host->timing == MMC_TIMING_UHS_DDR50 ||
++ host->timing == MMC_TIMING_MMC_DDR52)
++ esdhc_set_dll_override(host);
++ }
++
+ pm_runtime_put_autosuspend(dev);
+
+ return ret;
--- /dev/null
+From 8da5930144712412d85e7f868693d96ec5c2018c Mon Sep 17 00:00:00 2001
+From: Luke Wang <ziniu.wang_1@nxp.com>
+Date: Wed, 15 Jul 2026 15:18:16 +0800
+Subject: mmc: sdhci-esdhc-imx: use pm_runtime_resume_and_get() in suspend
+
+From: Luke Wang <ziniu.wang_1@nxp.com>
+
+commit 8da5930144712412d85e7f868693d96ec5c2018c upstream.
+
+Replace pm_runtime_get_sync() with pm_runtime_resume_and_get() to
+simplify error handling. pm_runtime_resume_and_get() automatically
+drops the usage counter on failure, avoiding the need for a separate
+pm_runtime_put_noidle() call. If it fails, the device is unclocked and
+accessing hardware registers would cause a kernel panic, so return the
+error immediately.
+
+Fixes: 676a83855614 ("mmc: host: sdhci-esdhc-imx: refactor the system PM logic")
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -2061,7 +2061,9 @@ static int sdhci_esdhc_suspend(struct de
+ * 2, make sure the pm_runtime_force_resume() in sdhci_esdhc_resume() really
+ * invoke its ->runtime_resume callback (needs_force_resume = 1).
+ */
+- pm_runtime_get_sync(dev);
++ ret = pm_runtime_resume_and_get(dev);
++ if (ret)
++ return ret;
+
+ if ((imx_data->socdata->flags & ESDHC_FLAG_STATE_LOST_IN_LPMODE) &&
+ (host->tuning_mode != SDHCI_TUNING_MODE_1)) {
--- /dev/null
+From 521f39ca93cc43ce1b3eae8d44201f8f55dd9151 Mon Sep 17 00:00:00 2001
+From: Sergey Shtylyov <s.shtylyov@auroraos.dev>
+Date: Mon, 1 Jun 2026 17:49:01 +0300
+Subject: mmc: sdhci-of-dwcmshc: check bus clock enable result in the probe() method
+
+From: Sergey Shtylyov <s.shtylyov@auroraos.dev>
+
+commit 521f39ca93cc43ce1b3eae8d44201f8f55dd9151 upstream.
+
+In the driver's probe() method, clk_disable_unprepare() for the bus clock
+is called on the error path even if the prior clk_prepare_enable() call has
+failed (and the same thing happens in the remove() method as well) -- that
+would cause the prepare/enable counter imbalance. Also, the same problem
+can happen in the driver's suspend() method; note that the resume() method
+does check the clk_prepare_enable()'s result -- let's be consistent and do
+that in probe() method as well. BTW, I don't know for sure what does the
+bus clock control -- if it affects the register accesses, the driver will
+likely cause (e.g. on ARM) a kernel oops if it fails to prepare/enable the
+bus clock in the probe() method...
+
+Found by Linux Verification Center (linuxtesting.org) with the Svace static
+analysis tool.
+
+Fixes: e438cf49b305 ("mmc: sdhci-of-dwcmshc: add SDHCI OF Synopsys DWC MSHC driver")
+Fixes: bccce2ec7790 ("mmc: sdhci-of-dwcmshc: add suspend/resume support")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@auroraos.dev>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/sdhci-of-dwcmshc.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
+@@ -2441,13 +2441,16 @@ static int dwcmshc_probe(struct platform
+ return err;
+
+ priv->bus_clk = devm_clk_get(dev, "bus");
+- if (!IS_ERR(priv->bus_clk))
+- clk_prepare_enable(priv->bus_clk);
++ if (!IS_ERR(priv->bus_clk)) {
++ err = clk_prepare_enable(priv->bus_clk);
++ if (err)
++ goto err_clk;
++ }
+ }
+
+ err = mmc_of_parse(host->mmc);
+ if (err)
+- goto err_clk;
++ goto err_bus_clk;
+
+ sdhci_get_of_property(pdev);
+
+@@ -2461,7 +2464,7 @@ static int dwcmshc_probe(struct platform
+ if (pltfm_data->init) {
+ err = pltfm_data->init(&pdev->dev, host, priv);
+ if (err)
+- goto err_clk;
++ goto err_bus_clk;
+ }
+
+ #ifdef CONFIG_ACPI
+@@ -2507,9 +2510,10 @@ err_setup_host:
+ err_rpm:
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
++err_bus_clk:
++ clk_disable_unprepare(priv->bus_clk);
+ err_clk:
+ clk_disable_unprepare(pltfm_host->clk);
+- clk_disable_unprepare(priv->bus_clk);
+ clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks);
+ return err;
+ }
--- /dev/null
+From ee5fb641c4ccac8406c668d3e947eb20ce44f233 Mon Sep 17 00:00:00 2001
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Date: Wed, 17 Jun 2026 23:23:19 +0800
+Subject: mmc: vub300: defer reset until cmd_mutex is unlocked
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+commit ee5fb641c4ccac8406c668d3e947eb20ce44f233 upstream.
+
+vub300_cmndwork_thread() holds cmd_mutex while it sends a command and
+waits for the command response. If the response wait times out,
+__vub300_command_response() kills the command URBs and then synchronously
+resets the USB device through usb_reset_device().
+
+That reset path re-enters the driver through vub300_pre_reset(), which
+also takes cmd_mutex. The worker therefore tries to acquire the same
+mutex recursively while it is still holding it from the command path.
+
+This issue was found by our static analysis tool and then manually
+reviewed against the current tree.
+
+The grounded PoC kept the real worker and timeout/reset carrier:
+
+ vub300_cmndwork_thread()
+ __vub300_command_response()
+ usb_lock_device_for_reset()
+ usb_reset_device()
+ vub300_pre_reset()
+
+Lockdep reported the same-task recursive acquisition on cmd_mutex:
+
+ WARNING: possible recursive locking detected
+ ... (&test_vub300.cmd_mutex) ... at: usb_reset_device... [vuln_msv]
+ ... (&test_vub300.cmd_mutex) ... at: vub300_cmndwork_thread+0x12/0x20 [vuln_msv]
+ Workqueue: vub300_cmd_wq vub300_cmndwork_thread [vuln_msv]
+ *** DEADLOCK ***
+
+Return a flag from __vub300_command_response() when the timeout path needs
+a device reset, then perform the reset after vub300_cmndwork_thread() has
+cleared the in-flight command state and dropped cmd_mutex. The reset is
+still attempted before mmc_request_done(), preserving the existing request
+completion ordering while avoiding the recursive lock.
+
+Fixes: 88095e7b473a ("mmc: Add new VUB300 USB-to-SD/SDIO/MMC driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Signed-off-by: Ulf Hansson <ulfh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/vub300.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+--- a/drivers/mmc/host/vub300.c
++++ b/drivers/mmc/host/vub300.c
+@@ -1586,7 +1586,7 @@ static int __command_write_data(struct v
+ return linear_length;
+ }
+
+-static void __vub300_command_response(struct vub300_mmc_host *vub300,
++static bool __vub300_command_response(struct vub300_mmc_host *vub300,
+ struct mmc_command *cmd,
+ struct mmc_data *data, int data_length)
+ {
+@@ -1598,17 +1598,11 @@ static void __vub300_command_response(st
+ msecs_to_jiffies(msec_timeout));
+ if (respretval == 0) { /* TIMED OUT */
+ /* we don't know which of "out" and "res" if any failed */
+- int result;
+ vub300->usb_timed_out = 1;
+ usb_kill_urb(vub300->command_out_urb);
+ usb_kill_urb(vub300->command_res_urb);
+ cmd->error = -ETIMEDOUT;
+- result = usb_lock_device_for_reset(vub300->udev,
+- vub300->interface);
+- if (result == 0) {
+- result = usb_reset_device(vub300->udev);
+- usb_unlock_device(vub300->udev);
+- }
++ return true;
+ } else if (respretval < 0) {
+ /* we don't know which of "out" and "res" if any failed */
+ usb_kill_urb(vub300->command_out_urb);
+@@ -1704,6 +1698,8 @@ static void __vub300_command_response(st
+ } else {
+ cmd->error = -EINVAL;
+ }
++
++ return false;
+ }
+
+ static void construct_request_response(struct vub300_mmc_host *vub300,
+@@ -1749,6 +1745,7 @@ static void vub300_cmndwork_thread(struc
+ struct mmc_request *req = vub300->req;
+ struct mmc_command *cmd = vub300->cmd;
+ struct mmc_data *data = vub300->data;
++ bool reset_device;
+ int data_length;
+ mutex_lock(&vub300->cmd_mutex);
+ init_completion(&vub300->command_complete);
+@@ -1771,7 +1768,8 @@ static void vub300_cmndwork_thread(struc
+ data_length = __command_read_data(vub300, cmd, data);
+ else
+ data_length = __command_write_data(vub300, cmd, data);
+- __vub300_command_response(vub300, cmd, data, data_length);
++ reset_device = __vub300_command_response(vub300, cmd,
++ data, data_length);
+ vub300->req = NULL;
+ vub300->cmd = NULL;
+ vub300->data = NULL;
+@@ -1779,6 +1777,16 @@ static void vub300_cmndwork_thread(struc
+ if (cmd->error == -ENOMEDIUM)
+ check_vub300_port_status(vub300);
+ mutex_unlock(&vub300->cmd_mutex);
++ if (reset_device) {
++ int result;
++
++ result = usb_lock_device_for_reset(vub300->udev,
++ vub300->interface);
++ if (result == 0) {
++ result = usb_reset_device(vub300->udev);
++ usb_unlock_device(vub300->udev);
++ }
++ }
+ mmc_request_done(vub300->mmc, req);
+ kref_put(&vub300->kref, vub300_delete);
+ return;
--- /dev/null
+From d322e40f4edf92bf0ca329e5aa4ae1c0316feb38 Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Fri, 3 Jul 2026 15:40:52 +0800
+Subject: mtd: mchp23k256: use SPI match data for chip caps
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit d322e40f4edf92bf0ca329e5aa4ae1c0316feb38 upstream.
+
+The driver stores chip capacity information in both the OF match table
+and the SPI id table. Probe currently uses of_device_get_match_data(),
+so a non-OF SPI modalias match falls back to mchp23k256_caps even when
+the SPI id table selected a different part.
+
+Use spi_get_device_match_data() so SPI id-table driver_data is consumed
+when OF match data is absent. This keeps the existing default fallback
+while avoiding the wrong MTD geometry for id-table-only matches.
+
+Fixes: 4379075a870b ("mtd: mchp23k256: Add support for mchp23lcv1024")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/devices/mchp23k256.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/devices/mchp23k256.c
++++ b/drivers/mtd/devices/mchp23k256.c
+@@ -188,7 +188,7 @@ static int mchp23k256_probe(struct spi_d
+
+ data = dev_get_platdata(&spi->dev);
+
+- flash->caps = of_device_get_match_data(&spi->dev);
++ flash->caps = spi_get_device_match_data(spi);
+ if (!flash->caps)
+ flash->caps = &mchp23k256_caps;
+
--- /dev/null
+From d03a19bd6c7f86b99ca8fb61a6ec2345cee1d9d6 Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Fri, 3 Jul 2026 15:43:50 +0800
+Subject: mtd: onenand: samsung: report DMA completion timeouts
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit d03a19bd6c7f86b99ca8fb61a6ec2345cee1d9d6 upstream.
+
+The S5PC110 OneNAND DMA helpers have bounded waits for transfer
+completion. The polling helper falls out of its timeout loop and returns
+success, and the IRQ helper ignores wait_for_completion_timeout().
+
+Return -ETIMEDOUT when the DMA transfer-done bit or completion does not
+arrive before the timeout so callers can treat the buffer transfer as
+failed.
+
+Fixes: e23abf4b7743 ("mtd: OneNAND: S5PC110: Implement DMA interrupt method")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/nand/onenand/onenand_samsung.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/onenand/onenand_samsung.c
++++ b/drivers/mtd/nand/onenand/onenand_samsung.c
+@@ -554,6 +554,9 @@ static int s5pc110_dma_poll(dma_addr_t d
+ } while (!(status & S5PC110_DMA_TRANS_STATUS_TD) &&
+ time_before(jiffies, timeout));
+
++ if (!(status & S5PC110_DMA_TRANS_STATUS_TD))
++ return -ETIMEDOUT;
++
+ writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD);
+
+ return 0;
+@@ -608,7 +611,9 @@ static int s5pc110_dma_irq(dma_addr_t ds
+
+ writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD);
+
+- wait_for_completion_timeout(&onenand->complete, msecs_to_jiffies(20));
++ if (!wait_for_completion_timeout(&onenand->complete,
++ msecs_to_jiffies(20)))
++ return -ETIMEDOUT;
+
+ return 0;
+ }
--- /dev/null
+From f9a13e05a327080c3a1c8165adf9e678fb68fef2 Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Fri, 3 Jul 2026 15:42:33 +0800
+Subject: mtd: rawnand: fsl_ifc: return errors for failed page reads
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit f9a13e05a327080c3a1c8165adf9e678fb68fef2 upstream.
+
+fsl_ifc_run_command() logs controller timeout and other non-OPC
+completion states in ctrl->nand_stat. fsl_ifc_read_page() then only
+increments the ECC failure counter for non-OPC status and still returns
+max_bitflips, which can be zero.
+
+Return -ETIMEDOUT when the command did not complete at all and -EIO for
+other non-OPC read completions so the NAND core does not treat a failed
+page read as a clean page.
+
+Fixes: 82771882d960 ("NAND Machine support for Integrated Flash Controller")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/nand/raw/fsl_ifc_nand.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
++++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
+@@ -684,8 +684,15 @@ static int fsl_ifc_read_page(struct nand
+ return check_erased_page(chip, buf);
+ }
+
+- if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
++ if (!ctrl->nand_stat) {
+ mtd->ecc_stats.failed++;
++ return -ETIMEDOUT;
++ }
++
++ if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) {
++ mtd->ecc_stats.failed++;
++ return -EIO;
++ }
+
+ return nctrl->max_bitflips;
+ }
--- /dev/null
+From dbf590b662695b16fbf5917ef129697be4410ea9 Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Fri, 3 Jul 2026 15:37:59 +0800
+Subject: mtd: rawnand: lpc32xx_mlc: fail DMA transfers on timeout
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit dbf590b662695b16fbf5917ef129697be4410ea9 upstream.
+
+lpc32xx_xmit_dma() starts a DMA transfer and waits up to one second
+for its completion, but it ignores the wait result and returns success
+after unmapping the buffer.
+
+A timed out read can therefore return success with incomplete data, and
+a timed out write can continue the NAND operation without proof that the
+DMA payload reached the controller.
+
+Terminate the DMA channel on timeout, unmap the scatterlist through the
+existing cleanup path, and return -ETIMEDOUT to the NAND read/write
+callers. Initialize the shared cleanup-path result before using it for
+dmaengine_prep_slave_sg() failures.
+
+Fixes: 70f7cb78ec53 ("mtd: add LPC32xx MLC NAND driver")
+Cc: stable@vger.kernel.org
+Reviewed-by: Vladimir Zapolskiy <vz@kernel.org>
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/nand/raw/lpc32xx_mlc.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/mtd/nand/raw/lpc32xx_mlc.c
++++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c
+@@ -396,6 +396,7 @@ static int lpc32xx_xmit_dma(struct mtd_i
+ struct lpc32xx_nand_host *host = nand_get_controller_data(chip);
+ struct dma_async_tx_descriptor *desc;
+ int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
++ unsigned long time_left;
+ int res;
+
+ sg_init_one(&host->sgl, mem, len);
+@@ -410,6 +411,7 @@ static int lpc32xx_xmit_dma(struct mtd_i
+ flags);
+ if (!desc) {
+ dev_err(mtd->dev.parent, "Failed to prepare slave sg\n");
++ res = -ENXIO;
+ goto out1;
+ }
+
+@@ -420,7 +422,13 @@ static int lpc32xx_xmit_dma(struct mtd_i
+ dmaengine_submit(desc);
+ dma_async_issue_pending(host->dma_chan);
+
+- wait_for_completion_timeout(&host->comp_dma, msecs_to_jiffies(1000));
++ time_left = wait_for_completion_timeout(&host->comp_dma,
++ msecs_to_jiffies(1000));
++ if (!time_left) {
++ dmaengine_terminate_sync(host->dma_chan);
++ res = -ETIMEDOUT;
++ goto out1;
++ }
+
+ dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
+@@ -428,7 +436,7 @@ static int lpc32xx_xmit_dma(struct mtd_i
+ out1:
+ dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
+- return -ENXIO;
++ return res;
+ }
+
+ static int lpc32xx_read_page(struct nand_chip *chip, uint8_t *buf,
--- /dev/null
+From 17a8ce84964f243c8f89dc7353ac7e8d3137bc74 Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Fri, 3 Jul 2026 15:39:43 +0800
+Subject: mtd: rawnand: lpc32xx_slc: fail DMA transfer on completion timeout
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit 17a8ce84964f243c8f89dc7353ac7e8d3137bc74 upstream.
+
+lpc32xx_xmit_dma() waits for the DMA completion callback but ignores
+wait_for_completion_timeout(). A timed out DMA transfer is therefore
+unmapped and reported as successful to the NAND read/write path.
+
+Return -ETIMEDOUT when the completion wait expires. Terminate the DMA
+channel before unmapping the scatterlist so the timed out transfer cannot
+continue to access the buffer after the error is returned.
+
+Fixes: 2944a44da09e ("mtd: add LPC32xx SLC NAND driver")
+Cc: stable@vger.kernel.org
+Reviewed-by: Vladimir Zapolskiy <vz@kernel.org>
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/nand/raw/lpc32xx_slc.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/mtd/nand/raw/lpc32xx_slc.c
++++ b/drivers/mtd/nand/raw/lpc32xx_slc.c
+@@ -430,6 +430,7 @@ static int lpc32xx_xmit_dma(struct mtd_i
+ struct dma_async_tx_descriptor *desc;
+ int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
+ int res;
++ unsigned long time_left;
+
+ host->dma_slave_config.direction = dir;
+ host->dma_slave_config.src_addr = dma;
+@@ -467,12 +468,19 @@ static int lpc32xx_xmit_dma(struct mtd_i
+ dmaengine_submit(desc);
+ dma_async_issue_pending(host->dma_chan);
+
+- wait_for_completion_timeout(&host->comp, msecs_to_jiffies(1000));
++ time_left = wait_for_completion_timeout(&host->comp,
++ msecs_to_jiffies(1000));
++ if (!time_left) {
++ dmaengine_terminate_sync(host->dma_chan);
++ res = -ETIMEDOUT;
++ } else {
++ res = 0;
++ }
+
+ dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
+
+- return 0;
++ return res;
+ out1:
+ dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
--- /dev/null
+From caa0ecbeff4f7fbf70f22bd8ca598918bffb1b78 Mon Sep 17 00:00:00 2001
+From: Xu Rao <raoxu@uniontech.com>
+Date: Fri, 26 Jun 2026 10:13:38 +0800
+Subject: mtd: virt-concat: free duplicate generated name
+
+From: Xu Rao <raoxu@uniontech.com>
+
+commit caa0ecbeff4f7fbf70f22bd8ca598918bffb1b78 upstream.
+
+Every MTD registration runs mtd_virt_concat_create_join(). Once a
+virtual concat has already been registered, the function builds the same
+name again and takes the equal-name branch. That branch skips to the
+next item without freeing the newly allocated string.
+
+Free the temporary name before continuing.
+
+Fixes: 43db6366fc2d ("mtd: Add driver for concatenating devices")
+Cc: stable@vger.kernel.org
+Signed-off-by: Xu Rao <raoxu@uniontech.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/mtd_virt_concat.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtd_virt_concat.c b/drivers/mtd/mtd_virt_concat.c
+index c872a8827718..da4277ced4d6 100644
+--- a/drivers/mtd/mtd_virt_concat.c
++++ b/drivers/mtd/mtd_virt_concat.c
+@@ -321,8 +321,10 @@ int mtd_virt_concat_create_join(void)
+
+ if (concat->mtd.name) {
+ ret = memcmp(concat->mtd.name, name, name_sz);
+- if (ret == 0)
++ if (ret == 0) {
++ kfree(name);
+ continue;
++ }
+ }
+ mtd = mtd_concat_create(concat->subdev, concat->num_subdev, name);
+ if (!mtd) {
+--
+2.55.0
+
--- /dev/null
+From 47b87f469a35b5ffc81c16eee6b13a9b6c8d55c6 Mon Sep 17 00:00:00 2001
+From: Junrui Luo <moonafterrain@outlook.com>
+Date: Mon, 1 Jun 2026 15:50:00 +0800
+Subject: powerpc/spufs: fix out-of-bounds access in spufs_mem_mmap_access()
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+commit 47b87f469a35b5ffc81c16eee6b13a9b6c8d55c6 upstream.
+
+spufs_mem_mmap_access() computes the local store offset as
+address - vma->vm_start, but bounds-checks it against vma->vm_end
+instead of the local store size. On 64-bit, offset is always well
+below vma->vm_end, so the clamp never fires and len stays unbounded
+against the LS_SIZE buffer returned by ctx->ops->get_ls().
+
+Reject offsets at or beyond LS_SIZE and clamp len to the remaining
+space, mirroring the guard already used by spufs_mem_mmap_fault() and
+spufs_ps_fault().
+
+Fixes: a352894d0705 ("spufs: use new vm_ops->access to allow local state access from gdb")
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/SYBPR01MB7881EE775E8B51C09F5A29E7AF152@SYBPR01MB7881.ausprd01.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/platforms/cell/spufs/file.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/platforms/cell/spufs/file.c
++++ b/arch/powerpc/platforms/cell/spufs/file.c
+@@ -268,10 +268,12 @@ static int spufs_mem_mmap_access(struct
+
+ if (write && !(vma->vm_flags & VM_WRITE))
+ return -EACCES;
++ if (offset >= LS_SIZE)
++ return -EFAULT;
+ if (spu_acquire(ctx))
+ return -EINTR;
+- if ((offset + len) > vma->vm_end)
+- len = vma->vm_end - offset;
++ if ((offset + len) > LS_SIZE)
++ len = LS_SIZE - offset;
+ local_store = ctx->ops->get_ls(ctx);
+ if (write)
+ memcpy_toio(local_store + offset, buf, len);
--- /dev/null
+From d610d3ab18197d87618da11ec5fe8b3cebf32208 Mon Sep 17 00:00:00 2001
+From: Ethan Nelson-Moore <enelsonmoore@gmail.com>
+Date: Mon, 15 Jun 2026 16:37:26 -0700
+Subject: powerpc/uaccess: correct check for CONFIG_PPC_E500 in mask_user_address()
+
+From: Ethan Nelson-Moore <enelsonmoore@gmail.com>
+
+commit d610d3ab18197d87618da11ec5fe8b3cebf32208 upstream.
+
+mask_user_address() incorrectly checks for CONFIG_E500 instead of
+CONFIG_PPC_E500, causing mask_user_address_isel() to not be used on
+E500 hardware. Fix the check to use the correct name.
+
+Fixes: 861574d51bbd ("powerpc/uaccess: Implement masked user access")
+Cc: stable@vger.kernel.org # 7.0+
+Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
+Fixes: 861574d51bbd ("powerpc/uaccess: Implement masked user access")
+Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260615233729.29386-1-enelsonmoore@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/uaccess.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/include/asm/uaccess.h
++++ b/arch/powerpc/include/asm/uaccess.h
+@@ -511,7 +511,7 @@ static inline void __user *mask_user_add
+
+ if (IS_ENABLED(CONFIG_PPC64))
+ return mask_user_address_simple(ptr);
+- if (IS_ENABLED(CONFIG_E500))
++ if (IS_ENABLED(CONFIG_PPC_E500))
+ return mask_user_address_isel(ptr);
+ if (TASK_SIZE <= UL(SZ_2G) && border >= UL(SZ_2G))
+ return mask_user_address_simple(ptr);
ipvs-reload-ip-header-after-head-reallocation.patch
reset-imx7-correct-polarity-of-mipi-csi-resets-on-i.mx8mq.patch
reset-sunxi-fix-memory-region-leak-on-ioremap-failure.patch
+powerpc-spufs-fix-out-of-bounds-access-in-spufs_mem_mmap_access.patch
+powerpc-uaccess-correct-check-for-config_ppc_e500-in-mask_user_address.patch
+wifi-cfg80211-validate-eht-mle-before-mld-id-read.patch
+wifi-ieee80211-validate-mle-common-info-length.patch
+wifi-mac80211-free-ack-status-frame-on-tx-header-build-failure.patch
+wifi-mac80211-validate-extension-frame-layout-before-rx.patch
+wifi-mwifiex-fix-permanently-busy-scans-after-multiple-roam-iterations.patch
+mtd-virt-concat-free-duplicate-generated-name.patch
+mtd-onenand-samsung-report-dma-completion-timeouts.patch
+mtd-mchp23k256-use-spi-match-data-for-chip-caps.patch
+mmc-vub300-defer-reset-until-cmd_mutex-is-unlocked.patch
+mtd-rawnand-fsl_ifc-return-errors-for-failed-page-reads.patch
+mtd-rawnand-lpc32xx_mlc-fail-dma-transfers-on-timeout.patch
+mtd-rawnand-lpc32xx_slc-fail-dma-transfer-on-completion-timeout.patch
+mmc-block-fix-rpmb-device-unregister-ordering.patch
+mmc-mmc_test-fix-__counted_by-handling-after-kzalloc_flex-conversion.patch
+mmc-sdhci-of-dwcmshc-check-bus-clock-enable-result-in-the-probe-method.patch
+mmc-sdhci-esdhc-imx-remove-unnecessary-mmc_card_wake_sdio_irq-check-for-tuning-save-restore.patch
+mmc-sdhci-esdhc-imx-restore-dll-override-for-ddr-modes-on-resume.patch
+mmc-sdhci-esdhc-imx-fix-esdhc_change_pinstate-to-allow-default-state-restore.patch
+mmc-sdhci-esdhc-imx-disable-irq-during-suspend-to-fix-unhandled-interrupt.patch
+mmc-sdhci-esdhc-imx-use-pm_runtime_resume_and_get-in-suspend.patch
+mmc-sdhci-esdhc-imx-make-non-fatal-errors-non-blocking-in-suspend.patch
+mmc-sdhci-esdhc-imx-fix-resume-error-handling.patch
--- /dev/null
+From 74e27cd1d98b546fdb276008a83708d062339661 Mon Sep 17 00:00:00 2001
+From: Haofeng Li <lihaofeng@kylinos.cn>
+Date: Wed, 1 Jul 2026 17:33:27 +0800
+Subject: wifi: cfg80211: validate EHT MLE before MLD ID read
+
+From: Haofeng Li <lihaofeng@kylinos.cn>
+
+commit 74e27cd1d98b546fdb276008a83708d062339661 upstream.
+
+cfg80211_gen_new_ie() copies ML probe response elements from
+the parent frame when the parent EHT multi-link element has an
+MLD ID matching the nontransmitted BSSID index.
+
+The code only checked that the extension element had more than
+one byte before calling ieee80211_mle_get_mld_id(). That helper
+assumes a BASIC MLE with enough common info and documents that
+callers must first use ieee80211_mle_type_ok().
+
+Attack chain:
+malicious AP sends a short EHT MLE in an MBSSID beacon.
+cfg80211_inform_bss_frame_data() stores the copied IE buffer.
+cfg80211_parse_mbssid_data() builds the nontransmitted BSS IE.
+cfg80211_gen_new_ie() sees the EHT MLE in the parent frame.
+ieee80211_mle_get_mld_id() then reads past the IE boundary.
+
+Validate the MLE type and size before reading the MLD ID. This
+matches the contract required by the MLE helper and rejects the
+short element before any internal MLE fields are accessed.
+
+Cc: stable@vger.kernel.org
+Fixes: 61dcfa8c2a8f ("wifi: cfg80211: copy multi-link element from the multi-link probe request's frame body to the generated elements")
+Signed-off-by: Haofeng Li <lihaofeng@kylinos.cn>
+Link: https://patch.msgid.link/20260701093327.2680709-1-lihaofeng@kylinos.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/wireless/scan.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -326,8 +326,11 @@ cfg80211_gen_new_ie(const u8 *ie, size_t
+ /* For ML probe response, match the MLE in the frame body with
+ * MLD id being 'bssid_index'
+ */
+- if (parent->id == WLAN_EID_EXTENSION && parent->datalen > 1 &&
++ if (parent->id == WLAN_EID_EXTENSION &&
+ parent->data[0] == WLAN_EID_EXT_EHT_MULTI_LINK &&
++ ieee80211_mle_type_ok(parent->data + 1,
++ IEEE80211_ML_CONTROL_TYPE_BASIC,
++ parent->datalen - 1) &&
+ bssid_index == ieee80211_mle_get_mld_id(parent->data + 1)) {
+ if (!cfg80211_copy_elem_with_frags(parent,
+ ie, ielen,
--- /dev/null
+From 293baeae9b2434a3e432629d7720b5603db2d77e Mon Sep 17 00:00:00 2001
+From: Zhao Li <enderaoelyther@gmail.com>
+Date: Fri, 12 Jun 2026 01:35:07 +0800
+Subject: wifi: ieee80211: validate MLE common info length
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+commit 293baeae9b2434a3e432629d7720b5603db2d77e upstream.
+
+ieee80211_mle_common_size() uses the first common-info octet as the
+common information length for all known MLE types. However,
+ieee80211_mle_size_ok() only validates that octet for Basic, Probe
+Request, and TDLS MLEs.
+
+Reconfiguration MLEs also skipped the length octet when calculating the
+minimum common size, and Priority Access MLEs skipped validation of the
+advertised common information length.
+
+Account for the Reconfiguration common-info length octet and validate
+the advertised common information length for all known MLE types. Keep
+unknown-type handling unchanged.
+
+Fixes: 0f48b8b88aa9 ("wifi: ieee80211: add definitions for multi-link element")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260611173506.36838-2-enderaoelyther@gmail.com
+[remove now misleading comment]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/ieee80211-eht.h | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+--- a/include/linux/ieee80211-eht.h
++++ b/include/linux/ieee80211-eht.h
+@@ -844,7 +844,7 @@ static inline bool ieee80211_mle_size_ok
+ const struct ieee80211_multi_link_elem *mle = (const void *)data;
+ u8 fixed = sizeof(*mle);
+ u8 common = 0;
+- bool check_common_len = false;
++ u8 common_len;
+ u16 control;
+
+ if (!data || len < fixed)
+@@ -855,7 +855,6 @@ static inline bool ieee80211_mle_size_ok
+ switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) {
+ case IEEE80211_ML_CONTROL_TYPE_BASIC:
+ common += sizeof(struct ieee80211_mle_basic_common_info);
+- check_common_len = true;
+ if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID)
+ common += 1;
+ if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)
+@@ -875,9 +874,9 @@ static inline bool ieee80211_mle_size_ok
+ common += sizeof(struct ieee80211_mle_preq_common_info);
+ if (control & IEEE80211_MLC_PREQ_PRES_MLD_ID)
+ common += 1;
+- check_common_len = true;
+ break;
+ case IEEE80211_ML_CONTROL_TYPE_RECONF:
++ common += 1;
+ if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR)
+ common += ETH_ALEN;
+ if (control & IEEE80211_MLC_RECONF_PRES_EML_CAPA)
+@@ -889,7 +888,6 @@ static inline bool ieee80211_mle_size_ok
+ break;
+ case IEEE80211_ML_CONTROL_TYPE_TDLS:
+ common += sizeof(struct ieee80211_mle_tdls_common_info);
+- check_common_len = true;
+ break;
+ case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS:
+ common = ETH_ALEN + 1;
+@@ -902,11 +900,9 @@ static inline bool ieee80211_mle_size_ok
+ if (len < fixed + common)
+ return false;
+
+- if (!check_common_len)
+- return true;
++ common_len = mle->variable[0];
+
+- /* if present, common length is the first octet there */
+- return mle->variable[0] >= common;
++ return common_len >= common && common_len <= len - fixed;
+ }
+
+ /**
--- /dev/null
+From 2c51457d930f723e5f2903af90f5847f7df53f42 Mon Sep 17 00:00:00 2001
+From: Zhiling Zou <roxy520tt@gmail.com>
+Date: Sat, 27 Jun 2026 00:58:30 +0800
+Subject: wifi: mac80211: free ack status frame on TX header build failure
+
+From: Zhiling Zou <roxy520tt@gmail.com>
+
+commit 2c51457d930f723e5f2903af90f5847f7df53f42 upstream.
+
+ieee80211_build_hdr() stores an ACK status frame before it has
+finished all validation and header construction. If a later error path
+is taken, the transmit skb is freed but the stored ACK status frame
+remains in local->ack_status_frames.
+
+This can happen for control port frames when the requested MLO link ID
+does not match the link selected for a non-MLO station. Repeated
+failures can fill the ACK status IDR and leave pending ACK frames until
+hardware teardown.
+
+Remove any stored ACK status frame before returning an error after it
+has been inserted into the IDR.
+
+Fixes: a729cff8ad51 ("mac80211: implement wifi TX status")
+Cc: stable@vger.kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Assisted-by: Codex:gpt-5.4
+Signed-off-by: Zhiling Zou <roxy520tt@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Link: https://patch.msgid.link/9de0423da840e92084915b8f92e66a421245c4b8.1782462409.git.roxy520tt@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/tx.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -2597,6 +2597,18 @@ static u16 ieee80211_store_ack_skb(struc
+ return info_id;
+ }
+
++static void ieee80211_remove_ack_skb(struct ieee80211_local *local, u16 info_id)
++{
++ struct sk_buff *ack_skb;
++ unsigned long flags;
++
++ spin_lock_irqsave(&local->ack_status_lock, flags);
++ ack_skb = idr_remove(&local->ack_status_frames, info_id);
++ spin_unlock_irqrestore(&local->ack_status_lock, flags);
++
++ kfree_skb(ack_skb);
++}
++
+ /**
+ * ieee80211_build_hdr - build 802.11 header in the given frame
+ * @sdata: virtual interface to build the header for
+@@ -2972,7 +2984,8 @@ static struct sk_buff *ieee80211_build_h
+ if (ieee80211_skb_resize(sdata, skb, head_need, ENCRYPT_DATA)) {
+ ieee80211_free_txskb(&local->hw, skb);
+ skb = NULL;
+- return ERR_PTR(-ENOMEM);
++ ret = -ENOMEM;
++ goto free;
+ }
+ }
+
+@@ -3040,6 +3053,8 @@ static struct sk_buff *ieee80211_build_h
+
+ return skb;
+ free:
++ if (info_id)
++ ieee80211_remove_ack_skb(local, info_id);
+ kfree_skb(skb);
+ return ERR_PTR(ret);
+ }
--- /dev/null
+From 57d503ce32eccfa7650065ca4c560f7e29a2e676 Mon Sep 17 00:00:00 2001
+From: Zhao Li <enderaoelyther@gmail.com>
+Date: Fri, 12 Jun 2026 00:19:45 +0800
+Subject: wifi: mac80211: validate extension-frame layout before RX
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+commit 57d503ce32eccfa7650065ca4c560f7e29a2e676 upstream.
+
+Extension frames only have the extension header at the regular 802.11
+header offset. The generic RX path can still reach helpers and interface
+dispatch code that read regular header address fields before unsupported
+extension subtypes are dropped.
+
+mac80211 currently only handles S1G beacon extension frames. Drop other
+extension subtypes before they can reach regular-header RX processing.
+For S1G beacons, linearize the SKB with the management-frame path and
+require the fixed S1G beacon header, including optional fixed fields
+indicated by frame control, before generic RX dispatch.
+
+Route S1G beacons through the station/default-link RX path without
+regular-header station lookup. Avoid regular-header address reads in the
+mac80211 RX paths that process S1G extension beacons, including
+accept-frame, duplicate-detection, address-copy, and MLO
+address-translation paths.
+
+Also make ieee80211_get_bssid() length-safe before returning the S1G
+source-address pointer.
+
+Fixes: 09a740ce352e ("mac80211: receive and process S1G beacons")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260611161943.91069-5-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/rx.c | 34 ++++++++++++++++++++++++++++++++--
+ net/mac80211/util.c | 3 +++
+ 2 files changed, 35 insertions(+), 2 deletions(-)
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -1526,6 +1526,9 @@ ieee80211_rx_h_check_dup(struct ieee8021
+ if (status->flag & RX_FLAG_DUP_VALIDATED)
+ return RX_CONTINUE;
+
++ if (ieee80211_is_ext(hdr->frame_control))
++ return RX_CONTINUE;
++
+ /*
+ * Drop duplicate 802.11 retransmissions
+ * (IEEE 802.11-2012: 9.3.2.10 "Duplicate detection and recovery")
+@@ -4487,12 +4490,16 @@ static bool ieee80211_accept_frame(struc
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
+- bool multicast = is_multicast_ether_addr(hdr->addr1) ||
+- ieee80211_is_s1g_beacon(hdr->frame_control);
++ bool multicast;
+ static const u8 nan_network_id[ETH_ALEN] __aligned(2) = {
+ 0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00
+ };
+
++ if (ieee80211_is_s1g_beacon(hdr->frame_control))
++ return sdata->vif.type == NL80211_IFTYPE_STATION && bssid;
++
++ multicast = is_multicast_ether_addr(hdr->addr1);
++
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+ if (!bssid && !sdata->u.mgd.use_4addr)
+@@ -5174,6 +5181,11 @@ static bool ieee80211_prepare_and_rx_han
+ hdr = (struct ieee80211_hdr *)rx->skb->data;
+ }
+
++ if (ieee80211_is_s1g_beacon(hdr->frame_control)) {
++ ieee80211_invoke_rx_handlers(rx);
++ return true;
++ }
++
+ /* Store a copy of the pre-translated link addresses for SW crypto */
+ if (unlikely(is_unicast_ether_addr(hdr->addr1) &&
+ !ieee80211_is_data(hdr->frame_control)))
+@@ -5263,6 +5275,13 @@ static bool ieee80211_rx_for_interface(s
+ struct sta_info *sta;
+ int link_id = -1;
+
++ if (ieee80211_is_s1g_beacon(hdr->frame_control)) {
++ if (!ieee80211_rx_data_set_sta(rx, NULL, -1))
++ return false;
++
++ return ieee80211_prepare_and_rx_handle(rx, skb, consume);
++ }
++
+ /*
+ * Look up link station first, in case there's a
+ * chance that they might have a link address that
+@@ -5338,6 +5357,17 @@ static void __ieee80211_rx_handle_packet
+ err = -ENOBUFS;
+ else
+ err = skb_linearize(skb);
++ } else if (ieee80211_is_s1g_beacon(fc)) {
++ size_t s1g_hdr_len = offsetof(struct ieee80211_ext,
++ u.s1g_beacon.variable) +
++ ieee80211_s1g_optional_len(fc);
++
++ if (skb->len < s1g_hdr_len)
++ err = -ENOBUFS;
++ else
++ err = skb_linearize(skb);
++ } else if (ieee80211_is_ext(fc)) {
++ err = -EINVAL;
+ } else {
+ err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
+ }
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -73,6 +73,9 @@ u8 *ieee80211_get_bssid(struct ieee80211
+ if (ieee80211_is_s1g_beacon(fc)) {
+ struct ieee80211_ext *ext = (void *) hdr;
+
++ if (len < offsetofend(struct ieee80211_ext, u.s1g_beacon.sa))
++ return NULL;
++
+ return ext->u.s1g_beacon.sa;
+ }
+
--- /dev/null
+From d78a407bad6f500884a8606aea1a5a9207be4030 Mon Sep 17 00:00:00 2001
+From: Rafael Beims <rafael.beims@toradex.com>
+Date: Fri, 12 Jun 2026 09:25:46 -0300
+Subject: wifi: mwifiex: fix permanently busy scans after multiple roam iterations
+
+From: Rafael Beims <rafael.beims@toradex.com>
+
+commit d78a407bad6f500884a8606aea1a5a9207be4030 upstream.
+
+In order for the firmware to sleep, the driver has to confirm a
+previously received sleep request. The normal sequence of evets goes
+like this:
+EVENT_SLEEP -> adapter->ps_state = PS_STATE_PRE_SLEEP -> sleep-confirm
+-> SLEEP -> EVENT_AWAKE -> AWAKE.
+Before sending the sleep-confirm command, the driver must make sure
+there are no commands either running or waiting to be completed.
+
+mwifiex_ret_802_11_associate() unconditionally sets
+ps_state = PS_STATE_AWAKE when it processes the association command
+response, outside of the normal powersave management flow. If
+EVENT_SLEEP arrives while the association command is in flight,
+ps_state is PRE_SLEEP when the association command response is parsed,
+and the forced AWAKE overwrites it. The deferred sleep-confirm is
+never sent.
+
+A subsequent scan_start command is correctly acknowledged, but the
+firmware doesn't generate scan_result events. The scan request never
+finishes, and additional requests from userspace fail with -EBUSY.
+
+After testing on both IW412 and W8997, I could only trigger the bug on
+the IW412 and observed the firmwares behave differently. On the IW412
+the firmware still sends EVENT_SLEEP while the authentication /
+association process is ongoing. A W8997 under the same
+conditions seems to suppress power-save for the duration of the
+association, so PRE_SLEEP never coincided with the association response
+even after extended periods of testing using the loops
+described below (>12hours).
+
+On the IW412, the delay between commands that triggers an EVENT_SLEEP
+was empirically determined to be ~20ms. This delay can naturally occur
+when the driver is outputting debugging information
+(debug_mask = 0x00000037), in which situation the busy scans issue is
+repeatable while running "test 1)" as described below. If the delay
+between commands is less than ~20ms, the firmware stays awake and
+the issue was not reproducible running the same test.
+
+The host_mlme=false path also behaves differently. In this case, the
+entire authentication / association transaction is executed by one
+command (HostCmd_CMD_802_11_ASSOCIATE), and the firmware doesn't emit
+EVENT_SLEEP while the command is running.
+
+Remove the assignment so the ps_state is only manipulated in the paths
+that are related to powersave event handling and on the main workqueue
+for correct sleep confirmation.
+
+The following loop tests were performed (with debugging output enabled):
+1) force roaming between two AP's, one 5GHz and one 2.4GHz, same
+SSID. Use wpa_cli to trigger the roaming behavior, sleep 2s
+between iterations.
+2) force a disconnection to AP 1 and a connection to AP 2, test
+scan. Use wpa_cli to trigger the connection changes, sleep 2s
+between iterations.
+
+Each test ran in each device for at least 3 hours.
+
+Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Rafael Beims <rafael.beims@toradex.com>
+Reviewed-by: Jeff Chen <jeff.chen_1@nxp.com>
+Link: https://patch.msgid.link/20260612122547.1586872-2-rafael@beims.me
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/marvell/mwifiex/join.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/wireless/marvell/mwifiex/join.c
++++ b/drivers/net/wireless/marvell/mwifiex/join.c
+@@ -736,7 +736,6 @@ int mwifiex_ret_802_11_associate(struct
+ /* Send a Media Connected event, according to the Spec */
+ priv->media_connected = true;
+
+- priv->adapter->ps_state = PS_STATE_AWAKE;
+ priv->adapter->pps_uapsd_mode = false;
+ priv->adapter->tx_lock_flag = false;
+