diff options
author | Anton Vorontsov <avorontsov@ru.mvista.com> | 2009-09-22 19:45:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 10:39:37 -0400 |
commit | 81b39802468fe4bf5c6b038837319b608acfdd3e (patch) | |
tree | aa5e95bcee95cb4dd7a4811abd8e740f4ef4a958 /drivers/mmc/host/sdhci.c | |
parent | c08592698534f390afe726c38301aa8f1620c361 (diff) |
sdhci-of: fix high-speed cards recognition
eSDHC fails to recognize some SDHS cards, throwing timeout errors:
mmc0: error -110 whilst initialising SD card
That's because we calculate timeout value in a wrong way: on eSDHC hosts
the timeout clock is derivied from the SD clock, which is set dynamically.
As David Vrabel suggested, deriving timeout clock from SD clock is a
common scheme, so let's implement DATA_TIMEOUT_USES_SDCLK quirk and use it
for eSDHC hosts.
Also, from now on we don't need esdhc_get_timeout_clock() callback, so
remove it.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Cc: Pierre Ossman <pierre@ossman.eu>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: David Vrabel <david.vrabel@csr.com>
Cc: Ben Dooks <ben@fluff.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: <linux-mmc@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 7f7f45b4b07b..38a78743fc51 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -591,6 +591,9 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data) | |||
591 | target_timeout = data->timeout_ns / 1000 + | 591 | target_timeout = data->timeout_ns / 1000 + |
592 | data->timeout_clks / host->clock; | 592 | data->timeout_clks / host->clock; |
593 | 593 | ||
594 | if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) | ||
595 | host->timeout_clk = host->clock / 1000; | ||
596 | |||
594 | /* | 597 | /* |
595 | * Figure out needed cycles. | 598 | * Figure out needed cycles. |
596 | * We do this in steps in order to fit inside a 32 bit int. | 599 | * We do this in steps in order to fit inside a 32 bit int. |
@@ -1757,13 +1760,15 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1757 | host->timeout_clk = | 1760 | host->timeout_clk = |
1758 | (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; | 1761 | (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; |
1759 | if (host->timeout_clk == 0) { | 1762 | if (host->timeout_clk == 0) { |
1760 | if (!host->ops->get_timeout_clock) { | 1763 | if (host->ops->get_timeout_clock) { |
1764 | host->timeout_clk = host->ops->get_timeout_clock(host); | ||
1765 | } else if (!(host->quirks & | ||
1766 | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) { | ||
1761 | printk(KERN_ERR | 1767 | printk(KERN_ERR |
1762 | "%s: Hardware doesn't specify timeout clock " | 1768 | "%s: Hardware doesn't specify timeout clock " |
1763 | "frequency.\n", mmc_hostname(mmc)); | 1769 | "frequency.\n", mmc_hostname(mmc)); |
1764 | return -ENODEV; | 1770 | return -ENODEV; |
1765 | } | 1771 | } |
1766 | host->timeout_clk = host->ops->get_timeout_clock(host); | ||
1767 | } | 1772 | } |
1768 | if (caps & SDHCI_TIMEOUT_CLK_UNIT) | 1773 | if (caps & SDHCI_TIMEOUT_CLK_UNIT) |
1769 | host->timeout_clk *= 1000; | 1774 | host->timeout_clk *= 1000; |