aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/lib')
-rw-r--r--arch/x86/lib/delay_64.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c
index 4c441be92641..d0326d07c845 100644
--- a/arch/x86/lib/delay_64.c
+++ b/arch/x86/lib/delay_64.c
@@ -22,13 +22,28 @@
22#include <asm/smp.h> 22#include <asm/smp.h>
23#endif 23#endif
24 24
25int __devinit read_current_timer(unsigned long *timer_value) 25/* simple loop based delay: */
26static void delay_loop(unsigned long loops)
26{ 27{
27 rdtscll(*timer_value); 28 asm volatile(
28 return 0; 29 " test %0,%0 \n"
30 " jz 3f \n"
31 " jmp 1f \n"
32
33 ".align 16 \n"
34 "1: jmp 2f \n"
35
36 ".align 16 \n"
37 "2: dec %0 \n"
38 " jnz 2b \n"
39 "3: dec %0 \n"
40
41 : /* we don't need output */
42 :"a" (loops)
43 );
29} 44}
30 45
31void __delay(unsigned long loops) 46static void delay_tsc(unsigned long loops)
32{ 47{
33 unsigned bclock, now; 48 unsigned bclock, now;
34 int cpu; 49 int cpu;
@@ -63,6 +78,27 @@ void __delay(unsigned long loops)
63 } 78 }
64 preempt_enable(); 79 preempt_enable();
65} 80}
81
82static void (*delay_fn)(unsigned long) = delay_loop;
83
84void use_tsc_delay(void)
85{
86 delay_fn = delay_tsc;
87}
88
89int __devinit read_current_timer(unsigned long *timer_value)
90{
91 if (delay_fn == delay_tsc) {
92 rdtscll(*timer_value);
93 return 0;
94 }
95 return -1;
96}
97
98void __delay(unsigned long loops)
99{
100 delay_fn(loops);
101}
66EXPORT_SYMBOL(__delay); 102EXPORT_SYMBOL(__delay);
67 103
68inline void __const_udelay(unsigned long xloops) 104inline void __const_udelay(unsigned long xloops)