summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJan Kloetzke <jan.kloetzke@dspg.com>2012-02-05 22:29:12 +0000
committerAndy Fleming <afleming@freescale.com>2012-02-15 17:42:22 -0600
commitd617c426a6ef8d731da1936bca7649a1574d5420 (patch)
tree44cd0587b8624692b62b478279bce1f5948fdbaa /drivers
parent93ad0d18c0ff1fb0a141bdfe66c76b7d4f922619 (diff)
downloadu-boot-imx-d617c426a6ef8d731da1936bca7649a1574d5420.zip
u-boot-imx-d617c426a6ef8d731da1936bca7649a1574d5420.tar.gz
u-boot-imx-d617c426a6ef8d731da1936bca7649a1574d5420.tar.bz2
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/mmc.c20
1 files changed, 12 insertions, 8 deletions
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_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
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 @@ int mmc_send_status(struct mmc *mmc, int timeout)
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