mmc: sdhci-of-esdhc: set timeout to max before tuning
[linux-2.6-microblaze.git] / drivers / mmc / host / sdhci-of-esdhc.c
index 45881b3..baf7801 100644 (file)
@@ -1052,6 +1052,17 @@ static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
        esdhc_tuning_block_enable(host, true);
 
+       /*
+        * The eSDHC controller takes the data timeout value into account
+        * during tuning. If the SD card is too slow sending the response, the
+        * timer will expire and a "Buffer Read Ready" interrupt without data
+        * is triggered. This leads to tuning errors.
+        *
+        * Just set the timeout to the maximum value because the core will
+        * already take care of it in sdhci_send_tuning().
+        */
+       sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
+
        hs400_tuning = host->flags & SDHCI_HS400_TUNING;
 
        do {
@@ -1360,13 +1371,19 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
                clk_put(clk);
        }
 
-       if (esdhc->peripheral_clock) {
-               esdhc_clock_enable(host, false);
-               val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+       esdhc_clock_enable(host, false);
+       val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+       /*
+        * This bit is not able to be reset by SDHCI_RESET_ALL. Need to
+        * initialize it as 1 or 0 once, to override the different value
+        * which may be configured in bootloader.
+        */
+       if (esdhc->peripheral_clock)
                val |= ESDHC_PERIPHERAL_CLK_SEL;
-               sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
-               esdhc_clock_enable(host, true);
-       }
+       else
+               val &= ~ESDHC_PERIPHERAL_CLK_SEL;
+       sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
+       esdhc_clock_enable(host, true);
 }
 
 static int esdhc_hs400_prepare_ddr(struct mmc_host *mmc)
@@ -1468,6 +1485,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
 static struct platform_driver sdhci_esdhc_driver = {
        .driver = {
                .name = "sdhci-esdhc",
+               .probe_type = PROBE_PREFER_ASYNCHRONOUS,
                .of_match_table = sdhci_esdhc_of_match,
                .pm = &esdhc_of_dev_pm_ops,
        },