On 11/27/2012 05:02 PM, Seungwon Jeon wrote: > On Thursday, November 08, 2012, Jaehoon Chung <jh80.chung@xxxxxxxxxxx> wrote: >> Before disabling clock, need to check whether card is busy on not. >> >> Signed-off-by: Jaehoon Chung <jh80.chung@xxxxxxxxxxx> >> --- >> drivers/mmc/host/dw_mmc.c | 53 +++++++++++++++++++++++++++----------------- >> drivers/mmc/host/dw_mmc.h | 1 + >> 2 files changed, 33 insertions(+), 21 deletions(-) >> >> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c >> index 0a80b5c..9704b09 100644 >> --- a/drivers/mmc/host/dw_mmc.c >> +++ b/drivers/mmc/host/dw_mmc.c >> @@ -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; >> @@ -622,6 +643,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; >> @@ -638,6 +660,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); > Should 'mci_wait_reset' be called every loop? > Only if card status is still busy at the end of while, one time is enough. > >> + } while (1); > How about counting jiffies for while-loop with usleep_range? > do { > ... > usleep_range(10, 20) > } while (time_before()) Is there reason that use "usleep_range()"? > > Thanks, > Seungwon Jeon >> >> /* 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; >> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h >> index 53b8fd9..4f27357 100644 >> --- a/drivers/mmc/host/dw_mmc.h >> +++ b/drivers/mmc/host/dw_mmc.h >> @@ -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) >> -- >> 1.7.4.1 >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in >> the body of a message to majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html