Hi Kaustabh,
On Fri, Oct 17, 2025 at 08:54:08PM +0530, Kaustabh Chakraborty wrote:
>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.

This patch looks good to me, but I need a few more details to understand:

Do you mean that DWMCI_INTMSK_CDONE must be cleared before sending
out next cmd?

Per my guess, DWMCI_CMD_START will be cleared when CMD done from
controller perspective, but the card may not return back response.
DWMCI_INTMSK_CDONE means response done. But if there is some commands
does not have response, will DWMCI_INTMSK_CDONE still be set?

Please help clarify.

Thanks,
Peng

>
>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]>
>---
> 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
>

Reply via email to