aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/tsc_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/tsc_32.c')
-rw-r--r--arch/x86/kernel/tsc_32.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index e4790728b224..068759db63dd 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -14,7 +14,7 @@
14 14
15#include "mach_timer.h" 15#include "mach_timer.h"
16 16
17static int tsc_enabled; 17static int tsc_disabled;
18 18
19/* 19/*
20 * On some systems the TSC frequency does not 20 * On some systems the TSC frequency does not
@@ -28,8 +28,8 @@ EXPORT_SYMBOL_GPL(tsc_khz);
28static int __init tsc_setup(char *str) 28static int __init tsc_setup(char *str)
29{ 29{
30 printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " 30 printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, "
31 "cannot disable TSC completely.\n"); 31 "cannot disable TSC completely.\n");
32 mark_tsc_unstable("user disabled TSC"); 32 tsc_disabled = 1;
33 return 1; 33 return 1;
34} 34}
35#else 35#else
@@ -120,7 +120,7 @@ unsigned long long native_sched_clock(void)
120 * very important for it to be as fast as the platform 120 * very important for it to be as fast as the platform
121 * can achive it. ) 121 * can achive it. )
122 */ 122 */
123 if (unlikely(!tsc_enabled && !tsc_unstable)) 123 if (unlikely(tsc_disabled))
124 /* No locking but a rare wrong value is not a big deal: */ 124 /* No locking but a rare wrong value is not a big deal: */
125 return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); 125 return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ);
126 126
@@ -322,7 +322,6 @@ void mark_tsc_unstable(char *reason)
322{ 322{
323 if (!tsc_unstable) { 323 if (!tsc_unstable) {
324 tsc_unstable = 1; 324 tsc_unstable = 1;
325 tsc_enabled = 0;
326 printk("Marking TSC unstable due to: %s.\n", reason); 325 printk("Marking TSC unstable due to: %s.\n", reason);
327 /* Can be called before registration */ 326 /* Can be called before registration */
328 if (clocksource_tsc.mult) 327 if (clocksource_tsc.mult)
@@ -336,7 +335,7 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable);
336static int __init dmi_mark_tsc_unstable(const struct dmi_system_id *d) 335static int __init dmi_mark_tsc_unstable(const struct dmi_system_id *d)
337{ 336{
338 printk(KERN_NOTICE "%s detected: marking TSC unstable.\n", 337 printk(KERN_NOTICE "%s detected: marking TSC unstable.\n",
339 d->ident); 338 d->ident);
340 tsc_unstable = 1; 339 tsc_unstable = 1;
341 return 0; 340 return 0;
342} 341}
@@ -403,14 +402,22 @@ void __init tsc_init(void)
403{ 402{
404 int cpu; 403 int cpu;
405 404
406 if (!cpu_has_tsc) 405 if (!cpu_has_tsc || tsc_disabled) {
406 /* Disable the TSC in case of !cpu_has_tsc */
407 tsc_disabled = 1;
407 return; 408 return;
409 }
408 410
409 cpu_khz = calculate_cpu_khz(); 411 cpu_khz = calculate_cpu_khz();
410 tsc_khz = cpu_khz; 412 tsc_khz = cpu_khz;
411 413
412 if (!cpu_khz) { 414 if (!cpu_khz) {
413 mark_tsc_unstable("could not calculate TSC khz"); 415 mark_tsc_unstable("could not calculate TSC khz");
416 /*
417 * We need to disable the TSC completely in this case
418 * to prevent sched_clock() from using it.
419 */
420 tsc_disabled = 1;
414 return; 421 return;
415 } 422 }
416 423
@@ -441,8 +448,6 @@ void __init tsc_init(void)
441 if (check_tsc_unstable()) { 448 if (check_tsc_unstable()) {
442 clocksource_tsc.rating = 0; 449 clocksource_tsc.rating = 0;
443 clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; 450 clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS;
444 } else 451 }
445 tsc_enabled = 1;
446
447 clocksource_register(&clocksource_tsc); 452 clocksource_register(&clocksource_tsc);
448} 453}