]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
powerpc: Fix delay functions for 601 processors
authorPaul Mackerras <paulus@samba.org>
Fri, 18 Nov 2005 02:44:17 +0000 (13:44 +1100)
committerPaul Mackerras <paulus@samba.org>
Fri, 18 Nov 2005 03:08:12 +0000 (14:08 +1100)
My earlier merge of delay.h introduced a timebase-based udelay for
32-bit machines but also broke the 601, which doesn't have the
timebase register.  This fixes it by using the 601's RTC register on
the 601, and also moves __delay() and udelay() to be out-of-line in
arch/powerpc/kernel/time.c.  These functions aren't really performance
critical, after all.

Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/time.c
include/asm-powerpc/delay.h

index f6d84a75ed266bbc2042da47f0c887f59796604b..624a983a9676776fc6e7b7a05cd8c50297efee2b 100644 (file)
 
        .text
 
-       .align  5
-_GLOBAL(__delay)
-       cmpwi   0,r3,0
-       mtctr   r3
-       beqlr
-1:     bdnz    1b
-       blr
-
 /*
  * This returns the high 64 bits of the product of two 64-bit numbers.
  */
index 070b4b458aafe73f9de49d0005ab23d6484fefc6..de8479769bb729cf3068e42d7b1488b462c0ff68 100644 (file)
@@ -130,6 +130,34 @@ unsigned long tb_last_stamp;
  */
 DEFINE_PER_CPU(unsigned long, last_jiffy);
 
+void __delay(unsigned long loops)
+{
+       unsigned long start;
+       int diff;
+
+       if (__USE_RTC()) {
+               start = get_rtcl();
+               do {
+                       /* the RTCL register wraps at 1000000000 */
+                       diff = get_rtcl() - start;
+                       if (diff < 0)
+                               diff += 1000000000;
+               } while (diff < loops);
+       } else {
+               start = get_tbl();
+               while (get_tbl() - start < loops)
+                       HMT_low();
+               HMT_medium();
+       }
+}
+EXPORT_SYMBOL(__delay);
+
+void udelay(unsigned long usecs)
+{
+       __delay(tb_ticks_per_usec * usecs);
+}
+EXPORT_SYMBOL(udelay);
+
 static __inline__ void timer_check_rtc(void)
 {
         /*
index 1492aa9ab716414aa98b17dec31f5840e0a37b02..54fe1f4f8fd069bdaa121aa6bd90e7e855f2e8eb 100644 (file)
  * Anton Blanchard.
  */
 
-extern unsigned long tb_ticks_per_usec;
-
-#ifdef CONFIG_PPC64
-/* define these here to prevent circular dependencies */
-/* these instructions control the thread priority on multi-threaded cpus */
-#define __HMT_low()    asm volatile("or 1,1,1")
-#define __HMT_medium() asm volatile("or 2,2,2")
-#else
-#define __HMT_low()
-#define __HMT_medium()
-#endif
-
-#define __barrier()    asm volatile("" ::: "memory")
-
-static inline unsigned long __get_tb(void)
-{
-       unsigned long rval;
-
-       asm volatile("mftb %0" : "=r" (rval));
-       return rval;
-}
-
-static inline void __delay(unsigned long loops)
-{
-       unsigned long start = __get_tb();
-
-       while((__get_tb() - start) < loops)
-               __HMT_low();
-       __HMT_medium();
-       __barrier();
-}
-
-static inline void udelay(unsigned long usecs)
-{
-       unsigned long loops = tb_ticks_per_usec * usecs;
-
-       __delay(loops);
-}
+extern void __delay(unsigned long loops);
+extern void udelay(unsigned long usecs);
 
 #endif /* _ASM_POWERPC_DELAY_H */