
Hi,
the timeout handling in e.g. drivers/cfi_flash.c assumes that get_timer() increments to 0xffffffff, then starts from 0 again.
The implementation in cpu/arm920t/at91rm9200/interrupts.c acts differently - it only increments to 0xffffffff/TIMER_LOAD_VAL, thereby wrapping too early (every couple of minutes). Now and again this causes e.g. flash_status_check() to erroneously report a timeout. The patch below fixes this (this time with patch appended, sorry)
Cheers Anders
CHANGELOG: fixed get_tiner() & friends to correctly return a full 32-bit ms value (the previous implementation wrapped every couple of minutes, in turn causing the flash write functions to erroneously report a timeout) Patch by Anders Larsen, 28 Feb 2007
Signed-off-by: Anders Larsen al@alarsen.net
---
cpu/arm920t/at91rm9200/interrupts.c | 37 +++++++++-------------------------- 1 files changed, 9 insertions(+), 28 deletions(-)
diff --git a/cpu/arm920t/at91rm9200/interrupts.c b/cpu/arm920t/at91rm9200/interrupts.c index 1054602..11c59a5 100644 --- a/cpu/arm920t/at91rm9200/interrupts.c +++ b/cpu/arm920t/at91rm9200/interrupts.c @@ -99,43 +99,24 @@ void reset_timer_masked (void) timestamp = 0; }
-ulong get_timer_raw (void) +ulong get_timer_masked (void) { ulong now = READ_TIMER; - - if (now >= lastinc) { - /* normal mode */ - timestamp += now - lastinc; - } else { - /* we have an overflow ... */ - timestamp += now + TIMER_LOAD_VAL - lastinc; - } + if (now < lastinc) + timestamp++; lastinc = now; - return timestamp; }
-ulong get_timer_masked (void) -{ - return get_timer_raw()/TIMER_LOAD_VAL; -} - void udelay_masked (unsigned long usec) { - ulong tmo; - ulong endtime; - signed long diff; - - tmo = CFG_HZ_CLOCK / 1000; - tmo *= usec; - tmo /= 1000; - - endtime = get_timer_raw () + tmo; + ulong start = get_timer(0); + ulong end;
- do { - ulong now = get_timer_raw (); - diff = endtime - now; - } while (diff >= 0); + /* Only 1ms resolution :-( */ + end = usec / 1000; + while (get_timer(start) < end) + ; }
/*