Commit d9098ee55f6cf6f51e2fbed0336957e2b7156225

Authored by Ladislav Michl
Committed by Tom Rini
1 parent 9a9d394639

mtd: OneNAND: add timeout to wait ready loops

Add timeout to onenand_wait ready loop as it hangs here indefinitely
when chip not present. Once there, do the same for onenand_bbt_wait
as well (note: recent Linux driver code does the same)

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Showing 1 changed file with 19 additions and 11 deletions Side-by-side Diff

drivers/mtd/onenand/onenand_base.c
... ... @@ -20,6 +20,7 @@
20 20 */
21 21  
22 22 #include <common.h>
  23 +#include <watchdog.h>
23 24 #include <linux/compat.h>
24 25 #include <linux/mtd/mtd.h>
25 26 #include "linux/mtd/flashchip.h"
26 27  
27 28  
... ... @@ -467,15 +468,18 @@
467 468 static int onenand_wait(struct mtd_info *mtd, int state)
468 469 {
469 470 struct onenand_chip *this = mtd->priv;
470   - unsigned int flags = ONENAND_INT_MASTER;
471 471 unsigned int interrupt = 0;
472 472 unsigned int ctrl;
473 473  
474   - while (1) {
  474 + /* Wait at most 20ms ... */
  475 + u32 timeo = (CONFIG_SYS_HZ * 20) / 1000;
  476 + u32 time_start = get_timer(0);
  477 + do {
  478 + WATCHDOG_RESET();
  479 + if (get_timer(time_start) > timeo)
  480 + return -EIO;
475 481 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
476   - if (interrupt & flags)
477   - break;
478   - }
  482 + } while ((interrupt & ONENAND_INT_MASTER) == 0);
479 483  
480 484 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
481 485  
482 486  
483 487  
... ... @@ -1154,15 +1158,18 @@
1154 1158 static int onenand_bbt_wait(struct mtd_info *mtd, int state)
1155 1159 {
1156 1160 struct onenand_chip *this = mtd->priv;
1157   - unsigned int flags = ONENAND_INT_MASTER;
1158 1161 unsigned int interrupt;
1159 1162 unsigned int ctrl;
1160 1163  
1161   - while (1) {
  1164 + /* Wait at most 20ms ... */
  1165 + u32 timeo = (CONFIG_SYS_HZ * 20) / 1000;
  1166 + u32 time_start = get_timer(0);
  1167 + do {
  1168 + WATCHDOG_RESET();
  1169 + if (get_timer(time_start) > timeo)
  1170 + return ONENAND_BBT_READ_FATAL_ERROR;
1162 1171 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
1163   - if (interrupt & flags)
1164   - break;
1165   - }
  1172 + } while ((interrupt & ONENAND_INT_MASTER) == 0);
1166 1173  
1167 1174 /* To get correct interrupt status in timeout case */
1168 1175 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
... ... @@ -2536,7 +2543,8 @@
2536 2543 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
2537 2544  
2538 2545 /* Wait reset */
2539   - this->wait(mtd, FL_RESETING);
  2546 + if (this->wait(mtd, FL_RESETING))
  2547 + return -ENXIO;
2540 2548  
2541 2549 /* Restore system configuration 1 */
2542 2550 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);