Commit 8cc35289 authored by Shawn Lin's avatar Shawn Lin Committed by Ulf Hansson

mmc: sdhci: clarify the get_timeout_clock callback

Currently the get_timeout_clock callback doesn't clearly
have a statement that it needs the variant drivers to return
the timeout clock rate in kHz if the SDHCI_TIMEOUT_CLK_UNIT
isn't present, otherwise the variant drivers should return it
in MHz. It's also very likely that further variant drivers which
are going to use this callback will be confused by this situation.
Given the fact that moderm sdhci variant hosts are very prone to get
the timeout clock from common clock framework (actually the only three
users did that), it's more natural to return the value in Hz and we
make an explicit comment there. Then we put the unit conversion inside
the sdhci core. Thus will improve the code and prevent further misuses.
Reported-by: default avatarAnssi Hannula <anssi.hannula@bitwise.fi>
Signed-off-by: default avatarShawn Lin <shawn.lin@rock-chips.com>
Acked-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent bd675698
...@@ -105,9 +105,9 @@ static unsigned int sdhci_cdns_get_timeout_clock(struct sdhci_host *host) ...@@ -105,9 +105,9 @@ static unsigned int sdhci_cdns_get_timeout_clock(struct sdhci_host *host)
{ {
/* /*
* Cadence's spec says the Timeout Clock Frequency is the same as the * Cadence's spec says the Timeout Clock Frequency is the same as the
* Base Clock Frequency. Divide it by 1000 to return a value in kHz. * Base Clock Frequency.
*/ */
return host->max_clk / 1000; return host->max_clk;
} }
static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_priv *priv, u32 mode) static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_priv *priv, u32 mode)
......
...@@ -157,21 +157,6 @@ static int sdhci_arasan_syscon_write(struct sdhci_host *host, ...@@ -157,21 +157,6 @@ static int sdhci_arasan_syscon_write(struct sdhci_host *host,
return ret; return ret;
} }
static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
{
unsigned long freq;
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
/* SDHCI timeout clock is in kHz */
freq = DIV_ROUND_UP(clk_get_rate(pltfm_host->clk), 1000);
/* or in MHz */
if (host->caps & SDHCI_TIMEOUT_CLK_UNIT)
freq = DIV_ROUND_UP(freq, 1000);
return freq;
}
static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock)
{ {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
...@@ -280,7 +265,7 @@ static int sdhci_arasan_voltage_switch(struct mmc_host *mmc, ...@@ -280,7 +265,7 @@ static int sdhci_arasan_voltage_switch(struct mmc_host *mmc,
static struct sdhci_ops sdhci_arasan_ops = { static struct sdhci_ops sdhci_arasan_ops = {
.set_clock = sdhci_arasan_set_clock, .set_clock = sdhci_arasan_set_clock,
.get_max_clock = sdhci_pltfm_clk_get_max_clock, .get_max_clock = sdhci_pltfm_clk_get_max_clock,
.get_timeout_clock = sdhci_arasan_get_timeout_clock, .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
.set_bus_width = sdhci_set_bus_width, .set_bus_width = sdhci_set_bus_width,
.reset = sdhci_arasan_reset, .reset = sdhci_arasan_reset,
.set_uhs_signaling = sdhci_set_uhs_signaling, .set_uhs_signaling = sdhci_set_uhs_signaling,
......
...@@ -3396,20 +3396,22 @@ int sdhci_setup_host(struct sdhci_host *host) ...@@ -3396,20 +3396,22 @@ int sdhci_setup_host(struct sdhci_host *host)
if (!(host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) { if (!(host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
host->timeout_clk = (host->caps & SDHCI_TIMEOUT_CLK_MASK) >> host->timeout_clk = (host->caps & SDHCI_TIMEOUT_CLK_MASK) >>
SDHCI_TIMEOUT_CLK_SHIFT; SDHCI_TIMEOUT_CLK_SHIFT;
if (host->caps & SDHCI_TIMEOUT_CLK_UNIT)
host->timeout_clk *= 1000;
if (host->timeout_clk == 0) { if (host->timeout_clk == 0) {
if (host->ops->get_timeout_clock) { if (!host->ops->get_timeout_clock) {
host->timeout_clk =
host->ops->get_timeout_clock(host);
} else {
pr_err("%s: Hardware doesn't specify timeout clock frequency.\n", pr_err("%s: Hardware doesn't specify timeout clock frequency.\n",
mmc_hostname(mmc)); mmc_hostname(mmc));
ret = -ENODEV; ret = -ENODEV;
goto undma; goto undma;
} }
}
if (host->caps & SDHCI_TIMEOUT_CLK_UNIT) host->timeout_clk =
host->timeout_clk *= 1000; DIV_ROUND_UP(host->ops->get_timeout_clock(host),
1000);
}
if (override_timeout_clk) if (override_timeout_clk)
host->timeout_clk = override_timeout_clk; host->timeout_clk = override_timeout_clk;
......
...@@ -561,6 +561,7 @@ struct sdhci_ops { ...@@ -561,6 +561,7 @@ struct sdhci_ops {
int (*enable_dma)(struct sdhci_host *host); int (*enable_dma)(struct sdhci_host *host);
unsigned int (*get_max_clock)(struct sdhci_host *host); unsigned int (*get_max_clock)(struct sdhci_host *host);
unsigned int (*get_min_clock)(struct sdhci_host *host); unsigned int (*get_min_clock)(struct sdhci_host *host);
/* get_timeout_clock should return clk rate in unit of Hz */
unsigned int (*get_timeout_clock)(struct sdhci_host *host); unsigned int (*get_timeout_clock)(struct sdhci_host *host);
unsigned int (*get_max_timeout_count)(struct sdhci_host *host); unsigned int (*get_max_timeout_count)(struct sdhci_host *host);
void (*set_timeout)(struct sdhci_host *host, void (*set_timeout)(struct sdhci_host *host,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment