summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRicky Wu <ricky_wu@realtek.com>2025-07-11 17:01:43 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-08-28 17:28:31 +0300
commitca9fb654f89baa76fa4f806080ad4c5ed69ed953 (patch)
tree73d9c4a06100aa067f90ba94467a06e40fe65f14
parent5badd56c711e2c8371d1670f9bd486697575423c (diff)
downloadlinux-ca9fb654f89baa76fa4f806080ad4c5ed69ed953.tar.xz
misc: rtsx: usb: Ensure mmc child device is active when card is present
commit 966c5cd72be8989c8a559ddef8e8ff07a37c5eb0 upstream. When a card is present in the reader, the driver currently defers autosuspend by returning -EAGAIN during the suspend callback to trigger USB remote wakeup signaling. However, this does not guarantee that the mmc child device has been resumed, which may cause issues if it remains suspended while the card is accessible. This patch ensures that all child devices, including the mmc host controller, are explicitly resumed before returning -EAGAIN. This fixes a corner case introduced by earlier remote wakeup handling, improving reliability of runtime PM when a card is inserted. Fixes: 883a87ddf2f1 ("misc: rtsx_usb: Use USB remote wakeup signaling for card insertion detection") Cc: stable@vger.kernel.org Signed-off-by: Ricky Wu <ricky_wu@realtek.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://lore.kernel.org/r/20250711140143.2105224-1-ricky_wu@realtek.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/misc/cardreader/rtsx_usb.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c
index f150d8769f19..f546b050cb49 100644
--- a/drivers/misc/cardreader/rtsx_usb.c
+++ b/drivers/misc/cardreader/rtsx_usb.c
@@ -698,6 +698,12 @@ static void rtsx_usb_disconnect(struct usb_interface *intf)
}
#ifdef CONFIG_PM
+static int rtsx_usb_resume_child(struct device *dev, void *data)
+{
+ pm_request_resume(dev);
+ return 0;
+}
+
static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
{
struct rtsx_ucr *ucr =
@@ -713,8 +719,10 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
mutex_unlock(&ucr->dev_mutex);
/* Defer the autosuspend if card exists */
- if (val & (SD_CD | MS_CD))
+ if (val & (SD_CD | MS_CD)) {
+ device_for_each_child(&intf->dev, NULL, rtsx_usb_resume_child);
return -EAGAIN;
+ }
} else {
/* There is an ongoing operation*/
return -EAGAIN;
@@ -724,12 +732,6 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
return 0;
}
-static int rtsx_usb_resume_child(struct device *dev, void *data)
-{
- pm_request_resume(dev);
- return 0;
-}
-
static int rtsx_usb_resume(struct usb_interface *intf)
{
device_for_each_child(&intf->dev, NULL, rtsx_usb_resume_child);