Fix timer code for ARM systems: make sure that udelay() does not
reset timers so it's save to use udelay() in timeout code.
diff --git a/CHANGELOG b/CHANGELOG
index 73fb943..ba250b6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,9 @@
 Changes for U-Boot 1.1.3:
 ======================================================================
 
+* Fix timer code for ARM systems: make sure that udelay() does not
+  reset timers so it's save to use udelay() in timeout code.
+
 * Patch by Mathias Küster, 23 Nov 2004:
   add udelay support for the mcf5282 cpu
 
diff --git a/cpu/arm1136/interrupts.c b/cpu/arm1136/interrupts.c
index c80d9a5..23236dc 100644
--- a/cpu/arm1136/interrupts.c
+++ b/cpu/arm1136/interrupts.c
@@ -254,6 +254,8 @@
 void udelay_masked (unsigned long usec)
 {
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
 	if (usec >= 1000) {			/* if "big" number, spread normalization to seconds */
 		tmo = usec / 1000;		/* start to normalize for usec to ticks per sec */
@@ -263,9 +265,12 @@
 		tmo = usec * CFG_HZ;
 		tmo /= (1000*1000);
 	}
-	reset_timer_masked ();		/* set "advancing" timestamp to 0, set lastinc vaule */
-	while (get_timer_masked () < tmo) /* wait for time stamp to overtake tick number.*/
-		/* NOP */;
+	endtime = get_timer_masked () + tmo;
+
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
 
 /*
diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c
index a7ea70a..ab28e60 100644
--- a/cpu/arm720t/interrupts.c
+++ b/cpu/arm720t/interrupts.c
@@ -358,15 +358,24 @@
 void udelay_masked (unsigned long usec)
 {
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
-	tmo = usec / 1000;
-	tmo *= CFG_HZ;
-	tmo /= 1000;
+	if (usec >= 1000) {
+		tmo = usec / 1000;
+		tmo *= CFG_HZ;
+		tmo /= 1000;
+	} else {
+		tmo = usec * CFG_HZ;
+		tmo /= (1000*1000);
+	}
 
-	reset_timer_masked ();
+	endtime = get_timer_masked () + tmo;
 
-	while (get_timer_masked () < tmo)
-		/*NOP*/;
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
 
 #elif defined(CONFIG_S3C4510B)
diff --git a/cpu/arm920t/imx/interrupts.c b/cpu/arm920t/imx/interrupts.c
index 12ae2fa..2f2e754 100644
--- a/cpu/arm920t/imx/interrupts.c
+++ b/cpu/arm920t/imx/interrupts.c
@@ -81,10 +81,13 @@
 
 void udelay_masked (unsigned long usec)
 {
-	ulong start = get_timer_masked();
+	ulong endtime = get_timer_masked() + usec;
+	signed long diff;
 
-	while (get_timer_masked () - start < usec )
-		/*NOP*/;
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
 
 void udelay (unsigned long usec)
diff --git a/cpu/arm920t/s3c24x0/interrupts.c b/cpu/arm920t/s3c24x0/interrupts.c
index f581d6d..868621f 100644
--- a/cpu/arm920t/s3c24x0/interrupts.c
+++ b/cpu/arm920t/s3c24x0/interrupts.c
@@ -137,15 +137,24 @@
 void udelay_masked (unsigned long usec)
 {
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
-	tmo = usec / 1000;
-	tmo *= (timer_load_val * 100);
-	tmo /= 1000;
+	if (usec >= 1000) {
+		tmo = usec / 1000;
+		tmo *= (timer_load_val * 100);
+		tmo /= 1000;
+	} else {
+		tmo = usec * (timer_load_val * 100);
+		tmo /= (1000*1000);
+	}
 
-	reset_timer_masked ();
+	endtime = get_timer_masked () + tmo;
 
-	while (get_timer_masked () < tmo)
-		/*NOP*/;
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
 
 /*
diff --git a/cpu/arm925t/interrupts.c b/cpu/arm925t/interrupts.c
index ea4aa3b..57bb4ea 100644
--- a/cpu/arm925t/interrupts.c
+++ b/cpu/arm925t/interrupts.c
@@ -275,20 +275,24 @@
 #else
 
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
-	if(usec >= 1000){		/* if "big" number, spread normalization to seconds */
+	if (usec >= 1000) {		/* if "big" number, spread normalization to seconds */
 		tmo = usec / 1000;	/* start to normalize for usec to ticks per sec */
 		tmo *= CFG_HZ;		/* find number of "ticks" to wait to achieve target */
 		tmo /= 1000;		/* finish normalize. */
-	}else{				/* else small number, don't kill it prior to HZ multiply */
+	} else {			/* else small number, don't kill it prior to HZ multiply */
 		tmo = usec * CFG_HZ;
 		tmo /= (1000*1000);
 	}
 
-	reset_timer_masked ();	/* set "advancing" timestamp to 0, set lastdec vaule */
+	endtime = get_timer_masked () + tmo;
 
-	while (get_timer_masked () < tmo) /* wait for time stamp to overtake tick number.*/
-		/*NOP*/;
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 #endif
 }
 
diff --git a/cpu/arm926ejs/interrupts.c b/cpu/arm926ejs/interrupts.c
index 062515e..ae8082d 100644
--- a/cpu/arm926ejs/interrupts.c
+++ b/cpu/arm926ejs/interrupts.c
@@ -26,7 +26,7 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
@@ -116,15 +116,15 @@
 
 	flags = condition_codes (regs);
 
-	printf ("pc : [<%08lx>]    lr : [<%08lx>]\n"
-		"sp : %08lx  ip : %08lx  fp : %08lx\n",
+	printf ("pc : [<%08lx>]	   lr : [<%08lx>]\n"
+		"sp : %08lx  ip : %08lx	 fp : %08lx\n",
 		instruction_pointer (regs),
 		regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
-	printf ("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
+	printf ("r10: %08lx  r9 : %08lx	 r8 : %08lx\n",
 		regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
-	printf ("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
+	printf ("r7 : %08lx  r6 : %08lx	 r5 : %08lx  r4 : %08lx\n",
 		regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
-	printf ("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
+	printf ("r3 : %08lx  r2 : %08lx	 r1 : %08lx  r0 : %08lx\n",
 		regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
 	printf ("Flags: %c%c%c%c",
 		flags & CC_N_BIT ? 'N' : 'n',
@@ -242,17 +242,17 @@
 {
 	ulong tmo, tmp;
 
-	if(usec >= 1000){               /* if "big" number, spread normalization to seconds */
-		tmo = usec / 1000;      /* start to normalize for usec to ticks per sec */
-		tmo *= CFG_HZ;          /* find number of "ticks" to wait to achieve target */
-		tmo /= 1000;            /* finish normalize. */
-	}else{                          /* else small number, don't kill it prior to HZ multiply */
+	if(usec >= 1000){		/* if "big" number, spread normalization to seconds */
+		tmo = usec / 1000;	/* start to normalize for usec to ticks per sec */
+		tmo *= CFG_HZ;		/* find number of "ticks" to wait to achieve target */
+		tmo /= 1000;		/* finish normalize. */
+	}else{				/* else small number, don't kill it prior to HZ multiply */
 		tmo = usec * CFG_HZ;
 		tmo /= (1000*1000);
 	}
 
 	tmp = get_timer (0);		/* get current timestamp */
-	if( (tmo + tmp + 1) < tmp ) 	/* if setting this fordward will roll time stamp */
+	if( (tmo + tmp + 1) < tmp )	/* if setting this fordward will roll time stamp */
 		reset_timer_masked ();	/* reset "advancing" timestamp to 0, set lastdec value */
 	else
 		tmo += tmp;		/* else, set advancing stamp wake up time */
@@ -265,7 +265,7 @@
 {
 	/* reset time */
 	lastdec = READ_TIMER;  /* capure current decrementer value time */
-	timestamp = 0;         /* start "advancing" time stamp from 0 */
+	timestamp = 0;	       /* start "advancing" time stamp from 0 */
 }
 
 ulong get_timer_masked (void)
@@ -292,20 +292,24 @@
 void udelay_masked (unsigned long usec)
 {
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
-	if(usec >= 1000){               /* if "big" number, spread normalization to seconds */
-		tmo = usec / 1000;      /* start to normalize for usec to ticks per sec */
-		tmo *= CFG_HZ;          /* find number of "ticks" to wait to achieve target */
-		tmo /= 1000;            /* finish normalize. */
-	}else{                          /* else small number, don't kill it prior to HZ multiply */
+	if (usec >= 1000) {		/* if "big" number, spread normalization to seconds */
+		tmo = usec / 1000;	/* start to normalize for usec to ticks per sec */
+		tmo *= CFG_HZ;		/* find number of "ticks" to wait to achieve target */
+		tmo /= 1000;		/* finish normalize. */
+	} else {			/* else small number, don't kill it prior to HZ multiply */
 		tmo = usec * CFG_HZ;
 		tmo /= (1000*1000);
 	}
 
-	reset_timer_masked ();	/* set "advancing" timestamp to 0, set lastdec vaule */
+	endtime = get_timer_masked () + tmo;
 
-	while (get_timer_masked () < tmo) /* wait for time stamp to overtake tick number.*/
-		/*NOP*/;
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
 
 /*
diff --git a/cpu/at91rm9200/interrupts.c b/cpu/at91rm9200/interrupts.c
index f15c583..cccc405 100644
--- a/cpu/at91rm9200/interrupts.c
+++ b/cpu/at91rm9200/interrupts.c
@@ -231,20 +231,19 @@
 void udelay_masked (unsigned long usec)
 {
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
-#if 0 /* doesn't work for usec < 1000 */
-	tmo = usec / 1000;
-	tmo *= CFG_HZ_CLOCK;
-#else
 	tmo = CFG_HZ_CLOCK / 1000;
 	tmo *= usec;
-#endif
 	tmo /= 1000;
 
-	reset_timer_masked ();
+	endtime = get_timer_raw () + tmo;
 
-	while (get_timer_raw () < tmo)
-		/*NOP*/;
+	do {
+		ulong now = get_timer_raw ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
 
 /*
diff --git a/cpu/at91rm9200/start.S b/cpu/at91rm9200/start.S
index e897e6b..1881ab1 100644
--- a/cpu/at91rm9200/start.S
+++ b/cpu/at91rm9200/start.S
@@ -117,11 +117,11 @@
 
 #ifdef CONFIG_INIT_CRITICAL
 	/* scratch stack */
-	ldr 	r1, =0x00204000
+/****	ldr 	r1, =0x00204000		****/
 	/* Insure word alignment */
-	bic     r1, r1, #3
+/****	bic     r1, r1, #3		****/
 	/* Init stack SYS	 */
-	mov     sp, r1
+/****	mov     sp, r1			****/
 	/*
 	 * This does a lot more than just set up the memory, which
 	 * is why it's called lowlevelinit
diff --git a/cpu/lh7a40x/interrupts.c b/cpu/lh7a40x/interrupts.c
index 3c2dc4f..23d8039 100644
--- a/cpu/lh7a40x/interrupts.c
+++ b/cpu/lh7a40x/interrupts.c
@@ -281,25 +281,29 @@
 void udelay_masked (unsigned long usec)
 {
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
 	/* normalize */
 	if (usec >= 1000) {
 		tmo = usec / 1000;
 		tmo *= CFG_HZ;
 		tmo /= 1000;
-	}
-	else {
+	} else {
 		if (usec > 1) {
 			tmo = usec * CFG_HZ;
 			tmo /= (1000*1000);
-		}
-		else
+		} else {
 			tmo = 1;
+		}
 	}
 
-	reset_timer_masked ();
+	endtime = get_timer_masked () + tmo;
 
-	while (get_timer_masked () < tmo);
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
 
 /*
diff --git a/cpu/pxa/interrupts.c b/cpu/pxa/interrupts.c
index b335a82..0479a10 100644
--- a/cpu/pxa/interrupts.c
+++ b/cpu/pxa/interrupts.c
@@ -190,6 +190,8 @@
 void udelay_masked (unsigned long usec)
 {
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
 	if (usec >= 1000) {
 		tmo = usec / 1000;
@@ -200,10 +202,12 @@
 		tmo /= (1000*1000);
 	}
 
-	reset_timer_masked ();
+	endtime = get_timer_masked () + tmo;
 
-	while (tmo >= get_timer_masked ())
-		/*NOP*/;
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
 
 /*
diff --git a/cpu/s3c44b0/interrupts.c b/cpu/s3c44b0/interrupts.c
index dea8118..5d2c13d 100644
--- a/cpu/s3c44b0/interrupts.c
+++ b/cpu/s3c44b0/interrupts.c
@@ -219,15 +219,22 @@
 void udelay_masked (unsigned long usec)
 {
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
-	tmo = usec / 1000;
-	tmo *= CFG_HZ;
-	tmo /= 8;
+	if (usec >= 1000) {
+		tmo = usec / 1000;
+		tmo *= CFG_HZ;
+		tmo /= 8;
+	} else {
+		tmo = usec * CFG_HZ;
+		tmo /= (1000*8);
+	}
 
-	tmo += get_timer (0);
+	endtime = get_timer(0) + tmo;
 
-	reset_timer_masked ();
-
-	while (get_timer_masked () < tmo)
-		/*NOP*/;
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
diff --git a/cpu/sa1100/interrupts.c b/cpu/sa1100/interrupts.c
index 93a78d7..b393e0d 100644
--- a/cpu/sa1100/interrupts.c
+++ b/cpu/sa1100/interrupts.c
@@ -206,15 +206,24 @@
 void udelay_masked (unsigned long usec)
 {
 	ulong tmo;
+	ulong endtime;
+	signed long diff;
 
-	tmo = usec / 1000;
-	tmo *= CFG_HZ;
-	tmo /= 1000;
+	if (usec >= 1000) {
+		tmo = usec / 1000;
+		tmo *= CFG_HZ;
+		tmo /= 1000;
+	} else {
+		tmo = usec * CFG_HZ;
+		tmo /= (1000*1000);
+	}
 
-	reset_timer_masked ();
+	endtime = get_timer_masked () + tmo;
 
-	while (tmo >= get_timer_masked ())
-		/*NOP*/;
+	do {
+		ulong now = get_timer_masked ();
+		diff = endtime - now;
+	} while (diff >= 0);
 }
 
 /*
diff --git a/include/configs/cmc_pu2.h b/include/configs/cmc_pu2.h
index ef2d1b7..96b7148 100644
--- a/include/configs/cmc_pu2.h
+++ b/include/configs/cmc_pu2.h
@@ -33,7 +33,7 @@
 
 /* ARM asynchronous clock */
 #define AT91C_MAIN_CLOCK	207360000	/* from 18.432 MHz crystal (18432000 / 4 * 45) */
-#define AT91C_MASTER_CLOCK	69120000	/* peripheral clock (AT91C_MASTER_CLOCK / 3) */
+#define AT91C_MASTER_CLOCK	(AT91C_MAIN_CLOCK/3)	/* peripheral clock */
 
 #define AT91_SLOW_CLOCK		32768	/* slow clock */
 
@@ -203,7 +203,7 @@
 #endif	/* __ASSEMBLY__ */
 
 #define CFG_HZ 1000
-#define CFG_HZ_CLOCK AT91C_MASTER_CLOCK/2	/* AT91C_TC0_CMR is implicitly set to */
+#define CFG_HZ_CLOCK (AT91C_MASTER_CLOCK/2)	/* AT91C_TC0_CMR is implicitly set to */
 						/* AT91C_TC_TIMER_DIV1_CLOCK */
 
 #define CONFIG_STACKSIZE	(32*1024)	/* regular stack */