diff options
author | Adrian Hunter <ext-adrian.hunter@nokia.com> | 2008-08-25 09:01:31 (GMT) |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-09-16 07:39:01 (GMT) |
commit | 8afbc114542a6810b0a2e658abda6e911121cd22 (patch) | |
tree | b88ecd5179b047b7f95a7895d88a0061326bf621 | |
parent | 34f6e15786293e8d6ed05f9c19ed784ff15d2702 (diff) | |
download | linux-8afbc114542a6810b0a2e658abda6e911121cd22.tar.xz |
[MTD] [NAND] OMAP2: add retry after read timeout
Very occasionally, (about one in a million) read operations are
ongoing after the timeout has expired. So, retry three times
while the ongoing bit remains set.
Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r-- | drivers/mtd/onenand/omap2.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 34b4253..8387e05 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -187,16 +187,36 @@ retry: } } } else { + int retry_cnt = 0; + /* Turn interrupts off */ syscfg = read_reg(c, ONENAND_REG_SYS_CFG1); syscfg &= ~ONENAND_SYS_CFG1_IOBE; write_reg(c, syscfg, ONENAND_REG_SYS_CFG1); timeout = jiffies + msecs_to_jiffies(20); - while (time_before(jiffies, timeout)) { - intr = read_reg(c, ONENAND_REG_INTERRUPT); - if (intr & ONENAND_INT_MASTER) + while (1) { + if (time_before(jiffies, timeout)) { + intr = read_reg(c, ONENAND_REG_INTERRUPT); + if (intr & ONENAND_INT_MASTER) + break; + } else { + /* Timeout after 20ms */ + ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS); + if (ctrl & ONENAND_CTRL_ONGO) { + /* + * The operation seems to be still going + * so give it some more time. + */ + retry_cnt += 1; + if (retry_cnt < 3) { + timeout = jiffies + + msecs_to_jiffies(20); + continue; + } + } break; + } } } |