aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand
diff options
context:
space:
mode:
authorAdrian Hunter <ext-adrian.hunter@nokia.com>2008-08-25 05:01:31 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-09-16 03:39:01 -0400
commit8afbc114542a6810b0a2e658abda6e911121cd22 (patch)
treeb88ecd5179b047b7f95a7895d88a0061326bf621 /drivers/mtd/onenand
parent34f6e15786293e8d6ed05f9c19ed784ff15d2702 (diff)
[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')
-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 34b42533f4bb..8387e05daae2 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -187,16 +187,36 @@ retry:
187 } 187 }
188 } 188 }
189 } else { 189 } else {
190 int retry_cnt = 0;
191
190 /* Turn interrupts off */ 192 /* Turn interrupts off */
191 syscfg = read_reg(c, ONENAND_REG_SYS_CFG1); 193 syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
192 syscfg &= ~ONENAND_SYS_CFG1_IOBE; 194 syscfg &= ~ONENAND_SYS_CFG1_IOBE;
193 write_reg(c, syscfg, ONENAND_REG_SYS_CFG1); 195 write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
194 196
195 timeout = jiffies + msecs_to_jiffies(20); 197 timeout = jiffies + msecs_to_jiffies(20);
196 while (time_before(jiffies, timeout)) { 198 while (1) {
197 intr = read_reg(c, ONENAND_REG_INTERRUPT); 199 if (time_before(jiffies, timeout)) {
198 if (intr & ONENAND_INT_MASTER) 200 intr = read_reg(c, ONENAND_REG_INTERRUPT);
201 if (intr & ONENAND_INT_MASTER)
202 break;
203 } else {
204 /* Timeout after 20ms */
205 ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
206 if (ctrl & ONENAND_CTRL_ONGO) {
207 /*
208 * The operation seems to be still going
209 * so give it some more time.
210 */
211 retry_cnt += 1;
212 if (retry_cnt < 3) {
213 timeout = jiffies +
214 msecs_to_jiffies(20);
215 continue;
216 }
217 }
199 break; 218 break;
219 }
200 } 220 }
201 } 221 }
202 222