summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKaustabh Chakraborty <[email protected]>2025-10-17 20:54:08 +0530
committerPeng Fan <[email protected]>2025-10-30 10:11:17 +0800
commitae4601959202f4ea21c8a1aa42c5d2d894b03d57 (patch)
tree2814bf4e085cd48537e61abdde013f87a351058a /drivers
parent3a5b187b5c03eff681d4e41823313dfa28dfe845 (diff)
mmc: dw_mmc: properly address command completion in dwmci_control_clken()
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 <[email protected]> Signed-off-by: Peng Fan <[email protected]>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/dw_mmc.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 130a5bb57f3..1aa992c352c 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;
}