Blackfin: bfin_sdh: clean up send_cmd
authorMike Frysinger <vapier@gentoo.org>
Mon, 21 Jun 2010 20:56:54 +0000 (20:56 +0000)
committerMike Frysinger <vapier@gentoo.org>
Sat, 2 Oct 2010 20:00:37 +0000 (16:00 -0400)
Simplify the command setup and status checking steps, and add a proper
timeout to the status polling code to avoid possible infinite hangs.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
drivers/mmc/bfin_sdh.c

index 4a77779f5b6bfb5bdf20ad92ab52b9fbe53198bd..27d9bf6cbf985d167ec116c4fadc25bd5752744f 100644 (file)
 static int
 sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
 {
-       unsigned int sdh_cmd;
-       unsigned int status;
+       unsigned int status, timeout;
        int cmd = mmc_cmd->cmdidx;
        int flags = mmc_cmd->resp_type;
        int arg = mmc_cmd->cmdarg;
-       int ret = 0;
-       sdh_cmd = 0;
-
-       sdh_cmd |= cmd;
+       int ret;
+       u16 sdh_cmd;
 
+       sdh_cmd = cmd | CMD_E;
        if (flags & MMC_RSP_PRESENT)
                sdh_cmd |= CMD_RSP;
-
        if (flags & MMC_RSP_136)
                sdh_cmd |= CMD_L_RSP;
 
        bfin_write_SDH_ARGUMENT(arg);
-       bfin_write_SDH_COMMAND(sdh_cmd | CMD_E);
+       bfin_write_SDH_COMMAND(sdh_cmd);
 
        /* wait for a while */
+       timeout = 0;
        do {
+               if (++timeout > 1000000) {
+                       status = CMD_TIME_OUT;
+                       break;
+               }
                udelay(1);
                status = bfin_read_SDH_STATUS();
        } while (!(status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT |
@@ -94,12 +96,15 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
        }
 
        if (status & CMD_TIME_OUT)
-               ret |= TIMEOUT;
+               ret = TIMEOUT;
        else if (status & CMD_CRC_FAIL && flags & MMC_RSP_CRC)
-               ret |= COMM_ERR;
+               ret = COMM_ERR;
+       else
+               ret = 0;
 
        bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT |
                                CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT);
+
        return ret;
 }