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>
This commit is contained in:
parent
fe7bce5ef7
commit
6defa38b37
|
@ -27,14 +27,6 @@
|
||||||
|
|
||||||
.text
|
.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.
|
* This returns the high 64 bits of the product of two 64-bit numbers.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -130,6 +130,34 @@ unsigned long tb_last_stamp;
|
||||||
*/
|
*/
|
||||||
DEFINE_PER_CPU(unsigned long, last_jiffy);
|
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)
|
static __inline__ void timer_check_rtc(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -13,43 +13,7 @@
|
||||||
* Anton Blanchard.
|
* Anton Blanchard.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern unsigned long tb_ticks_per_usec;
|
extern void __delay(unsigned long loops);
|
||||||
|
extern void udelay(unsigned long usecs);
|
||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_DELAY_H */
|
#endif /* _ASM_POWERPC_DELAY_H */
|
||||||
|
|
Loading…
Reference in New Issue