summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2010-06-21 20:56:54 +0000
committerMike Frysinger <vapier@gentoo.org>2010-10-02 16:00:37 -0400
commit6815f540db61b4c038e3ffb98b52009d11d3c1c1 (patch)
tree35338bbb7525d5488ecc0c74908ab4af1d80abc9 /drivers/mmc
parent6f070e1867f5c31df17571b0c26f0a73cc3fe600 (diff)
downloadu-boot-imx-6815f540db61b4c038e3ffb98b52009d11d3c1c1.zip
u-boot-imx-6815f540db61b4c038e3ffb98b52009d11d3c1c1.tar.gz
u-boot-imx-6815f540db61b4c038e3ffb98b52009d11d3c1c1.tar.bz2
Blackfin: bfin_sdh: clean up send_cmd
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>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/bfin_sdh.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c
index 4a77779..27d9bf6 100644
--- a/drivers/mmc/bfin_sdh.c
+++ b/drivers/mmc/bfin_sdh.c
@@ -58,27 +58,29 @@
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;
}