aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlauber Costa <gcosta@redhat.com>2008-06-24 08:34:08 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-09 02:51:41 -0400
commit0a4d8a472f645d99f86303db1462b64e371b090d (patch)
treedd6b4b3d4a5cb415b06e8e1625ea811a9012119d
parentff1b15b646177c6cc465ac2dd0be6ae16e965654 (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>
-rw-r--r--arch/x86/kernel/tsc.c1
-rw-r--r--arch/x86/lib/delay_64.c44
2 files changed, 41 insertions, 4 deletions
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 3c36f92160c9..4a775d001957 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -513,6 +513,7 @@ void __init tsc_init(void)
513 */ 513 */
514 for_each_possible_cpu(cpu) 514 for_each_possible_cpu(cpu)
515 set_cyc2ns_scale(cpu_khz, cpu); 515 set_cyc2ns_scale(cpu_khz, cpu);
516 use_tsc_delay();
516 517
517 if (tsc_disabled > 0) 518 if (tsc_disabled > 0)
518 return; 519 return;
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)