[PATCH v25 10/11] mmc: renesas_sdhi: Add write32_hook for CTL_SD_CARD_CLK_CTL register writes

From: Biju Das

Date: Wed Oct 28 2026 - 08:55:38 EST


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

Add a write32_hook, analogous to the existing write16_hook, so that
sd_ctrl_write32() can wait for the SD bus to become idle before
certain 32-bit register writes.

renesas_sdhi_write32_hook() checks whether the target register is
CTL_SD_CARD_CLK_CTL and, if so, waits for TMIO_STAT_SCLKDIVEN via
renesas_sdhi_wait_idle() before the write proceeds. Other registers
are unaffected. As with write16_hook, the write is skipped if the
hook returns a non-zero error.

Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
---
v24->v25:
* Updated comit description.
* Updated tmio_mmc_host_probe() to set write32_hook() to NULL if
TMIO_MMC_HAS_IDLE_WAIT is not defined.
v23->v24:
* No change.
v23:
* New patch.
---
drivers/mmc/host/renesas_sdhi_core.c | 9 +++++++++
drivers/mmc/host/tmio_mmc.h | 7 +++++++
drivers/mmc/host/tmio_mmc_core.c | 4 +++-
3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index e897328d5b70..cb41f38ec80e 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -965,6 +965,14 @@ static int renesas_sdhi_write16_hook(struct tmio_mmc_host *host, int addr)
return 0;
}

+static int renesas_sdhi_write32_hook(struct tmio_mmc_host *host, int addr)
+{
+ if (addr == CTL_SD_CARD_CLK_CTL)
+ return renesas_sdhi_wait_idle(host, TMIO_STAT_SCLKDIVEN);
+
+ return 0;
+}
+
static int renesas_sdhi_multi_io_quirk(struct mmc_card *card,
unsigned int direction, int blk_size)
{
@@ -1199,6 +1207,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,
}

host->write16_hook = renesas_sdhi_write16_hook;
+ host->write32_hook = renesas_sdhi_write32_hook;
host->clk_enable = renesas_sdhi_clk_enable;
host->clk_disable = renesas_sdhi_clk_disable;
host->set_clock = renesas_sdhi_set_clock;
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 3ab8c0d8a2bd..e29a2fe06ef6 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -189,6 +189,7 @@ struct tmio_mmc_host {
int (*multi_io_quirk)(struct mmc_card *card,
unsigned int direction, int blk_size);
int (*write16_hook)(struct tmio_mmc_host *host, int addr);
+ int (*write32_hook)(struct tmio_mmc_host *host, int addr);
void (*reset)(struct tmio_mmc_host *host, bool preserve);
bool (*check_retune)(struct tmio_mmc_host *host, struct mmc_request *mrq);
void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq);
@@ -283,6 +284,12 @@ static inline void sd_ctrl_write32_as_16_and_16(struct tmio_mmc_host *host,

static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, u32 val)
{
+ /* If there is a hook and it returns non-zero then there
+ * is an error and the write should be skipped
+ */
+ if (host->write32_hook && host->write32_hook(host, addr))
+ return;
+
iowrite32(val, host->ctl + (addr << host->bus_shift));
}

diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index 4116c4d29c63..4fe98b437121 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -1169,8 +1169,10 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
if (mmc->f_min == 0)
return -EINVAL;

- if (!(pdata->flags & TMIO_MMC_HAS_IDLE_WAIT))
+ if (!(pdata->flags & TMIO_MMC_HAS_IDLE_WAIT)) {
_host->write16_hook = NULL;
+ _host->write32_hook = NULL;
+ }

if (pdata->flags & TMIO_MMC_USE_BUSY_TIMEOUT && !_host->get_timeout_cycles)
_host->get_timeout_cycles = tmio_mmc_get_timeout_cycles;

--
2.43.0