diff mbox series

[v1] mmc: rtsx_usb_sdmmc: add parameter to always poll for card presence

Message ID 20250510031945.1004129-1-git@thegavinli.com
State New
Headers show
Series [v1] mmc: rtsx_usb_sdmmc: add parameter to always poll for card presence | expand

Commit Message

Gavin Li May 10, 2025, 3:19 a.m. UTC
Some RTS5179 implementations have broken remote wake-up, preventing the
runtime_resume calback from being called and breaking card insertion.
With the current implementation, the card is detected if it is present
when the RTS5179 enumerates. However, card insertions after the initial
enumeration are not detected, and a rtsx_usb_sdmmc module reload is
necessary to detect the card again.

The change to only poll when card inserted was added in commit
4dad599b8b5d ("Re-work card detection/removal support") to save power
when the card is not present. Thus, this change adds a module parameter
to revert to the previous behavior of always polling for card presence.

Signed-off-by: Gavin Li <git@thegavinli.com>
---
 drivers/mmc/host/rtsx_usb_sdmmc.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
index d229c2b83ea9..246b0da1e908 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -30,6 +30,10 @@ 
 #define RTSX_USB_USE_LEDS_CLASS
 #endif
 
+static bool always_poll = false;
+module_param(always_poll, bool, 0444);
+MODULE_PARM_DESC(always_poll, "always poll for card presence");
+
 struct rtsx_usb_sdmmc {
 	struct platform_device	*pdev;
 	struct rtsx_ucr	*ucr;
@@ -1306,6 +1310,14 @@  static void rtsx_usb_init_host(struct rtsx_usb_sdmmc *host)
 	mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE |
 		MMC_CAP2_NO_SDIO;
 
+	/*
+	 * Some RTS5179 implementations have broken remote wake-up, preventing the
+	 * runtime_resume calback from being called and breaking card insertion.
+	 * In that case, we always need to poll.
+	 */
+	if (always_poll)
+		mmc->caps |= MMC_CAP_NEEDS_POLL;
+
 	mmc->max_current_330 = 400;
 	mmc->max_current_180 = 800;
 	mmc->ops = &rtsx_usb_sdmmc_ops;
@@ -1419,7 +1431,9 @@  static int rtsx_usb_sdmmc_runtime_suspend(struct device *dev)
 {
 	struct rtsx_usb_sdmmc *host = dev_get_drvdata(dev);
 
-	host->mmc->caps &= ~MMC_CAP_NEEDS_POLL;
+	if (!always_poll)
+		host->mmc->caps &= ~MMC_CAP_NEEDS_POLL;
+
 	return 0;
 }
 
@@ -1427,9 +1441,12 @@  static int rtsx_usb_sdmmc_runtime_resume(struct device *dev)
 {
 	struct rtsx_usb_sdmmc *host = dev_get_drvdata(dev);
 
-	host->mmc->caps |= MMC_CAP_NEEDS_POLL;
-	if (sdmmc_get_cd(host->mmc) == 1)
-		mmc_detect_change(host->mmc, 0);
+	if (!always_poll) {
+		host->mmc->caps |= MMC_CAP_NEEDS_POLL;
+		if (sdmmc_get_cd(host->mmc) == 1)
+			mmc_detect_change(host->mmc, 0);
+	}
+
 	return 0;
 }
 #endif