4.14-stable review patch.  If anyone has any objections, please let me know.

------------------

From: yangbo lu <[email protected]>

commit dd3f6983b4a468efca9e8caa0e2b4aa20946d801 upstream.

SD clock should be disabled for clock value 0. It's not
right to just return. This may cause failure of signal
voltage switching.

Signed-off-by: Yangbo Lu <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Cc: Rasmus Villemoes <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 drivers/mmc/host/sdhci-of-esdhc.c |   58 +++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 28 deletions(-)

--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -458,6 +458,33 @@ static unsigned int esdhc_of_get_min_clo
        return clock / 256 / 16;
 }
 
+static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
+{
+       u32 val;
+       ktime_t timeout;
+
+       val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
+
+       if (enable)
+               val |= ESDHC_CLOCK_SDCLKEN;
+       else
+               val &= ~ESDHC_CLOCK_SDCLKEN;
+
+       sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
+
+       /* Wait max 20 ms */
+       timeout = ktime_add_ms(ktime_get(), 20);
+       val = ESDHC_CLOCK_STABLE;
+       while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
+               if (ktime_after(ktime_get(), timeout)) {
+                       pr_err("%s: Internal clock never stabilised.\n",
+                               mmc_hostname(host->mmc));
+                       break;
+               }
+               udelay(10);
+       }
+}
+
 static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -469,8 +496,10 @@ static void esdhc_of_set_clock(struct sd
 
        host->mmc->actual_clock = 0;
 
-       if (clock == 0)
+       if (clock == 0) {
+               esdhc_clock_enable(host, false);
                return;
+       }
 
        /* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
        if (esdhc->vendor_ver < VENDOR_V_23)
@@ -558,33 +587,6 @@ static void esdhc_pltfm_set_bus_width(st
        sdhci_writel(host, ctrl, ESDHC_PROCTL);
 }
 
-static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
-{
-       u32 val;
-       ktime_t timeout;
-
-       val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
-
-       if (enable)
-               val |= ESDHC_CLOCK_SDCLKEN;
-       else
-               val &= ~ESDHC_CLOCK_SDCLKEN;
-
-       sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
-
-       /* Wait max 20 ms */
-       timeout = ktime_add_ms(ktime_get(), 20);
-       val = ESDHC_CLOCK_STABLE;
-       while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
-               if (ktime_after(ktime_get(), timeout)) {
-                       pr_err("%s: Internal clock never stabilised.\n",
-                               mmc_hostname(host->mmc));
-                       break;
-               }
-               udelay(10);
-       }
-}
-
 static void esdhc_reset(struct sdhci_host *host, u8 mask)
 {
        sdhci_reset(host, mask);


Reply via email to