[PATCH v1 2/3] mmc: host: dw_mmc-rockchip: add rockchip,disable-runtime-pm quirk
Marco Schirrmeister
mschirrmeister at gmail.com
Fri Jan 9 17:07:14 PST 2026
The FriendlyElec NanoPi R76S (based on the Rockchip RK3576) suffers from
a persistent bus-reset loop on the microSD (dw_mmc) interface during
idle periods. When the microSD controller enters runtime-suspend, the
subsequent transition back to an active state causes the bus timing to
become unstable. This forces the driver to drop the bus speed to 400kHz
to perform a full retraining of the SDR104 link.
Investigations using the runtime_status interface confirm that
preventing the controller from entering a low-power state stabilizes
the link and eliminates the reset loop entirely.
This patch introduces a new 'rockchip,disable-runtime-pm' Boolean
property to the dw_mmc-rockchip driver. The property is used to:
- Bypass the 50ms autosuspend delay during the probe sequence.
- Explicitly increment the device usage count via pm_runtime_get_noresume()
to keep the controller active and prevent it from being suspended
during idle periods.
Signed-off-by: Marco Schirrmeister <mschirrmeister at gmail.com>
---
drivers/mmc/host/dw_mmc-rockchip.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 62c68cda1e21..d3e5c06d80ef 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -538,6 +538,7 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev)
{
const struct dw_mci_drv_data *drv_data;
const struct of_device_id *match;
+ bool disable_rpm = of_property_read_bool(pdev->dev.of_node, "rockchip,disable-runtime-pm");
int ret;
if (!pdev->dev.of_node)
@@ -549,8 +550,13 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev)
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
- pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
- pm_runtime_use_autosuspend(&pdev->dev);
+
+ /* Only setup autosuspend if the DTS hasn't prohibited it */
+ if (!disable_rpm) {
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ }
+
ret = dw_mci_pltfm_register(pdev, drv_data);
if (ret) {
@@ -560,7 +566,20 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev)
return ret;
}
- pm_runtime_put_autosuspend(&pdev->dev);
+ /*
+ * For boards with sensitive signaling like the RK3576-based NanoPi R76S,
+ * we inhibit runtime PM to prevent bus resets during idle transitions.
+ */
+ if (disable_rpm) {
+ /*
+ * Instead of nuclear option (pm_runtime_forbid), we use
+ * the "soft" way by incrementing the usage count to
+ * prevent the controller from ever hitting runtime_suspend.
+ */
+ pm_runtime_get_noresume(&pdev->dev);
+ } else {
+ pm_runtime_put_autosuspend(&pdev->dev);
+ }
return 0;
}
--
2.52.0
More information about the linux-arm-kernel
mailing list