[U-Boot-Users] [PATCH] Fix AT9RM9200 timer to avoid erroneous timeouts

Anders Larsen al at alarsen.net
Wed Feb 28 14:58:49 CET 2007


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 at 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)
+		;
 }
 
 /*





More information about the U-Boot mailing list