aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-11-18 13:44:17 +1100
committerPaul Mackerras <paulus@samba.org>2005-11-18 14:08:12 +1100
commit6defa38b3754c84cd3449447477aed81ea979407 (patch)
treeb5f40628d6fd9001470aa2f9a8fa3f2ed08862c6 /arch
parentfe7bce5ef70105a6546dc9b5c354219b9f6ea991 (diff)
downloadlinux-6defa38b3754c84cd3449447477aed81ea979407.tar.gz
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/misc_32.S8
-rw-r--r--arch/powerpc/kernel/time.c28
2 files changed, 28 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index f6d84a75ed266..624a983a96767 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -27,14 +27,6 @@
.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.
*/
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 070b4b458aafe..de8479769bb72 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -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)
{
/*