patch-2.4.22 linux-2.4.22/include/asm-arm/delay.h

Next file: linux-2.4.22/include/asm-arm/dma.h
Previous file: linux-2.4.22/include/asm-arm/cpu-single.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/include/asm-arm/delay.h linux-2.4.22/include/asm-arm/delay.h
@@ -1,32 +1,66 @@
+/*
+ *  linux/include/asm-arm/delay.h
+ *
+ *  Copyright (C) 1995-2003 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Delay routines, using a pre-computed "loops_per_second" value.
+ */
 #ifndef __ASM_ARM_DELAY_H
 #define __ASM_ARM_DELAY_H
 
 /*
- * Copyright (C) 1995 Russell King
+ * Division by multiplication and shifts.
+ *
+ *  We want the number of loops to complete, where loops is:
+ *      (us * (HZ * loops_per_jiffy)) / 10^6
+ *  or
+ *      (ns * (HZ * loops_per_jiffy)) / 10^9
+ *
+ *  Since we don't want to do long division, we multiply both numerator
+ *  and denominator by (2^28 / 10^6):
  *
- * Delay routines, using a pre-computed "loops_per_second" value.
+ *      (us * (2^28 / 10^6) * HZ * loops_per_jiffy) / 2^28
+ *
+ *  =>  (us * (2^28 * HZ / 10^6) * loops_per_jiffy) / 2^28
+ *
+ *  ~>  (((us * (2^28 * HZ / 10^6)) / 2^11) * (loops_per_jiffy / 2^12)) / 2^5
+ *         (for large loops_per_jiffy >> 2^12)
+ *
+ *  Note: maximum loops_per_jiffy = 67108863 (bogomips = 1342.18)
+ *        minimum loops_per_jiffy = 20000 (bogomips = 0.4)
+ *
+ * Note: we rely on HZ = 100.
  */
+#define UDELAY_FACTOR	26843
+#define NDELAY_FACTOR	27
 
-extern void __delay(int loops);
+#ifndef __ASSEMBLY__
 
-/*
- * division by multiplication: you don't have to worry about
- * loss of precision.
- *
- * Use only for very small delays ( < 1 msec).  Should probably use a
- * lookup table, really, as the multiplications take much too long with
- * short delays.  This is a "reasonable" implementation, though (and the
- * first constant multiplications gets optimized away if the delay is
- * a constant)
- */
-extern void udelay(unsigned long usecs);
+extern void __bad_udelay(void);	/* intentional errors */
+extern void __bad_ndelay(void);	/* intentional errors */
 
-static inline unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
-{
-	return a * b / c;
-}
+extern void __delay(unsigned long loops);
+extern void __udelay(unsigned long usecs);
+extern void __ndelay(unsigned long nsecs);
+extern void __const_delay(unsigned long units);
+
+#define udelay(n) 							\
+	(__builtin_constant_p(n) ?					\
+		((n) > 20000 ? __bad_udelay()				\
+			     : __const_delay((n) * UDELAY_FACTOR))	\
+				 : __udelay(n))
+
+#define ndelay(n) 							\
+	(__builtin_constant_p(n) ?					\
+		((n) > 20000 ? __bad_ndelay()				\
+			     : __const_delay((n) * NDELAY_FACTOR))	\
+				 : __ndelay(n))
 
-	
+#endif
 
 #endif /* defined(_ARM_DELAY_H) */
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)