aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand/omap2.c
diff options
context:
space:
mode:
authorAdrian Hunter <ext-adrian.hunter@nokia.com>2008-08-25 12:01:31 +0300
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-09-16 00:39:01 -0700
commit8afbc114542a6810b0a2e658abda6e911121cd22 (patch)
treeb88ecd5179b047b7f95a7895d88a0061326bf621 /drivers/mtd/onenand/omap2.c
parent34f6e15786293e8d6ed05f9c19ed784ff15d2702 (diff)
downloadkernel_samsung_smdk4412-8afbc114542a6810b0a2e658abda6e911121cd22.zip
kernel_samsung_smdk4412-8afbc114542a6810b0a2e658abda6e911121cd22.tar.gz
kernel_samsung_smdk4412-8afbc114542a6810b0a2e658abda6e911121cd22.tar.bz2
[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>
Diffstat (limited to 'drivers/mtd/onenand/omap2.c')
-rw-r--r--drivers/mtd/onenand/omap2.c26
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;
+ }
}
}