diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2006-06-30 02:22:28 -0700 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-07-02 16:54:50 +0100 |
commit | fd2208d7c72ef5995b730f1e23b082261499e334 (patch) | |
tree | 45ae8cd310437e2688bf78a53a194bc655a940b7 /drivers | |
parent | 1d676e02970d9e511c9b96101501da90954ee265 (diff) |
[MMC] sdhci: check only relevant inhibit bits
Conform to the sdhci specification as to which inhibit bits should be checked
at different times.
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/sdhci.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 302dd5bde751..5324eae6d720 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -465,6 +465,7 @@ static void sdhci_finish_data(struct sdhci_host *host) static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) { int flags; + u32 mask; unsigned long timeout; WARN_ON(host->cmd); @@ -473,11 +474,20 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) /* Wait max 10 ms */ timeout = 10; - while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & - (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT)) { + + mask = SDHCI_CMD_INHIBIT; + if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY)) + mask |= SDHCI_DATA_INHIBIT; + + /* We shouldn't wait for data inihibit for stop commands, even + though they might use busy signaling */ + if (host->mrq->data && (cmd == host->mrq->data->stop)) + mask &= ~SDHCI_DATA_INHIBIT; + + while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { if (timeout == 0) { printk(KERN_ERR "%s: Controller never released " - "inhibit bits. Please report this to " + "inhibit bit(s). Please report this to " BUGMAIL ".\n", mmc_hostname(host->mmc)); sdhci_dumpregs(host); cmd->error = MMC_ERR_FAILED; |