Skip to content

Commit dd3f698

Browse files
yangbolu1991storulf
authored andcommitted
mmc: sdhci-of-esdhc: disable SD clock for clock value 0
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 <yangbo.lu@nxp.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent cdaba73 commit dd3f698

File tree

1 file changed

+30
-28
lines changed

1 file changed

+30
-28
lines changed

drivers/mmc/host/sdhci-of-esdhc.c

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,33 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
458458
return clock / 256 / 16;
459459
}
460460

461+
static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
462+
{
463+
u32 val;
464+
ktime_t timeout;
465+
466+
val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
467+
468+
if (enable)
469+
val |= ESDHC_CLOCK_SDCLKEN;
470+
else
471+
val &= ~ESDHC_CLOCK_SDCLKEN;
472+
473+
sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
474+
475+
/* Wait max 20 ms */
476+
timeout = ktime_add_ms(ktime_get(), 20);
477+
val = ESDHC_CLOCK_STABLE;
478+
while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
479+
if (ktime_after(ktime_get(), timeout)) {
480+
pr_err("%s: Internal clock never stabilised.\n",
481+
mmc_hostname(host->mmc));
482+
break;
483+
}
484+
udelay(10);
485+
}
486+
}
487+
461488
static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
462489
{
463490
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -469,8 +496,10 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
469496

470497
host->mmc->actual_clock = 0;
471498

472-
if (clock == 0)
499+
if (clock == 0) {
500+
esdhc_clock_enable(host, false);
473501
return;
502+
}
474503

475504
/* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
476505
if (esdhc->vendor_ver < VENDOR_V_23)
@@ -558,33 +587,6 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
558587
sdhci_writel(host, ctrl, ESDHC_PROCTL);
559588
}
560589

561-
static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
562-
{
563-
u32 val;
564-
ktime_t timeout;
565-
566-
val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
567-
568-
if (enable)
569-
val |= ESDHC_CLOCK_SDCLKEN;
570-
else
571-
val &= ~ESDHC_CLOCK_SDCLKEN;
572-
573-
sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
574-
575-
/* Wait max 20 ms */
576-
timeout = ktime_add_ms(ktime_get(), 20);
577-
val = ESDHC_CLOCK_STABLE;
578-
while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
579-
if (ktime_after(ktime_get(), timeout)) {
580-
pr_err("%s: Internal clock never stabilised.\n",
581-
mmc_hostname(host->mmc));
582-
break;
583-
}
584-
udelay(10);
585-
}
586-
}
587-
588590
static void esdhc_reset(struct sdhci_host *host, u8 mask)
589591
{
590592
sdhci_reset(host, mask);

0 commit comments

Comments
 (0)