Fix erase timeout in M25P80 driver
PATCH 1/1 Fix erase timeout in M25P80 driver
The M25P80 driver erase operations timeout when using a M25P128 part with a Marvell Kirkwood (ARM) processor. Change the timeout from a simple loop count to a time based timeout. Also added a conditional schedule() in the loop.
drivers/mtd/devices/m25p80.c +12 -6
@@ -54,7 +54,7 @@#define SR_SRWD 0x80/* SR write protect */ /* Define max times to check status register before we give up. */ -#define MAX_READY_WAIT_COUNT 100000 +#define MAX_READY_WAIT_TIMEOUT 7000/* ms - M25P128 max is 6s */ #define CMD_SIZE 4#ifdef CONFIG_M25PXX_USE_FAST_READ
@@ -145,19 +145,25 @@*/ static int wait_till_ready (struct m25p *flash) { -int count; +# define DIV_U (n,d) (((n)+(d)-1)/(d)) + +unsigned long deadline;int sr; -/* one chip guarantees max 5 msec wait here after page writes, -* but potentially three seconds (!) after page erase. + deadline = jiffies +DIV_U (MAX_READY_WAIT_TIMEOUT *HZ ,1000 ); + +/* this can take a long time for sector erase. +* we should probably have a separate timeout +* for program and erase and we should check +* for signals ... */ -for (count =0 ; count <MAX_READY_WAIT_COUNT ; count++) { +while (!time_after_eq (jiffies, deadline)) {if ((sr =read_sr (flash)) <0 )break ;else if (!(sr &SR_WIP ))return 0 ; -/* REVISIT sometimes sleeping would be best */ +cond_resched (); }return 1 ;
Quoted 11 lines · Peter Horton
static int
wait_till_ready(struct m25p *flash)
{
- int count;drivers/mtd/devices/m25p80.c +3
-0+# define DIV_U(n,d) (((n)+(d)-1)/(d)) + + unsigned long deadline;int sr;
- /* one chip guarantees max 5 msec wait here after page writes,
- * but potentially three seconds (!) after page erase.
+ deadline = jiffies +DIV_U(MAX_READY_WAIT_TIMEOUT * HZ, 1000);
there's already a macro for working with jiffies and time. dont start writing yet another one with its own ugly magic. just look in linux/jiffies.h.
Quoted 4 lines
+ /* this can take a long time for sector erase.
+ * we should probably have a separate timeout
+ * for program and erase and we should check
+ * for signals ...
timeouts only occur when there's a problem. a problematic system is not normal, so having longer (and common) timeouts is fine because they should never be reached.
-mike