[PATCH AUTOSEL 6.16 58/85] mmc: sdhci-esdhc-imx: Don't change pinctrl in suspend if wakeup source

Sasha Levin sashal at kernel.org
Sun Aug 3 17:23:07 PDT 2025


From: Haibo Chen <haibo.chen at nxp.com>

[ Upstream commit 031d9e30d569ca15ca32f64357c83eee6488e09d ]

The pinctrl sleep state may config the pin mux to certain function to save
power in system suspend. Unfortunately this doesn't work if usdhc is used
as a wakeup source, like waking up on SDIO irqs or card-detect irqs. In
these cases, we need pin mux to be configured to usdhc function pad.

The issue is found on imx93-11x11-evk board, where WiFI over SDIO with
in-band irqs fails to wakeup the system, because the DATA[1] pin has been
set to GPIO function.

To fix the problem, don't change the pinctrl state in suspend if there is a
system wakeup enabled.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
Signed-off-by: Luke Wang <ziniu.wang_1 at nxp.com>
Link: https://lore.kernel.org/r/20250521033134.112671-1-ziniu.wang_1@nxp.com
Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---

LLM Generated explanations, may be completely bogus:

**Backport Status: YES**

This commit should be backported to stable kernel trees for the
following reasons:

1. **Fixes a real user-impacting bug**: The commit fixes a regression
   where SDIO WiFi devices fail to wake up the system from suspend. This
   is a functional regression that directly impacts users' ability to
   use WiFi wake-on-WLAN functionality on i.MX platforms.

2. **Small and contained fix**: The change is minimal - it simply moves
   the `pinctrl_pm_select_sleep_state()` call inside the else block of
   the wakeup check. The logic change is:
   - Before: Always switch to sleep pinctrl state during suspend
   - After: Only switch to sleep pinctrl state if the device is NOT a
     wakeup source

3. **Low risk of regression**: The fix is conservative and only affects
   the suspend path when the device is configured as a wakeup source.
   The normal suspend behavior (non-wakeup case) remains unchanged.

4. **Fixes a specific regression**: The bug was introduced when wakeup
   support was added in commit f62f7bcc827f ("mmc: sdhci-esdhc-imx:
   Enable support for system wakeup for SDIO") in v5.14. The original
   implementation didn't account for the conflict between pinctrl sleep
   states and wakeup functionality.

5. **Clear problem description**: The commit message clearly explains
   that on imx93-11x11-evk board, the DATA[1] pin being reconfigured to
   GPIO function during suspend prevents SDIO interrupts from waking the
   system.

6. **Subsystem-specific fix**: The change is confined to the i.MX-
   specific SDHCI driver and doesn't touch core MMC/SDHCI code,
   minimizing the risk of broader impacts.

The fix addresses a fundamental incompatibility between power-saving
pinctrl configurations and wakeup functionality - a common issue in
embedded systems that needs to be properly handled. This makes it a
strong candidate for stable backporting to ensure SDIO wakeup
functionality works correctly on affected i.MX platforms.

 drivers/mmc/host/sdhci-esdhc-imx.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index ac187a8798b7..05dd2b563c02 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -2039,12 +2039,20 @@ static int sdhci_esdhc_suspend(struct device *dev)
 		ret = sdhci_enable_irq_wakeups(host);
 		if (!ret)
 			dev_warn(dev, "Failed to enable irq wakeup\n");
+	} else {
+		/*
+		 * For the device which works as wakeup source, no need
+		 * to change the pinctrl to sleep state.
+		 * e.g. For SDIO device, the interrupt share with data pin,
+		 * but the pinctrl sleep state may config the data pin to
+		 * 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;
 	}
 
-	ret = pinctrl_pm_select_sleep_state(dev);
-	if (ret)
-		return ret;
-
 	ret = mmc_gpio_set_cd_wake(host->mmc, true);
 
 	/*
-- 
2.39.5




More information about the linux-arm-kernel mailing list