diff options
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 | ||