]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mmc: sdhci-esdhc-imx: Don't change pinctrl in suspend if wakeup source
authorHaibo Chen <haibo.chen@nxp.com>
Wed, 21 May 2025 03:31:34 +0000 (11:31 +0800)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 24 Jun 2025 10:43:21 +0000 (12:43 +0200)
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@nxp.com>
Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
Link: https://lore.kernel.org/r/20250521033134.112671-1-ziniu.wang_1@nxp.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/sdhci-esdhc-imx.c

index ac187a8798b710afa8bc1db8d724b4355a6cbdef..05dd2b563c02a75df1074ec2efd9af26ef0b040e 100644 (file)
@@ -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);
 
        /*