* [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers
@ 2026-01-05 6:02 Matthew Schwartz
2026-01-05 6:02 ` [PATCH 1/2] mmc: rtsx: reset power state on suspend Matthew Schwartz
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Matthew Schwartz @ 2026-01-05 6:02 UTC (permalink / raw)
To: Ulf Hansson, Arnd Bergmann, Ricky Wu, Greg Kroah-Hartman
Cc: linux-mmc, linux-kernel, Matthew Schwartz
This series fixes some SD card timeout errors that occur after suspend and
resume ops on systems with Realtek PCI card readers. These issues occur on
my 2 RTS525A card readers and my RTS5261 card reader.
As a stress test, I ran the amd-s2idle script from amd-debug-tools to
automate s2idle cycles and I launched a visual novel, WITCH ON THE HOLY
NIGHT, from the SD card. Visual novels are basically just slideshows, and
waiting for 10 seconds without advancing the text is an easy way to
trigger rtsx_pci_runtime_suspend/rtsx_pci_runtime_resume. I set amd-s2idle
to test with a 10 second long s2idle length with 13 seconds between runs.
The main symptom that always shows up is "mmc0: Card stuck being busy!"
followed by timeouts and filesystem errors. This can occur during both
runtime resume and s2idle resume:
[ 260.638214] mmc0: error -110 doing runtime resume
[ 261.054214] mmc0: card d555 removed
[ 261.054382] Aborting journal on device mmcblk0p1-8.
[ 261.054386] JBD2: I/O error when updating journal superblock for mmcblk0p1-8.
[ 261.067729] EXT4-fs (mmcblk0p1): shut down requested (2)
Patch 1 adds a power_off callback so rtsx_pcr can notify the sdmmc driver
during suspend, allowing it to reset prev_power_state. This ensures
sd_power_on properly reinitializes the card on resume. It reduces the
failure rate of "mmc0: Card stuck being busy!" after resume from 20% down
to 4%.
Patch 2 increases the post-power-on settling delay from 1ms to 5ms. The
shorter delay seems insufficient for reliable reinitialization after the
hardware has been powered off during suspend. Increasing this reduces the
failure rate from 4% down to 0%, tested with over 300 s2idle cycles.
Matthew Schwartz (2):
mmc: rtsx: reset power state on suspend
mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms
drivers/misc/cardreader/rtsx_pcr.c | 9 +++++++++
drivers/mmc/host/rtsx_pci_sdmmc.c | 24 +++++++++++++++++++++++-
include/linux/rtsx_common.h | 1 +
3 files changed, 33 insertions(+), 1 deletion(-)
--
2.52.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] mmc: rtsx: reset power state on suspend
2026-01-05 6:02 [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers Matthew Schwartz
@ 2026-01-05 6:02 ` Matthew Schwartz
2026-01-20 12:41 ` Ulf Hansson
2026-01-05 6:02 ` [PATCH 2/2] mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms Matthew Schwartz
2026-01-21 10:13 ` [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers Ulf Hansson
2 siblings, 1 reply; 10+ messages in thread
From: Matthew Schwartz @ 2026-01-05 6:02 UTC (permalink / raw)
To: Ulf Hansson, Arnd Bergmann, Ricky Wu, Greg Kroah-Hartman
Cc: linux-mmc, linux-kernel, Matthew Schwartz
When rtsx_pci suspends, the card reader hardware powers off but the sdmmc
driver's prev_power_state remains as MMC_POWER_ON. This causes sd_power_on
to skip reinitialization on the next I/O request, leading to DMA transfer
timeouts and errors on resume 20% of the time.
Add a power_off slot callback so the PCR can notify the sdmmc driver
during suspend. The sdmmc driver resets prev_power_state, and sd_request
checks this to reinitialize the card before the next I/O.
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
---
drivers/misc/cardreader/rtsx_pcr.c | 9 +++++++++
drivers/mmc/host/rtsx_pci_sdmmc.c | 22 ++++++++++++++++++++++
include/linux/rtsx_common.h | 1 +
3 files changed, 32 insertions(+)
diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
index f9952d76d6ed..f1f4d8ed544d 100644
--- a/drivers/misc/cardreader/rtsx_pcr.c
+++ b/drivers/misc/cardreader/rtsx_pcr.c
@@ -1654,6 +1654,7 @@ static int __maybe_unused rtsx_pci_suspend(struct device *dev_d)
struct pci_dev *pcidev = to_pci_dev(dev_d);
struct pcr_handle *handle = pci_get_drvdata(pcidev);
struct rtsx_pcr *pcr = handle->pcr;
+ struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
@@ -1661,6 +1662,9 @@ static int __maybe_unused rtsx_pci_suspend(struct device *dev_d)
mutex_lock(&pcr->pcr_mutex);
+ if (slot->p_dev && slot->power_off)
+ slot->power_off(slot->p_dev);
+
rtsx_pci_power_off(pcr, HOST_ENTER_S3, false);
mutex_unlock(&pcr->pcr_mutex);
@@ -1772,12 +1776,17 @@ static int rtsx_pci_runtime_suspend(struct device *device)
struct pci_dev *pcidev = to_pci_dev(device);
struct pcr_handle *handle = pci_get_drvdata(pcidev);
struct rtsx_pcr *pcr = handle->pcr;
+ struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
dev_dbg(device, "--> %s\n", __func__);
cancel_delayed_work_sync(&pcr->carddet_work);
mutex_lock(&pcr->pcr_mutex);
+
+ if (slot->p_dev && slot->power_off)
+ slot->power_off(slot->p_dev);
+
rtsx_pci_power_off(pcr, HOST_ENTER_S3, true);
mutex_unlock(&pcr->pcr_mutex);
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 792ebae46697..74ee8623ad4e 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -47,6 +47,7 @@ struct realtek_pci_sdmmc {
};
static int sdmmc_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios);
+static int sd_power_on(struct realtek_pci_sdmmc *host, unsigned char power_mode);
static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
{
@@ -821,6 +822,15 @@ static void sd_request(struct work_struct *work)
rtsx_pci_start_run(pcr);
+ if (host->prev_power_state == MMC_POWER_OFF) {
+ err = sd_power_on(host, MMC_POWER_ON);
+ if (err) {
+ cmd->error = err;
+ mutex_unlock(&pcr->pcr_mutex);
+ goto finish;
+ }
+ }
+
rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth,
host->initial_mode, host->double_clk, host->vpclk);
rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, SD_MOD_SEL);
@@ -1524,6 +1534,16 @@ static void rtsx_pci_sdmmc_card_event(struct platform_device *pdev)
mmc_detect_change(host->mmc, 0);
}
+static void rtsx_pci_sdmmc_power_off(struct platform_device *pdev)
+{
+ struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
+
+ if (!host)
+ return;
+
+ host->prev_power_state = MMC_POWER_OFF;
+}
+
static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
@@ -1556,6 +1576,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
pcr->slots[RTSX_SD_CARD].p_dev = pdev;
pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
+ pcr->slots[RTSX_SD_CARD].power_off = rtsx_pci_sdmmc_power_off;
mutex_init(&host->host_mutex);
@@ -1587,6 +1608,7 @@ static void rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
pcr = host->pcr;
pcr->slots[RTSX_SD_CARD].p_dev = NULL;
pcr->slots[RTSX_SD_CARD].card_event = NULL;
+ pcr->slots[RTSX_SD_CARD].power_off = NULL;
mmc = host->mmc;
cancel_work_sync(&host->work);
diff --git a/include/linux/rtsx_common.h b/include/linux/rtsx_common.h
index da9c8c6b5d50..f294f478f0c0 100644
--- a/include/linux/rtsx_common.h
+++ b/include/linux/rtsx_common.h
@@ -32,6 +32,7 @@ struct platform_device;
struct rtsx_slot {
struct platform_device *p_dev;
void (*card_event)(struct platform_device *p_dev);
+ void (*power_off)(struct platform_device *p_dev);
};
#endif
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/2] mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms
2026-01-05 6:02 [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers Matthew Schwartz
2026-01-05 6:02 ` [PATCH 1/2] mmc: rtsx: reset power state on suspend Matthew Schwartz
@ 2026-01-05 6:02 ` Matthew Schwartz
2026-01-21 10:13 ` [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers Ulf Hansson
2 siblings, 0 replies; 10+ messages in thread
From: Matthew Schwartz @ 2026-01-05 6:02 UTC (permalink / raw)
To: Ulf Hansson, Arnd Bergmann, Ricky Wu, Greg Kroah-Hartman
Cc: linux-mmc, linux-kernel, Matthew Schwartz
The existing 1ms delay in sd_power_on is insufficient and causes resume
errors around 4% of the time.
Increasing the delay to 5ms resolves this issue after testing 300
s2idle cycles.
Fixes: 1f311c94aabd ("mmc: rtsx: add 74 Clocks in power on flow")
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
---
drivers/mmc/host/rtsx_pci_sdmmc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 74ee8623ad4e..9e95c6000256 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -947,7 +947,7 @@ static int sd_power_on(struct realtek_pci_sdmmc *host, unsigned char power_mode)
if (err < 0)
return err;
- mdelay(1);
+ mdelay(5);
err = rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN);
if (err < 0)
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] mmc: rtsx: reset power state on suspend
2026-01-05 6:02 ` [PATCH 1/2] mmc: rtsx: reset power state on suspend Matthew Schwartz
@ 2026-01-20 12:41 ` Ulf Hansson
2026-01-20 18:38 ` Matthew Schwartz
0 siblings, 1 reply; 10+ messages in thread
From: Ulf Hansson @ 2026-01-20 12:41 UTC (permalink / raw)
To: Matthew Schwartz
Cc: Arnd Bergmann, Ricky Wu, Greg Kroah-Hartman, linux-mmc,
linux-kernel
On Mon, 5 Jan 2026 at 07:02, Matthew Schwartz
<matthew.schwartz@linux.dev> wrote:
>
> When rtsx_pci suspends, the card reader hardware powers off but the sdmmc
> driver's prev_power_state remains as MMC_POWER_ON. This causes sd_power_on
> to skip reinitialization on the next I/O request, leading to DMA transfer
> timeouts and errors on resume 20% of the time.
The mmc core should power-off the card, via the ->set_ios() callback
before the rtsx_pci suspends. In other words, the mmc core should have
set MMC_POWER_OFF.
That said, there seems to be something wrong in
drivers/mmc/host/rtsx_pci_sdmmc.c's ->set_ios(), if that isn't tracked
correctly. The parent device/driver, rtsx_pci should not need to
inform that the power to the card is removed, as that should be known
already by the rtsx_pci_sdmmc driver.
>
> Add a power_off slot callback so the PCR can notify the sdmmc driver
> during suspend. The sdmmc driver resets prev_power_state, and sd_request
> checks this to reinitialize the card before the next I/O.
>
> Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
> ---
> drivers/misc/cardreader/rtsx_pcr.c | 9 +++++++++
> drivers/mmc/host/rtsx_pci_sdmmc.c | 22 ++++++++++++++++++++++
> include/linux/rtsx_common.h | 1 +
> 3 files changed, 32 insertions(+)
>
> diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
> index f9952d76d6ed..f1f4d8ed544d 100644
> --- a/drivers/misc/cardreader/rtsx_pcr.c
> +++ b/drivers/misc/cardreader/rtsx_pcr.c
> @@ -1654,6 +1654,7 @@ static int __maybe_unused rtsx_pci_suspend(struct device *dev_d)
> struct pci_dev *pcidev = to_pci_dev(dev_d);
> struct pcr_handle *handle = pci_get_drvdata(pcidev);
> struct rtsx_pcr *pcr = handle->pcr;
> + struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
>
> dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
>
> @@ -1661,6 +1662,9 @@ static int __maybe_unused rtsx_pci_suspend(struct device *dev_d)
>
> mutex_lock(&pcr->pcr_mutex);
>
> + if (slot->p_dev && slot->power_off)
> + slot->power_off(slot->p_dev);
> +
> rtsx_pci_power_off(pcr, HOST_ENTER_S3, false);
>
> mutex_unlock(&pcr->pcr_mutex);
> @@ -1772,12 +1776,17 @@ static int rtsx_pci_runtime_suspend(struct device *device)
> struct pci_dev *pcidev = to_pci_dev(device);
> struct pcr_handle *handle = pci_get_drvdata(pcidev);
> struct rtsx_pcr *pcr = handle->pcr;
> + struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
>
> dev_dbg(device, "--> %s\n", __func__);
>
> cancel_delayed_work_sync(&pcr->carddet_work);
>
> mutex_lock(&pcr->pcr_mutex);
> +
> + if (slot->p_dev && slot->power_off)
> + slot->power_off(slot->p_dev);
> +
> rtsx_pci_power_off(pcr, HOST_ENTER_S3, true);
>
> mutex_unlock(&pcr->pcr_mutex);
> diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
> index 792ebae46697..74ee8623ad4e 100644
> --- a/drivers/mmc/host/rtsx_pci_sdmmc.c
> +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
> @@ -47,6 +47,7 @@ struct realtek_pci_sdmmc {
> };
>
> static int sdmmc_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios);
> +static int sd_power_on(struct realtek_pci_sdmmc *host, unsigned char power_mode);
>
> static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
> {
> @@ -821,6 +822,15 @@ static void sd_request(struct work_struct *work)
>
> rtsx_pci_start_run(pcr);
>
> + if (host->prev_power_state == MMC_POWER_OFF) {
> + err = sd_power_on(host, MMC_POWER_ON);
> + if (err) {
> + cmd->error = err;
> + mutex_unlock(&pcr->pcr_mutex);
> + goto finish;
> + }
> + }
> +
> rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth,
> host->initial_mode, host->double_clk, host->vpclk);
> rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, SD_MOD_SEL);
> @@ -1524,6 +1534,16 @@ static void rtsx_pci_sdmmc_card_event(struct platform_device *pdev)
> mmc_detect_change(host->mmc, 0);
> }
>
> +static void rtsx_pci_sdmmc_power_off(struct platform_device *pdev)
> +{
> + struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
> +
> + if (!host)
> + return;
> +
> + host->prev_power_state = MMC_POWER_OFF;
> +}
> +
> static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
> {
> struct mmc_host *mmc;
> @@ -1556,6 +1576,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
> platform_set_drvdata(pdev, host);
> pcr->slots[RTSX_SD_CARD].p_dev = pdev;
> pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
> + pcr->slots[RTSX_SD_CARD].power_off = rtsx_pci_sdmmc_power_off;
>
> mutex_init(&host->host_mutex);
>
> @@ -1587,6 +1608,7 @@ static void rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
> pcr = host->pcr;
> pcr->slots[RTSX_SD_CARD].p_dev = NULL;
> pcr->slots[RTSX_SD_CARD].card_event = NULL;
> + pcr->slots[RTSX_SD_CARD].power_off = NULL;
> mmc = host->mmc;
>
> cancel_work_sync(&host->work);
> diff --git a/include/linux/rtsx_common.h b/include/linux/rtsx_common.h
> index da9c8c6b5d50..f294f478f0c0 100644
> --- a/include/linux/rtsx_common.h
> +++ b/include/linux/rtsx_common.h
> @@ -32,6 +32,7 @@ struct platform_device;
> struct rtsx_slot {
> struct platform_device *p_dev;
> void (*card_event)(struct platform_device *p_dev);
> + void (*power_off)(struct platform_device *p_dev);
> };
>
> #endif
> --
> 2.52.0
>
Kind regards
Uffe
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] mmc: rtsx: reset power state on suspend
2026-01-20 12:41 ` Ulf Hansson
@ 2026-01-20 18:38 ` Matthew Schwartz
2026-01-21 10:16 ` Ulf Hansson
0 siblings, 1 reply; 10+ messages in thread
From: Matthew Schwartz @ 2026-01-20 18:38 UTC (permalink / raw)
To: Ulf Hansson
Cc: Arnd Bergmann, Ricky Wu, Greg Kroah-Hartman, linux-mmc,
linux-kernel
On 1/20/26 4:41 AM, Ulf Hansson wrote:
> On Mon, 5 Jan 2026 at 07:02, Matthew Schwartz
> <matthew.schwartz@linux.dev> wrote:
>>
>> When rtsx_pci suspends, the card reader hardware powers off but the sdmmc
>> driver's prev_power_state remains as MMC_POWER_ON. This causes sd_power_on
>> to skip reinitialization on the next I/O request, leading to DMA transfer
>> timeouts and errors on resume 20% of the time.
>
> The mmc core should power-off the card, via the ->set_ios() callback
> before the rtsx_pci suspends. In other words, the mmc core should have
> set MMC_POWER_OFF.
>
> That said, there seems to be something wrong in
> drivers/mmc/host/rtsx_pci_sdmmc.c's ->set_ios(), if that isn't tracked
> correctly. The parent device/driver, rtsx_pci should not need to
> inform that the power to the card is removed, as that should be known
> already by the rtsx_pci_sdmmc driver.
Ah, I see what you mean now, I think it should be fixed in rtsx_pci_sdmmc
too.
These already seem to be in char-misc-next, so I think I need to wait
until those hit upstream and then revert as a part of a v2 patch? If I revert
from char-misc-next I'm worried the commit id won't match once it gets merged
into master.
Thanks,
Matt
>
>>
>> Add a power_off slot callback so the PCR can notify the sdmmc driver
>> during suspend. The sdmmc driver resets prev_power_state, and sd_request
>> checks this to reinitialize the card before the next I/O.
>>
>> Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
>> ---
>> drivers/misc/cardreader/rtsx_pcr.c | 9 +++++++++
>> drivers/mmc/host/rtsx_pci_sdmmc.c | 22 ++++++++++++++++++++++
>> include/linux/rtsx_common.h | 1 +
>> 3 files changed, 32 insertions(+)
>>
>> diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
>> index f9952d76d6ed..f1f4d8ed544d 100644
>> --- a/drivers/misc/cardreader/rtsx_pcr.c
>> +++ b/drivers/misc/cardreader/rtsx_pcr.c
>> @@ -1654,6 +1654,7 @@ static int __maybe_unused rtsx_pci_suspend(struct device *dev_d)
>> struct pci_dev *pcidev = to_pci_dev(dev_d);
>> struct pcr_handle *handle = pci_get_drvdata(pcidev);
>> struct rtsx_pcr *pcr = handle->pcr;
>> + struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
>>
>> dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
>>
>> @@ -1661,6 +1662,9 @@ static int __maybe_unused rtsx_pci_suspend(struct device *dev_d)
>>
>> mutex_lock(&pcr->pcr_mutex);
>>
>> + if (slot->p_dev && slot->power_off)
>> + slot->power_off(slot->p_dev);
>> +
>> rtsx_pci_power_off(pcr, HOST_ENTER_S3, false);
>>
>> mutex_unlock(&pcr->pcr_mutex);
>> @@ -1772,12 +1776,17 @@ static int rtsx_pci_runtime_suspend(struct device *device)
>> struct pci_dev *pcidev = to_pci_dev(device);
>> struct pcr_handle *handle = pci_get_drvdata(pcidev);
>> struct rtsx_pcr *pcr = handle->pcr;
>> + struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD];
>>
>> dev_dbg(device, "--> %s\n", __func__);
>>
>> cancel_delayed_work_sync(&pcr->carddet_work);
>>
>> mutex_lock(&pcr->pcr_mutex);
>> +
>> + if (slot->p_dev && slot->power_off)
>> + slot->power_off(slot->p_dev);
>> +
>> rtsx_pci_power_off(pcr, HOST_ENTER_S3, true);
>>
>> mutex_unlock(&pcr->pcr_mutex);
>> diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
>> index 792ebae46697..74ee8623ad4e 100644
>> --- a/drivers/mmc/host/rtsx_pci_sdmmc.c
>> +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
>> @@ -47,6 +47,7 @@ struct realtek_pci_sdmmc {
>> };
>>
>> static int sdmmc_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios);
>> +static int sd_power_on(struct realtek_pci_sdmmc *host, unsigned char power_mode);
>>
>> static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
>> {
>> @@ -821,6 +822,15 @@ static void sd_request(struct work_struct *work)
>>
>> rtsx_pci_start_run(pcr);
>>
>> + if (host->prev_power_state == MMC_POWER_OFF) {
>> + err = sd_power_on(host, MMC_POWER_ON);
>> + if (err) {
>> + cmd->error = err;
>> + mutex_unlock(&pcr->pcr_mutex);
>> + goto finish;
>> + }
>> + }
>> +
>> rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth,
>> host->initial_mode, host->double_clk, host->vpclk);
>> rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, SD_MOD_SEL);
>> @@ -1524,6 +1534,16 @@ static void rtsx_pci_sdmmc_card_event(struct platform_device *pdev)
>> mmc_detect_change(host->mmc, 0);
>> }
>>
>> +static void rtsx_pci_sdmmc_power_off(struct platform_device *pdev)
>> +{
>> + struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
>> +
>> + if (!host)
>> + return;
>> +
>> + host->prev_power_state = MMC_POWER_OFF;
>> +}
>> +
>> static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
>> {
>> struct mmc_host *mmc;
>> @@ -1556,6 +1576,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
>> platform_set_drvdata(pdev, host);
>> pcr->slots[RTSX_SD_CARD].p_dev = pdev;
>> pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
>> + pcr->slots[RTSX_SD_CARD].power_off = rtsx_pci_sdmmc_power_off;
>>
>> mutex_init(&host->host_mutex);
>>
>> @@ -1587,6 +1608,7 @@ static void rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
>> pcr = host->pcr;
>> pcr->slots[RTSX_SD_CARD].p_dev = NULL;
>> pcr->slots[RTSX_SD_CARD].card_event = NULL;
>> + pcr->slots[RTSX_SD_CARD].power_off = NULL;
>> mmc = host->mmc;
>>
>> cancel_work_sync(&host->work);
>> diff --git a/include/linux/rtsx_common.h b/include/linux/rtsx_common.h
>> index da9c8c6b5d50..f294f478f0c0 100644
>> --- a/include/linux/rtsx_common.h
>> +++ b/include/linux/rtsx_common.h
>> @@ -32,6 +32,7 @@ struct platform_device;
>> struct rtsx_slot {
>> struct platform_device *p_dev;
>> void (*card_event)(struct platform_device *p_dev);
>> + void (*power_off)(struct platform_device *p_dev);
>> };
>>
>> #endif
>> --
>> 2.52.0
>>
>
> Kind regards
> Uffe
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers
2026-01-05 6:02 [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers Matthew Schwartz
2026-01-05 6:02 ` [PATCH 1/2] mmc: rtsx: reset power state on suspend Matthew Schwartz
2026-01-05 6:02 ` [PATCH 2/2] mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms Matthew Schwartz
@ 2026-01-21 10:13 ` Ulf Hansson
2026-01-21 10:31 ` Greg Kroah-Hartman
2 siblings, 1 reply; 10+ messages in thread
From: Ulf Hansson @ 2026-01-21 10:13 UTC (permalink / raw)
To: Matthew Schwartz, Greg Kroah-Hartman
Cc: Arnd Bergmann, Ricky Wu, linux-mmc, linux-kernel
On Mon, 5 Jan 2026 at 07:02, Matthew Schwartz
<matthew.schwartz@linux.dev> wrote:
>
> This series fixes some SD card timeout errors that occur after suspend and
> resume ops on systems with Realtek PCI card readers. These issues occur on
> my 2 RTS525A card readers and my RTS5261 card reader.
>
> As a stress test, I ran the amd-s2idle script from amd-debug-tools to
> automate s2idle cycles and I launched a visual novel, WITCH ON THE HOLY
> NIGHT, from the SD card. Visual novels are basically just slideshows, and
> waiting for 10 seconds without advancing the text is an easy way to
> trigger rtsx_pci_runtime_suspend/rtsx_pci_runtime_resume. I set amd-s2idle
> to test with a 10 second long s2idle length with 13 seconds between runs.
>
> The main symptom that always shows up is "mmc0: Card stuck being busy!"
> followed by timeouts and filesystem errors. This can occur during both
> runtime resume and s2idle resume:
>
> [ 260.638214] mmc0: error -110 doing runtime resume
> [ 261.054214] mmc0: card d555 removed
> [ 261.054382] Aborting journal on device mmcblk0p1-8.
> [ 261.054386] JBD2: I/O error when updating journal superblock for mmcblk0p1-8.
> [ 261.067729] EXT4-fs (mmcblk0p1): shut down requested (2)
>
> Patch 1 adds a power_off callback so rtsx_pcr can notify the sdmmc driver
> during suspend, allowing it to reset prev_power_state. This ensures
> sd_power_on properly reinitializes the card on resume. It reduces the
> failure rate of "mmc0: Card stuck being busy!" after resume from 20% down
> to 4%.
>
> Patch 2 increases the post-power-on settling delay from 1ms to 5ms. The
> shorter delay seems insufficient for reliable reinitialization after the
> hardware has been powered off during suspend. Increasing this reduces the
> failure rate from 4% down to 0%, tested with over 300 s2idle cycles.
>
> Matthew Schwartz (2):
> mmc: rtsx: reset power state on suspend
> mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms
>
> drivers/misc/cardreader/rtsx_pcr.c | 9 +++++++++
> drivers/mmc/host/rtsx_pci_sdmmc.c | 24 +++++++++++++++++++++++-
> include/linux/rtsx_common.h | 1 +
> 3 files changed, 33 insertions(+), 1 deletion(-)
>
> --
> 2.52.0
>
Greg, looks like you have queued up these patches via your misc tree,
can you please drop them? We need a different approach to the problem.
Kind regards
Uffe
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] mmc: rtsx: reset power state on suspend
2026-01-20 18:38 ` Matthew Schwartz
@ 2026-01-21 10:16 ` Ulf Hansson
0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2026-01-21 10:16 UTC (permalink / raw)
To: Matthew Schwartz
Cc: Arnd Bergmann, Ricky Wu, Greg Kroah-Hartman, linux-mmc,
linux-kernel
On Tue, 20 Jan 2026 at 19:39, Matthew Schwartz
<matthew.schwartz@linux.dev> wrote:
>
> On 1/20/26 4:41 AM, Ulf Hansson wrote:
> > On Mon, 5 Jan 2026 at 07:02, Matthew Schwartz
> > <matthew.schwartz@linux.dev> wrote:
> >>
> >> When rtsx_pci suspends, the card reader hardware powers off but the sdmmc
> >> driver's prev_power_state remains as MMC_POWER_ON. This causes sd_power_on
> >> to skip reinitialization on the next I/O request, leading to DMA transfer
> >> timeouts and errors on resume 20% of the time.
> >
> > The mmc core should power-off the card, via the ->set_ios() callback
> > before the rtsx_pci suspends. In other words, the mmc core should have
> > set MMC_POWER_OFF.
> >
> > That said, there seems to be something wrong in
> > drivers/mmc/host/rtsx_pci_sdmmc.c's ->set_ios(), if that isn't tracked
> > correctly. The parent device/driver, rtsx_pci should not need to
> > inform that the power to the card is removed, as that should be known
> > already by the rtsx_pci_sdmmc driver.
>
> Ah, I see what you mean now, I think it should be fixed in rtsx_pci_sdmmc
> too.
>
> These already seem to be in char-misc-next, so I think I need to wait
> until those hit upstream and then revert as a part of a v2 patch? If I revert
> from char-misc-next I'm worried the commit id won't match once it gets merged
> into master.
I have asked Greg to drop them from his misc tree. We should either do
that or revert them in his tree. Let's see what he responds.
In the meantime, it's perfectly possible to continue working on the
issue and please base your patches on top of the mmc tree.
[...]
Kind regards
Uffe
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers
2026-01-21 10:13 ` [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers Ulf Hansson
@ 2026-01-21 10:31 ` Greg Kroah-Hartman
2026-01-21 12:49 ` Ulf Hansson
0 siblings, 1 reply; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-01-21 10:31 UTC (permalink / raw)
To: Ulf Hansson
Cc: Matthew Schwartz, Arnd Bergmann, Ricky Wu, linux-mmc,
linux-kernel
On Wed, Jan 21, 2026 at 11:13:03AM +0100, Ulf Hansson wrote:
> On Mon, 5 Jan 2026 at 07:02, Matthew Schwartz
> <matthew.schwartz@linux.dev> wrote:
> >
> > This series fixes some SD card timeout errors that occur after suspend and
> > resume ops on systems with Realtek PCI card readers. These issues occur on
> > my 2 RTS525A card readers and my RTS5261 card reader.
> >
> > As a stress test, I ran the amd-s2idle script from amd-debug-tools to
> > automate s2idle cycles and I launched a visual novel, WITCH ON THE HOLY
> > NIGHT, from the SD card. Visual novels are basically just slideshows, and
> > waiting for 10 seconds without advancing the text is an easy way to
> > trigger rtsx_pci_runtime_suspend/rtsx_pci_runtime_resume. I set amd-s2idle
> > to test with a 10 second long s2idle length with 13 seconds between runs.
> >
> > The main symptom that always shows up is "mmc0: Card stuck being busy!"
> > followed by timeouts and filesystem errors. This can occur during both
> > runtime resume and s2idle resume:
> >
> > [ 260.638214] mmc0: error -110 doing runtime resume
> > [ 261.054214] mmc0: card d555 removed
> > [ 261.054382] Aborting journal on device mmcblk0p1-8.
> > [ 261.054386] JBD2: I/O error when updating journal superblock for mmcblk0p1-8.
> > [ 261.067729] EXT4-fs (mmcblk0p1): shut down requested (2)
> >
> > Patch 1 adds a power_off callback so rtsx_pcr can notify the sdmmc driver
> > during suspend, allowing it to reset prev_power_state. This ensures
> > sd_power_on properly reinitializes the card on resume. It reduces the
> > failure rate of "mmc0: Card stuck being busy!" after resume from 20% down
> > to 4%.
> >
> > Patch 2 increases the post-power-on settling delay from 1ms to 5ms. The
> > shorter delay seems insufficient for reliable reinitialization after the
> > hardware has been powered off during suspend. Increasing this reduces the
> > failure rate from 4% down to 0%, tested with over 300 s2idle cycles.
> >
> > Matthew Schwartz (2):
> > mmc: rtsx: reset power state on suspend
> > mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms
> >
> > drivers/misc/cardreader/rtsx_pcr.c | 9 +++++++++
> > drivers/mmc/host/rtsx_pci_sdmmc.c | 24 +++++++++++++++++++++++-
> > include/linux/rtsx_common.h | 1 +
> > 3 files changed, 33 insertions(+), 1 deletion(-)
> >
> > --
> > 2.52.0
> >
>
> Greg, looks like you have queued up these patches via your misc tree,
> can you please drop them? We need a different approach to the problem.
They need to be reverted (my tree can not be rebased.) Should I do
that, or does someone want to send me the reverts?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers
2026-01-21 10:31 ` Greg Kroah-Hartman
@ 2026-01-21 12:49 ` Ulf Hansson
2026-01-21 14:51 ` Greg Kroah-Hartman
0 siblings, 1 reply; 10+ messages in thread
From: Ulf Hansson @ 2026-01-21 12:49 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Matthew Schwartz, Arnd Bergmann, Ricky Wu, linux-mmc,
linux-kernel
On Wed, 21 Jan 2026 at 11:31, Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Wed, Jan 21, 2026 at 11:13:03AM +0100, Ulf Hansson wrote:
> > On Mon, 5 Jan 2026 at 07:02, Matthew Schwartz
> > <matthew.schwartz@linux.dev> wrote:
> > >
> > > This series fixes some SD card timeout errors that occur after suspend and
> > > resume ops on systems with Realtek PCI card readers. These issues occur on
> > > my 2 RTS525A card readers and my RTS5261 card reader.
> > >
> > > As a stress test, I ran the amd-s2idle script from amd-debug-tools to
> > > automate s2idle cycles and I launched a visual novel, WITCH ON THE HOLY
> > > NIGHT, from the SD card. Visual novels are basically just slideshows, and
> > > waiting for 10 seconds without advancing the text is an easy way to
> > > trigger rtsx_pci_runtime_suspend/rtsx_pci_runtime_resume. I set amd-s2idle
> > > to test with a 10 second long s2idle length with 13 seconds between runs.
> > >
> > > The main symptom that always shows up is "mmc0: Card stuck being busy!"
> > > followed by timeouts and filesystem errors. This can occur during both
> > > runtime resume and s2idle resume:
> > >
> > > [ 260.638214] mmc0: error -110 doing runtime resume
> > > [ 261.054214] mmc0: card d555 removed
> > > [ 261.054382] Aborting journal on device mmcblk0p1-8.
> > > [ 261.054386] JBD2: I/O error when updating journal superblock for mmcblk0p1-8.
> > > [ 261.067729] EXT4-fs (mmcblk0p1): shut down requested (2)
> > >
> > > Patch 1 adds a power_off callback so rtsx_pcr can notify the sdmmc driver
> > > during suspend, allowing it to reset prev_power_state. This ensures
> > > sd_power_on properly reinitializes the card on resume. It reduces the
> > > failure rate of "mmc0: Card stuck being busy!" after resume from 20% down
> > > to 4%.
> > >
> > > Patch 2 increases the post-power-on settling delay from 1ms to 5ms. The
> > > shorter delay seems insufficient for reliable reinitialization after the
> > > hardware has been powered off during suspend. Increasing this reduces the
> > > failure rate from 4% down to 0%, tested with over 300 s2idle cycles.
> > >
> > > Matthew Schwartz (2):
> > > mmc: rtsx: reset power state on suspend
> > > mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms
> > >
> > > drivers/misc/cardreader/rtsx_pcr.c | 9 +++++++++
> > > drivers/mmc/host/rtsx_pci_sdmmc.c | 24 +++++++++++++++++++++++-
> > > include/linux/rtsx_common.h | 1 +
> > > 3 files changed, 33 insertions(+), 1 deletion(-)
> > >
> > > --
> > > 2.52.0
> > >
> >
> > Greg, looks like you have queued up these patches via your misc tree,
> > can you please drop them? We need a different approach to the problem.
>
> They need to be reverted (my tree can not be rebased.) Should I do
> that, or does someone want to send me the reverts?
If you can revert them, that would be great!
Then I will continue to work with Matthew to fix the problem in a more
proper way.
Kind regards
Uffe
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers
2026-01-21 12:49 ` Ulf Hansson
@ 2026-01-21 14:51 ` Greg Kroah-Hartman
0 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-01-21 14:51 UTC (permalink / raw)
To: Ulf Hansson
Cc: Matthew Schwartz, Arnd Bergmann, Ricky Wu, linux-mmc,
linux-kernel
On Wed, Jan 21, 2026 at 01:49:11PM +0100, Ulf Hansson wrote:
> On Wed, 21 Jan 2026 at 11:31, Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > On Wed, Jan 21, 2026 at 11:13:03AM +0100, Ulf Hansson wrote:
> > > On Mon, 5 Jan 2026 at 07:02, Matthew Schwartz
> > > <matthew.schwartz@linux.dev> wrote:
> > > >
> > > > This series fixes some SD card timeout errors that occur after suspend and
> > > > resume ops on systems with Realtek PCI card readers. These issues occur on
> > > > my 2 RTS525A card readers and my RTS5261 card reader.
> > > >
> > > > As a stress test, I ran the amd-s2idle script from amd-debug-tools to
> > > > automate s2idle cycles and I launched a visual novel, WITCH ON THE HOLY
> > > > NIGHT, from the SD card. Visual novels are basically just slideshows, and
> > > > waiting for 10 seconds without advancing the text is an easy way to
> > > > trigger rtsx_pci_runtime_suspend/rtsx_pci_runtime_resume. I set amd-s2idle
> > > > to test with a 10 second long s2idle length with 13 seconds between runs.
> > > >
> > > > The main symptom that always shows up is "mmc0: Card stuck being busy!"
> > > > followed by timeouts and filesystem errors. This can occur during both
> > > > runtime resume and s2idle resume:
> > > >
> > > > [ 260.638214] mmc0: error -110 doing runtime resume
> > > > [ 261.054214] mmc0: card d555 removed
> > > > [ 261.054382] Aborting journal on device mmcblk0p1-8.
> > > > [ 261.054386] JBD2: I/O error when updating journal superblock for mmcblk0p1-8.
> > > > [ 261.067729] EXT4-fs (mmcblk0p1): shut down requested (2)
> > > >
> > > > Patch 1 adds a power_off callback so rtsx_pcr can notify the sdmmc driver
> > > > during suspend, allowing it to reset prev_power_state. This ensures
> > > > sd_power_on properly reinitializes the card on resume. It reduces the
> > > > failure rate of "mmc0: Card stuck being busy!" after resume from 20% down
> > > > to 4%.
> > > >
> > > > Patch 2 increases the post-power-on settling delay from 1ms to 5ms. The
> > > > shorter delay seems insufficient for reliable reinitialization after the
> > > > hardware has been powered off during suspend. Increasing this reduces the
> > > > failure rate from 4% down to 0%, tested with over 300 s2idle cycles.
> > > >
> > > > Matthew Schwartz (2):
> > > > mmc: rtsx: reset power state on suspend
> > > > mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms
> > > >
> > > > drivers/misc/cardreader/rtsx_pcr.c | 9 +++++++++
> > > > drivers/mmc/host/rtsx_pci_sdmmc.c | 24 +++++++++++++++++++++++-
> > > > include/linux/rtsx_common.h | 1 +
> > > > 3 files changed, 33 insertions(+), 1 deletion(-)
> > > >
> > > > --
> > > > 2.52.0
> > > >
> > >
> > > Greg, looks like you have queued up these patches via your misc tree,
> > > can you please drop them? We need a different approach to the problem.
> >
> > They need to be reverted (my tree can not be rebased.) Should I do
> > that, or does someone want to send me the reverts?
>
> If you can revert them, that would be great!
>
> Then I will continue to work with Matthew to fix the problem in a more
> proper way.
All now reverted, thanks!
greg k-h
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-01-21 14:52 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-05 6:02 [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers Matthew Schwartz
2026-01-05 6:02 ` [PATCH 1/2] mmc: rtsx: reset power state on suspend Matthew Schwartz
2026-01-20 12:41 ` Ulf Hansson
2026-01-20 18:38 ` Matthew Schwartz
2026-01-21 10:16 ` Ulf Hansson
2026-01-05 6:02 ` [PATCH 2/2] mmc: rtsx_pci_sdmmc: increase power-on settling delay to 5ms Matthew Schwartz
2026-01-21 10:13 ` [PATCH 0/2] mmc: rtsx: card stuck busy fixes for Realtek PCI SD card readers Ulf Hansson
2026-01-21 10:31 ` Greg Kroah-Hartman
2026-01-21 12:49 ` Ulf Hansson
2026-01-21 14:51 ` Greg Kroah-Hartman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox