[U-Boot] [PATCH] mmc: fsl_esdhc: add controller reset in case of data related errors too
Andrew Gabbasov
andrew_gabbasov at mentor.com
Mon Mar 24 08:41:06 CET 2014
The controller reset is performed now if command error occurs.
This commit adds the reset for the case of data related errors too.
Signed-off-by: Andrew Gabbasov <andrew_gabbasov at mentor.com>
---
drivers/mmc/fsl_esdhc.c | 63 +++++++++++++++++++++++++++--------------------
1 file changed, 36 insertions(+), 27 deletions(-)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index f4d3132..dfb1cc3 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -265,6 +265,7 @@ static void check_and_invalidate_dcache_range
static int
esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
{
+ int err = 0;
uint xfertyp;
uint irqstat;
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
@@ -296,8 +297,6 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
/* Set up for a data transfer if we have one */
if (data) {
- int err;
-
err = esdhc_setup_data(mmc, data);
if(err)
return err;
@@ -325,27 +324,15 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
irqstat = esdhc_read32(®s->irqstat);
- /* Reset CMD and DATA portions on error */
- if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) {
- esdhc_write32(®s->sysctl, esdhc_read32(®s->sysctl) |
- SYSCTL_RSTC);
- while (esdhc_read32(®s->sysctl) & SYSCTL_RSTC)
- ;
-
- if (data) {
- esdhc_write32(®s->sysctl,
- esdhc_read32(®s->sysctl) |
- SYSCTL_RSTD);
- while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTD))
- ;
- }
+ if (irqstat & CMD_ERR) {
+ err = COMM_ERR;
+ goto out;
}
- if (irqstat & CMD_ERR)
- return COMM_ERR;
-
- if (irqstat & IRQSTAT_CTOE)
- return TIMEOUT;
+ if (irqstat & IRQSTAT_CTOE) {
+ err = TIMEOUT;
+ goto out;
+ }
/* Workaround for ESDHC errata ENGcm03648 */
if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
@@ -360,7 +347,8 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
if (timeout <= 0) {
printf("Timeout waiting for DAT0 to go high!\n");
- return TIMEOUT;
+ err = TIMEOUT;
+ goto out;
}
}
@@ -387,20 +375,41 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
do {
irqstat = esdhc_read32(®s->irqstat);
- if (irqstat & IRQSTAT_DTOE)
- return TIMEOUT;
+ if (irqstat & IRQSTAT_DTOE) {
+ err = TIMEOUT;
+ goto out;
+ }
- if (irqstat & DATA_ERR)
- return COMM_ERR;
+ if (irqstat & DATA_ERR) {
+ err = COMM_ERR;
+ goto out;
+ }
} while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
#endif
if (data->flags & MMC_DATA_READ)
check_and_invalidate_dcache_range(cmd, data);
}
+out:
+ /* Reset CMD and DATA portions on error */
+ if (err) {
+ esdhc_write32(®s->sysctl, esdhc_read32(®s->sysctl) |
+ SYSCTL_RSTC);
+ while (esdhc_read32(®s->sysctl) & SYSCTL_RSTC)
+ ;
+
+ if (data) {
+ esdhc_write32(®s->sysctl,
+ esdhc_read32(®s->sysctl) |
+ SYSCTL_RSTD);
+ while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTD))
+ ;
+ }
+ }
+
esdhc_write32(®s->irqstat, -1);
- return 0;
+ return err;
}
static void set_sysctl(struct mmc *mmc, uint clock)
--
1.7.10.4
More information about the U-Boot
mailing list