diff options
author | Adrian Hunter <ext-adrian.hunter@nokia.com> | 2008-08-25 05:01:31 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-09-16 03:39:01 -0400 |
commit | 8afbc114542a6810b0a2e658abda6e911121cd22 (patch) | |
tree | b88ecd5179b047b7f95a7895d88a0061326bf621 /drivers/mtd/onenand | |
parent | 34f6e15786293e8d6ed05f9c19ed784ff15d2702 (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.c | 26 |
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 | ||