Commit 8a573022c38da9ecc749acbc60556a8e8bd41996
Committed by
Pantelis Antoniou
1 parent
fb823981c5
Exists in
v2017.01-smarct4x
and in
48 other branches
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(®s->irqstat); |
327 | 326 | |
328 | - /* Reset CMD and DATA portions on error */ | |
329 | - if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) { | |
330 | - esdhc_write32(®s->sysctl, esdhc_read32(®s->sysctl) | | |
331 | - SYSCTL_RSTC); | |
332 | - while (esdhc_read32(®s->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(®s->sysctl, | |
337 | - esdhc_read32(®s->sysctl) | | |
338 | - SYSCTL_RSTD); | |
339 | - while ((esdhc_read32(®s->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(®s->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(®s->sysctl, esdhc_read32(®s->sysctl) | | |
397 | + SYSCTL_RSTC); | |
398 | + while (esdhc_read32(®s->sysctl) & SYSCTL_RSTC) | |
399 | + ; | |
400 | + | |
401 | + if (data) { | |
402 | + esdhc_write32(®s->sysctl, | |
403 | + esdhc_read32(®s->sysctl) | | |
404 | + SYSCTL_RSTD); | |
405 | + while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTD)) | |
406 | + ; | |
407 | + } | |
408 | + } | |
409 | + | |
401 | 410 | esdhc_write32(®s->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) |