This patch ensured the CIU-reset.

If data0 line is low, bit[9] in status register is set to 1.
Then we can know the card is busy.

Using this bit in status register, we can ensure to reset the CIU correctly.
When card is busy and doing ciu-reset, seem like reset completed.
But actually didn't complete ciu-reset. because card is busy.

So i think good whether check card busy or not before reset the ciu.


Signed-off-by: Jaehoon Chung <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
Reported-by: Wonil Choi <[email protected]>
---
 drivers/mmc/host/dw_mmc.c |   15 +++++++++------
 drivers/mmc/host/dw_mmc.h |    3 +++
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0ed1d28..277f8ef 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1785,17 +1785,20 @@ no_dma:
 static bool mci_wait_reset(struct device *dev, struct dw_mci *host)
 {
        unsigned long timeout = jiffies + msecs_to_jiffies(500);
-       unsigned int ctrl;
+       unsigned int ctrl, status;
 
-       mci_writel(host, CTRL, (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET |
-                               SDMMC_CTRL_DMA_RESET));
+       mci_writel(host, CTRL, SDMMC_CTRL_RESET_ALL);
 
        /* wait till resets clear */
        do {
                ctrl = mci_readl(host, CTRL);
-               if (!(ctrl & (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET |
-                             SDMMC_CTRL_DMA_RESET)))
-                       return true;
+               if (!(ctrl & SDMMC_CTRL_RESET_ALL)) {
+                       status = mci_readl(host, STATUS);
+                       if (!(status & SDMMC_DATA_BUSY))
+                               return true;
+                       else
+                               mci_writel(host, CTRL, SDMMC_CTRL_RESET_ALL);
+               }
        } while (time_before(jiffies, timeout));
 
        dev_err(dev, "Timeout resetting block (ctrl %#x)\n", ctrl);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index bfa3c1c..94e48ad 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -69,6 +69,8 @@
 #define SDMMC_CTRL_DMA_RESET           BIT(2)
 #define SDMMC_CTRL_FIFO_RESET          BIT(1)
 #define SDMMC_CTRL_RESET               BIT(0)
+#define SDMMC_CTRL_RESET_ALL   (SDMMC_CTRL_DMA_RESET |\
+                       SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_RESET)
 /* Clock Enable register defines */
 #define SDMMC_CLKEN_LOW_PWR            BIT(16)
 #define SDMMC_CLKEN_ENABLE             BIT(0)
@@ -118,6 +120,7 @@
 #define SDMMC_CMD_INDX(n)              ((n) & 0x1F)
 /* Status register defines */
 #define SDMMC_GET_FCNT(x)              (((x)>>17) & 0x1FF)
+#define SDMMC_DATA_BUSY                        BIT(9)
 /* Internal DMAC interrupt defines */
 #define SDMMC_IDMAC_INT_AI             BIT(9)
 #define SDMMC_IDMAC_INT_NI             BIT(8)
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to