diff options
| author | Wolfgang Denk <wd@denx.de> | 2012-02-17 23:54:46 +0100 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2012-02-17 23:54:46 +0100 | 
| commit | 2acca35ce4604dcef933f07d90aa9c9c930e1049 (patch) | |
| tree | c97ed42561e365e04d62b38425f65c662ab267d4 /drivers/mmc | |
| parent | 7dda0c3759c6ee190d44b8ceaeab58047cb9a957 (diff) | |
| parent | d617c426a6ef8d731da1936bca7649a1574d5420 (diff) | |
| download | olio-uboot-2014.01-2acca35ce4604dcef933f07d90aa9c9c930e1049.tar.xz olio-uboot-2014.01-2acca35ce4604dcef933f07d90aa9c9c930e1049.zip  | |
Merge branch 'master' of git://git.denx.de/u-boot-mmc
* 'master' of git://git.denx.de/u-boot-mmc:
  mmc: make mmc_send_status() more reliable
  mmc: fix card busy polling
  Tegra: mmc: Fixed handling of interrupts in timeouts.
  omap_hsmmc: Wait for CMDI to be clear
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/mmc.c | 34 | ||||
| -rw-r--r-- | drivers/mmc/omap_hsmmc.c | 5 | ||||
| -rw-r--r-- | drivers/mmc/tegra2_mmc.c | 4 | 
3 files changed, 25 insertions, 18 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6db37b1fc..49c3349f5 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 @@ -305,11 +309,12 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)  			printf("mmc fail to send stop cmd\n");  			return 0;  		} - -		/* Waiting for the ready status */ -		mmc_send_status(mmc, timeout);  	} +	/* Waiting for the ready status */ +	if (mmc_send_status(mmc, timeout)) +		return 0; +  	return blkcnt;  } @@ -341,7 +346,6 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)  {  	struct mmc_cmd cmd;  	struct mmc_data data; -	int timeout = 1000;  	if (blkcnt > 1)  		cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; @@ -373,9 +377,6 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)  			printf("mmc fail to send stop cmd\n");  			return 0;  		} - -		/* Waiting for the ready status */ -		mmc_send_status(mmc, timeout);  	}  	return blkcnt; @@ -610,7 +611,8 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)  	ret = mmc_send_cmd(mmc, &cmd, NULL);  	/* Waiting for the ready status */ -	mmc_send_status(mmc, timeout); +	if (!ret) +		ret = mmc_send_status(mmc, timeout);  	return ret; diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index ef64e3741..2400db2f3 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -198,9 +198,10 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,  	ulong start;  	start = get_timer(0); -	while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS) { +	while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {  		if (get_timer(0) - start > MAX_RETRY_MS) { -			printf("%s: timedout waiting for cmddis!\n", __func__); +			printf("%s: timedout waiting on cmd inhibit to clear\n", +					__func__);  			return TIMEOUT;  		}  	} diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c index 3191557c5..33cc8fb80 100644 --- a/drivers/mmc/tegra2_mmc.c +++ b/drivers/mmc/tegra2_mmc.c @@ -227,16 +227,19 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,  	if (i == retry) {  		printf("%s: waiting for status update\n", __func__); +		writel(mask, &host->reg->norintsts);  		return TIMEOUT;  	}  	if (mask & TEGRA_MMC_NORINTSTS_CMD_TIMEOUT) {  		/* Timeout Error */  		debug("timeout: %08x cmd %d\n", mask, cmd->cmdidx); +		writel(mask, &host->reg->norintsts);  		return TIMEOUT;  	} else if (mask & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) {  		/* Error Interrupt */  		debug("error: %08x cmd %d\n", mask, cmd->cmdidx); +		writel(mask, &host->reg->norintsts);  		return -1;  	} @@ -265,6 +268,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,  			if (i == retry) {  				printf("%s: card is still busy\n", __func__); +				writel(mask, &host->reg->norintsts);  				return TIMEOUT;  			}  |