diff options
author | Glauber Costa <gcosta@redhat.com> | 2008-06-24 08:34:08 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-09 02:51:41 -0400 |
commit | 0a4d8a472f645d99f86303db1462b64e371b090d (patch) | |
tree | dd6b4b3d4a5cb415b06e8e1625ea811a9012119d /arch/x86/lib/delay_64.c | |
parent | ff1b15b646177c6cc465ac2dd0be6ae16e965654 (diff) |
x86: provide delay loop for x86_64.
This is for consistency with i386. We call use_tsc_delay()
at tsc initialization for x86_64, so we'll be always using it.
Signed-off-by: Glauber Costa <gcosta@redhat.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/lib/delay_64.c')
-rw-r--r-- | arch/x86/lib/delay_64.c | 44 |
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 | ||
25 | int __devinit read_current_timer(unsigned long *timer_value) | 25 | /* simple loop based delay: */ |
26 | static 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 | ||
31 | void __delay(unsigned long loops) | 46 | static 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 | |||
82 | static void (*delay_fn)(unsigned long) = delay_loop; | ||
83 | |||
84 | void use_tsc_delay(void) | ||
85 | { | ||
86 | delay_fn = delay_tsc; | ||
87 | } | ||
88 | |||
89 | int __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 | |||
98 | void __delay(unsigned long loops) | ||
99 | { | ||
100 | delay_fn(loops); | ||
101 | } | ||
66 | EXPORT_SYMBOL(__delay); | 102 | EXPORT_SYMBOL(__delay); |
67 | 103 | ||
68 | inline void __const_udelay(unsigned long xloops) | 104 | inline void __const_udelay(unsigned long xloops) |