[PATCH v21 10/12] mmc: renesas_sdhi: Save and restore IOVS across suspend/resume

From: Biju

Date: Sat Jul 18 2026 - 09:39:54 EST


From: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>

The SD_STATUS register, specifically the IOVS (I/O Voltage Switch) bit, is
not automatically restored after a suspend/resume cycle, causing the
regulator to report an incorrect voltage on resume.

Fix this by caching the CTL_SD_STATUS register value in the renesas_sdhi
private struct at suspend time and writing it back during resume. The
save/restore is only performed when a regulator device (rdev) is present,
as the IOVS bit is only relevant in that context.

Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
---
v20->v21:
* No change.
v19->v20:
* Updated resume() with scoped PM runtime call.
v18->v19:
* Updated suspend/resume with scoped runtime calls in suspend.
v17->v18:
* No change.
v1->v17:
* No change.
---
drivers/mmc/host/renesas_sdhi.h | 2 ++
drivers/mmc/host/renesas_sdhi_core.c | 26 +++++++++++++++++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index a085a4cb2e38..e2c26917b884 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -105,6 +105,8 @@ struct renesas_sdhi {
struct reset_control *rstc_axim;
struct tmio_mmc_host *host;
struct regulator_dev *rdev;
+
+ u32 cache_sd_status;
};

#define host_to_priv(host) \
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index e3ffe790cb21..d5d8afde9bfc 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -1406,6 +1406,15 @@ int renesas_sdhi_suspend(struct device *dev)
};
int ret;

+ if (priv->rdev) {
+ PM_RUNTIME_ACQUIRE_IF_ENABLED(dev, pm);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+ if (ret < 0)
+ return ret;
+
+ priv->cache_sd_status = sd_ctrl_read32(host, CTL_SD_STATUS);
+ }
+
ret = pm_runtime_force_suspend(dev);
if (ret)
return ret;
@@ -1435,8 +1444,23 @@ int renesas_sdhi_resume(struct device *dev)

ret = pm_runtime_force_resume(dev);
if (ret)
- reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
+ goto err_assert;
+
+ if (priv->rdev) {
+ PM_RUNTIME_ACQUIRE_IF_ENABLED(dev, pm);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+ if (ret < 0)
+ goto err_pm;
+
+ sd_ctrl_write32(host, CTL_SD_STATUS, priv->cache_sd_status);
+ }
+
+ return 0;

+err_pm:
+ pm_runtime_force_suspend(dev);
+err_assert:
+ reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
return ret;
}
EXPORT_SYMBOL_GPL(renesas_sdhi_resume);
--
2.43.0