Commit 8a573022c38da9ecc749acbc60556a8e8bd41996

Authored by Andrew Gabbasov
Committed by Pantelis Antoniou
1 parent fb823981c5

mmc: fsl_esdhc: add controller reset in case of data related errors too

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@mentor.com>
Acked-by: Pantelis Antoniou <panto@antoniou-consulting.com>

Showing 1 changed file with 36 additions and 27 deletions Side-by-side Diff

drivers/mmc/fsl_esdhc.c
... ... @@ -265,6 +265,7 @@
265 265 static int
266 266 esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
267 267 {
  268 + int err = 0;
268 269 uint xfertyp;
269 270 uint irqstat;
270 271 struct fsl_esdhc_cfg *cfg = mmc->priv;
... ... @@ -296,8 +297,6 @@
296 297  
297 298 /* Set up for a data transfer if we have one */
298 299 if (data) {
299   - int err;
300   -
301 300 err = esdhc_setup_data(mmc, data);
302 301 if(err)
303 302 return err;
304 303  
305 304  
... ... @@ -325,28 +324,16 @@
325 324  
326 325 irqstat = esdhc_read32(&regs->irqstat);
327 326  
328   - /* Reset CMD and DATA portions on error */
329   - if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) {
330   - esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
331   - SYSCTL_RSTC);
332   - while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
333   - ;
  327 + if (irqstat & CMD_ERR) {
  328 + err = COMM_ERR;
  329 + goto out;
  330 + }
334 331  
335   - if (data) {
336   - esdhc_write32(&regs->sysctl,
337   - esdhc_read32(&regs->sysctl) |
338   - SYSCTL_RSTD);
339   - while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
340   - ;
341   - }
  332 + if (irqstat & IRQSTAT_CTOE) {
  333 + err = TIMEOUT;
  334 + goto out;
342 335 }
343 336  
344   - if (irqstat & CMD_ERR)
345   - return COMM_ERR;
346   -
347   - if (irqstat & IRQSTAT_CTOE)
348   - return TIMEOUT;
349   -
350 337 /* Workaround for ESDHC errata ENGcm03648 */
351 338 if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
352 339 int timeout = 2500;
... ... @@ -360,7 +347,8 @@
360 347  
361 348 if (timeout <= 0) {
362 349 printf("Timeout waiting for DAT0 to go high!\n");
363   - return TIMEOUT;
  350 + err = TIMEOUT;
  351 + goto out;
364 352 }
365 353 }
366 354  
367 355  
368 356  
369 357  
... ... @@ -387,20 +375,41 @@
387 375 do {
388 376 irqstat = esdhc_read32(&regs->irqstat);
389 377  
390   - if (irqstat & IRQSTAT_DTOE)
391   - return TIMEOUT;
  378 + if (irqstat & IRQSTAT_DTOE) {
  379 + err = TIMEOUT;
  380 + goto out;
  381 + }
392 382  
393   - if (irqstat & DATA_ERR)
394   - return COMM_ERR;
  383 + if (irqstat & DATA_ERR) {
  384 + err = COMM_ERR;
  385 + goto out;
  386 + }
395 387 } while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
396 388 #endif
397 389 if (data->flags & MMC_DATA_READ)
398 390 check_and_invalidate_dcache_range(cmd, data);
399 391 }
400 392  
  393 +out:
  394 + /* Reset CMD and DATA portions on error */
  395 + if (err) {
  396 + esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
  397 + SYSCTL_RSTC);
  398 + while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
  399 + ;
  400 +
  401 + if (data) {
  402 + esdhc_write32(&regs->sysctl,
  403 + esdhc_read32(&regs->sysctl) |
  404 + SYSCTL_RSTD);
  405 + while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
  406 + ;
  407 + }
  408 + }
  409 +
401 410 esdhc_write32(&regs->irqstat, -1);
402 411  
403   - return 0;
  412 + return err;
404 413 }
405 414  
406 415 static void set_sysctl(struct mmc *mmc, uint clock)