@@ -878,6 +878,25 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
cmd, arg, cmd_status);
}
+static bool dw_mci_wait_busy(struct dw_mci *host)
+{
+ unsigned long timeout;
+
+ if (host->verid < DW_MMC_250A)
+ return true;
+
+ timeout = jiffies + msecs_to_jiffies(500);
+ while (time_before(jiffies, timeout)) {
+ if (!(mci_readl(host, STATUS) & SDMMC_STATUS_BUSY))
+ return true;
+
+ usleep(1000, 2000);
+ }
+ dev_err(host->dev, "Busy timeout\n");
+
+ return false;
+}
+
static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
{
struct dw_mci *host = slot->host;
@@ -891,8 +910,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
if (!clock) {
- mci_writel(host, CLKENA, 0);
- mci_send_cmd(slot, sdmmc_cmd_bits, 0);
+ if (dw_mci_wait_busy(host)) {
+ mci_writel(host, CLKENA, 0);
+ mci_send_cmd(slot, sdmmc_cmd_bits, 0);
+ } else
+ return;
} else if (clock != host->current_speed || force_clkinit) {
div = host->bus_hz / clock;
if (host->bus_hz % clock && host->bus_hz > clock)
@@ -15,6 +15,7 @@
#define _DW_MMC_H_
#define DW_MMC_240A 0x240a
+#define DW_MMC_250A 0x250a
#define SDMMC_CTRL 0x000
#define SDMMC_PWREN 0x004
According to specs for version 250A, status register should be tested before clock update. Otherwise in case MMC card is missing mci_send_cmd timeouts and subsequent CTYPE registry write causes system hang. This behavior has been observed on Exynos5422/Odroid-XU3. Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> --- drivers/mmc/host/dw_mmc.c | 26 ++++++++++++++++++++++++-- drivers/mmc/host/dw_mmc.h | 1 + 2 files changed, 25 insertions(+), 2 deletions(-)