[PATCH 3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken()

Kaustabh Chakraborty kauschluss at disroot.org
Fri Oct 17 17:24:08 CEST 2025


The current implementation polls for the DWMCI_CMD register, for the
DWMCI_CMD_START bit to turn off, which indicates that the command has
been completed. The problem with this approach is that it doesn't
address the DWMCI_INTMSK_CDONE bit in the interrupt register,
DWMCI_RINTSTS. As a result, subsequent commands result in timeout errors.

Re-implement the waiting logic by polling for said interrupt status bit
and setting it low if raised.

Signed-off-by: Kaustabh Chakraborty <kauschluss at disroot.org>
---
 drivers/mmc/dw_mmc.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 130a5bb57f3cddc50b3cd0df2f40981de680e852..1aa992c352c3f11ccdd1c02745fa988646952261 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -507,20 +507,21 @@ static int dwmci_control_clken(struct dwmci_host *host, bool on)
 {
 	const u32 val = on ? DWMCI_CLKEN_ENABLE | DWMCI_CLKEN_LOW_PWR : 0;
 	const u32 cmd_only_clk = DWMCI_CMD_PRV_DAT_WAIT | DWMCI_CMD_UPD_CLK;
-	int timeout = 10000;
-	u32 status;
+	int i, timeout = 10000;
+	u32 mask;
 
 	dwmci_writel(host, DWMCI_CLKENA, val);
 
 	/* Inform CIU */
 	dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_START | cmd_only_clk);
-	do {
-		status = dwmci_readl(host, DWMCI_CMD);
-		if (timeout-- < 0) {
-			debug("%s: Timeout!\n", __func__);
-			return -ETIMEDOUT;
+
+	for (i = 0; i < timeout; i++) {
+		mask = dwmci_readl(host, DWMCI_RINTSTS);
+		if (mask & DWMCI_INTMSK_CDONE) {
+			dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_CDONE);
+			break;
 		}
-	} while (status & DWMCI_CMD_START);
+	}
 
 	return 0;
 }

-- 
2.51.0



More information about the U-Boot mailing list