mmc: dw-mmc: check whether card is busy or not, before disabling clock
Subsystems (2)
Jaehoon Chung
maintainerPATCH 1/1 mmc: dw-mmc: check whether card is busy or not, before disabling clock
Before disabling clock, need to check whether card is busy on not.
Signed-off-by Jaehoon Chung <[email protected]>
Signed-off-by Kyungmin Park <[email protected]>
--- drivers/mmc/host/dw_mmc.c | 53 +++++++++++++++++++++++++++----------------- drivers/mmc/host/dw_mmc.h | 1 + 2 files changed, 33 insertions(+), 21 deletions(-)
drivers/mmc/host/dw_mmc.c +32 -21
@@ -228,6 +228,27 @@ static void dw_mci_set_timeout(struct dw_mci *host)mci_writel (host,TMOUT ,0xffffffff ); } +static bool mci_wait_reset (struct device *dev,struct dw_mci *host) +{ +unsigned long timeout = jiffies +msecs_to_jiffies (500 ); +unsigned int ctrl; + +mci_writel (host,CTRL , (SDMMC_CTRL_RESET |SDMMC_CTRL_FIFO_RESET | +SDMMC_CTRL_DMA_RESET )); + +/* 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; + }while (time_before (jiffies, timeout)); + +dev_err (dev,"Timeout resetting block (ctrl %#x)\n" , ctrl); + +return false; +} +static u32 dw_mci_prepare_command (struct mmc_host *mmc,struct mmc_command *cmd) {struct mmc_data *data;
@@ -621,6 +642,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)struct dw_mci *host = slot->host;u32 div;u32 clk_en_a; +int timeout =1000 ;if (slot->clock != host->current_speed) { div = host->bus_hz / slot->clock;
@@ -637,6 +659,16 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)"Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ" " div = %d)\n" , slot->id, host->bus_hz, slot->clock, div ? ((host->bus_hz / div) >> 1) : host->bus_hz, div); +do { +if (!(mci_readl (host,STATUS ) &SDMMC_DATA_BUSY )) +break ; +if (timeout-- <0 ) { +dev_err (host->dev,"Can't disable clock" +"because Card is busy!!\n" ); +return ; + } +mci_wait_reset (host->dev, host); + }while (1 );/* disable clock */ mci_writel (host,CLKENA ,0 );
@@ -1995,27 +2027,6 @@ no_dma:return ; } -static bool mci_wait_reset (struct device *dev,struct dw_mci *host) -{ -unsigned long timeout = jiffies +msecs_to_jiffies (500 ); -unsigned int ctrl; - -mci_writel (host,CTRL , (SDMMC_CTRL_RESET |SDMMC_CTRL_FIFO_RESET | -SDMMC_CTRL_DMA_RESET )); - -/* 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; - }while (time_before (jiffies, timeout)); - -dev_err (dev,"Timeout resetting block (ctrl %#x)\n" , ctrl); - -return false; -} - #ifdef CONFIG_OF static struct dw_mci_of_quirks { char *quirk;
drivers/mmc/host/dw_mmc.h +1 -0
@@ -127,6 +127,7 @@#define SDMMC_CMD_INDX (n) ((n) & 0x1F)/* Status register defines */ #define SDMMC_GET_FCNT (x) (((x)>>17) & 0x1FFF) +#define SDMMC_DATA_BUSY BIT(9)/* Internal DMAC interrupt defines */ #define SDMMC_IDMAC_INT_AI BIT(9)#define SDMMC_IDMAC_INT_NI BIT(8)
Signature · 1 line
1.7.4.1