mmc: make mmc_send_status() more reliable
Align the card status polling with the Linux kernel and retry the
command at least five times. Also some cards apparently mishandle the
status bits, so make sure to check the card state too.
Signed-off-by: Jan Kloetzke <jan.kloetzke@dspg.com>
Cc: Andy Fleming <afleming@gmail.com>
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 7b09272..49c3349 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -108,7 +108,7 @@
int mmc_send_status(struct mmc *mmc, int timeout)
{
struct mmc_cmd cmd;
- int err;
+ int err, retries = 5;
#ifdef CONFIG_MMC_TRACE
int status;
#endif
@@ -121,17 +121,21 @@
do {
err = mmc_send_cmd(mmc, &cmd, NULL);
- if (err)
+ if (!err) {
+ if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
+ (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
+ MMC_STATE_PRG)
+ break;
+ else if (cmd.response[0] & MMC_STATUS_MASK) {
+ printf("Status Error: 0x%08X\n",
+ cmd.response[0]);
+ return COMM_ERR;
+ }
+ } else if (--retries < 0)
return err;
- else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
- break;
udelay(1000);
- if (cmd.response[0] & MMC_STATUS_MASK) {
- printf("Status Error: 0x%08X\n", cmd.response[0]);
- return COMM_ERR;
- }
} while (timeout--);
#ifdef CONFIG_MMC_TRACE