diff options
| author | Paul Mackerras <paulus@samba.org> | 2005-11-17 21:44:17 -0500 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2005-11-17 22:08:12 -0500 |
| commit | 6defa38b3754c84cd3449447477aed81ea979407 (patch) | |
| tree | b5f40628d6fd9001470aa2f9a8fa3f2ed08862c6 | |
| parent | fe7bce5ef70105a6546dc9b5c354219b9f6ea991 (diff) | |
powerpc: Fix delay functions for 601 processors
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>
| -rw-r--r-- | arch/powerpc/kernel/misc_32.S | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/time.c | 28 | ||||
| -rw-r--r-- | include/asm-powerpc/delay.h | 40 |
3 files changed, 30 insertions, 46 deletions
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index f6d84a75ed26..624a983a9676 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
| @@ -27,14 +27,6 @@ | |||
| 27 | 27 | ||
| 28 | .text | 28 | .text |
| 29 | 29 | ||
| 30 | .align 5 | ||
| 31 | _GLOBAL(__delay) | ||
| 32 | cmpwi 0,r3,0 | ||
| 33 | mtctr r3 | ||
| 34 | beqlr | ||
| 35 | 1: bdnz 1b | ||
| 36 | blr | ||
| 37 | |||
| 38 | /* | 30 | /* |
| 39 | * This returns the high 64 bits of the product of two 64-bit numbers. | 31 | * This returns the high 64 bits of the product of two 64-bit numbers. |
| 40 | */ | 32 | */ |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 070b4b458aaf..de8479769bb7 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -130,6 +130,34 @@ unsigned long tb_last_stamp; | |||
| 130 | */ | 130 | */ |
| 131 | DEFINE_PER_CPU(unsigned long, last_jiffy); | 131 | DEFINE_PER_CPU(unsigned long, last_jiffy); |
| 132 | 132 | ||
| 133 | void __delay(unsigned long loops) | ||
| 134 | { | ||
| 135 | unsigned long start; | ||
| 136 | int diff; | ||
| 137 | |||
| 138 | if (__USE_RTC()) { | ||
| 139 | start = get_rtcl(); | ||
| 140 | do { | ||
| 141 | /* the RTCL register wraps at 1000000000 */ | ||
| 142 | diff = get_rtcl() - start; | ||
| 143 | if (diff < 0) | ||
| 144 | diff += 1000000000; | ||
| 145 | } while (diff < loops); | ||
| 146 | } else { | ||
| 147 | start = get_tbl(); | ||
| 148 | while (get_tbl() - start < loops) | ||
| 149 | HMT_low(); | ||
| 150 | HMT_medium(); | ||
| 151 | } | ||
| 152 | } | ||
| 153 | EXPORT_SYMBOL(__delay); | ||
| 154 | |||
| 155 | void udelay(unsigned long usecs) | ||
| 156 | { | ||
| 157 | __delay(tb_ticks_per_usec * usecs); | ||
| 158 | } | ||
| 159 | EXPORT_SYMBOL(udelay); | ||
| 160 | |||
| 133 | static __inline__ void timer_check_rtc(void) | 161 | static __inline__ void timer_check_rtc(void) |
| 134 | { | 162 | { |
| 135 | /* | 163 | /* |
diff --git a/include/asm-powerpc/delay.h b/include/asm-powerpc/delay.h index 1492aa9ab716..54fe1f4f8fd0 100644 --- a/include/asm-powerpc/delay.h +++ b/include/asm-powerpc/delay.h | |||
| @@ -13,43 +13,7 @@ | |||
| 13 | * Anton Blanchard. | 13 | * Anton Blanchard. |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | extern unsigned long tb_ticks_per_usec; | 16 | extern void __delay(unsigned long loops); |
| 17 | 17 | extern void udelay(unsigned long usecs); | |
| 18 | #ifdef CONFIG_PPC64 | ||
| 19 | /* define these here to prevent circular dependencies */ | ||
| 20 | /* these instructions control the thread priority on multi-threaded cpus */ | ||
| 21 | #define __HMT_low() asm volatile("or 1,1,1") | ||
| 22 | #define __HMT_medium() asm volatile("or 2,2,2") | ||
| 23 | #else | ||
| 24 | #define __HMT_low() | ||
| 25 | #define __HMT_medium() | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #define __barrier() asm volatile("" ::: "memory") | ||
| 29 | |||
| 30 | static inline unsigned long __get_tb(void) | ||
| 31 | { | ||
| 32 | unsigned long rval; | ||
| 33 | |||
| 34 | asm volatile("mftb %0" : "=r" (rval)); | ||
| 35 | return rval; | ||
| 36 | } | ||
| 37 | |||
| 38 | static inline void __delay(unsigned long loops) | ||
| 39 | { | ||
| 40 | unsigned long start = __get_tb(); | ||
| 41 | |||
| 42 | while((__get_tb() - start) < loops) | ||
| 43 | __HMT_low(); | ||
| 44 | __HMT_medium(); | ||
| 45 | __barrier(); | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline void udelay(unsigned long usecs) | ||
| 49 | { | ||
| 50 | unsigned long loops = tb_ticks_per_usec * usecs; | ||
| 51 | |||
| 52 | __delay(loops); | ||
| 53 | } | ||
| 54 | 18 | ||
| 55 | #endif /* _ASM_POWERPC_DELAY_H */ | 19 | #endif /* _ASM_POWERPC_DELAY_H */ |
