]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
mmc: sdhci: Optimize delay loops
authorAdrian Hunter <adrian.hunter@intel.com>
Mon, 20 Mar 2017 17:50:31 +0000 (19:50 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 24 Apr 2017 19:41:26 +0000 (21:41 +0200)
The delay loops for reset and clock enable always take at least 1 ms
because they use mdelay(1). However they can take a lot less time e.g. less
than 50us. Use ktime and reduce the delay to 10 microseconds per loop.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Ludovic Desroches <ludovic.desroches@microchip.com>
drivers/mmc/host/sdhci.c

index 63bc33a54d0dd8e63b50197611be31aae6f288fc..777c82efce1d5286ecc98ac3c943199f59f878f1 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/ktime.h>
 #include <linux/highmem.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -165,7 +166,7 @@ static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
 
 void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
-       unsigned long timeout;
+       ktime_t timeout;
 
        sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
 
@@ -177,18 +178,17 @@ void sdhci_reset(struct sdhci_host *host, u8 mask)
        }
 
        /* Wait max 100 ms */
-       timeout = 100;
+       timeout = ktime_add_ms(ktime_get(), 100);
 
        /* hw clears the bit when it's done */
        while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
-               if (timeout == 0) {
+               if (ktime_after(ktime_get(), timeout)) {
                        pr_err("%s: Reset 0x%x never completed.\n",
                                mmc_hostname(host->mmc), (int)mask);
                        sdhci_dumpregs(host);
                        return;
                }
-               timeout--;
-               mdelay(1);
+               udelay(10);
        }
 }
 EXPORT_SYMBOL_GPL(sdhci_reset);
@@ -1346,24 +1346,23 @@ EXPORT_SYMBOL_GPL(sdhci_calc_clk);
 
 void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
 {
-       unsigned long timeout;
+       ktime_t timeout;
 
        clk |= SDHCI_CLOCK_INT_EN;
        sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
        /* Wait max 20 ms */
-       timeout = 20;
+       timeout = ktime_add_ms(ktime_get(), 20);
        while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
                & SDHCI_CLOCK_INT_STABLE)) {
-               if (timeout == 0) {
+               if (ktime_after(ktime_get(), timeout)) {
                        pr_err("%s: Internal clock never stabilised.\n",
                               mmc_hostname(host->mmc));
                        sdhci_dumpregs(host);
                        return;
                }
-               timeout--;
                spin_unlock_irq(&host->lock);
-               usleep_range(900, 1100);
+               udelay(10);
                spin_lock_irq(&host->lock);
        }