[MMC] sdhci: check only relevant inhibit bits
authorPierre Ossman <drzeus@drzeus.cx>
Fri, 30 Jun 2006 09:22:28 +0000 (02:22 -0700)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 2 Jul 2006 15:54:50 +0000 (16:54 +0100)
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>
drivers/mmc/sdhci.c

index 302dd5bde751cb84ac73113d64cb9b23a75b7566..5324eae6d72090caf0de6cea7841c90fc91d08bc 100644 (file)
@@ -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;