diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2006-06-30 02:22:24 -0700 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-07-02 16:02:03 +0100 |
commit | e16514d8d86ecbde18a2a7495cf028861b34c157 (patch) | |
tree | 9bef8f5f095d8fb4088ec1344369ada10c106d00 | |
parent | 7cb2c76fa2251474e42d55b75163c9d7ed11741e (diff) |
[MMC] sdhci: fix sdhci reset timeout
The reset register is automatically cleared when the reset has completed.
Hence, we should busy wait and not have a fixed delay.
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | drivers/mmc/sdhci.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 007e825dcb9..77b7db27b55 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -94,12 +94,27 @@ static void sdhci_dumpregs(struct sdhci_host *host) static void sdhci_reset(struct sdhci_host *host, u8 mask) { + unsigned long timeout; + writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET); - if (mask & SDHCI_RESET_ALL) { + if (mask & SDHCI_RESET_ALL) host->clock = 0; - mdelay(50); + /* Wait max 100 ms */ + timeout = 100; + + /* hw clears the bit when it's done */ + while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) { + if (timeout == 0) { + printk(KERN_ERR "%s: Reset 0x%x never completed. " + "Please report this to " BUGMAIL ".\n", + mmc_hostname(host->mmc), (int)mask); + sdhci_dumpregs(host); + return; + } + timeout--; + mdelay(1); } } @@ -619,9 +634,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) */ if (ios->power_mode == MMC_POWER_OFF) { writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE); - spin_unlock_irqrestore(&host->lock, flags); sdhci_init(host); - spin_lock_irqsave(&host->lock, flags); } sdhci_set_clock(host, ios->clock); |