diff options
Diffstat (limited to 'arch/x86_64/kernel/apic.c')
-rw-r--r-- | arch/x86_64/kernel/apic.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 673a2fe9923c..c02218b3ae2b 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
@@ -40,6 +40,7 @@ | |||
40 | 40 | ||
41 | int apic_verbosity; | 41 | int apic_verbosity; |
42 | int apic_runs_main_timer; | 42 | int apic_runs_main_timer; |
43 | int apic_calibrate_pmtmr __initdata; | ||
43 | 44 | ||
44 | int disable_apic_timer __initdata; | 45 | int disable_apic_timer __initdata; |
45 | 46 | ||
@@ -746,14 +747,27 @@ static int __init calibrate_APIC_clock(void) | |||
746 | __setup_APIC_LVTT(1000000000); | 747 | __setup_APIC_LVTT(1000000000); |
747 | 748 | ||
748 | apic_start = apic_read(APIC_TMCCT); | 749 | apic_start = apic_read(APIC_TMCCT); |
749 | rdtscl(tsc_start); | 750 | #ifdef CONFIG_X86_PM_TIMER |
750 | 751 | if (apic_calibrate_pmtmr && pmtmr_ioport) { | |
751 | do { | 752 | pmtimer_wait(5000); /* 5ms wait */ |
752 | apic = apic_read(APIC_TMCCT); | 753 | apic = apic_read(APIC_TMCCT); |
753 | rdtscl(tsc); | 754 | result = (apic_start - apic) * 1000L / 5; |
754 | } while ((tsc - tsc_start) < TICK_COUNT && (apic - apic_start) < TICK_COUNT); | 755 | } else |
756 | #endif | ||
757 | { | ||
758 | rdtscl(tsc_start); | ||
759 | |||
760 | do { | ||
761 | apic = apic_read(APIC_TMCCT); | ||
762 | rdtscl(tsc); | ||
763 | } while ((tsc - tsc_start) < TICK_COUNT && | ||
764 | (apic - apic_start) < TICK_COUNT); | ||
765 | |||
766 | result = (apic_start - apic) * 1000L * cpu_khz / | ||
767 | (tsc - tsc_start); | ||
768 | } | ||
769 | printk("result %d\n", result); | ||
755 | 770 | ||
756 | result = (apic_start - apic) * 1000L * cpu_khz / (tsc - tsc_start); | ||
757 | 771 | ||
758 | printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n", | 772 | printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n", |
759 | result / 1000 / 1000, result / 1000 % 1000); | 773 | result / 1000 / 1000, result / 1000 % 1000); |
@@ -1115,6 +1129,13 @@ static __init int setup_noapicmaintimer(char *str) | |||
1115 | } | 1129 | } |
1116 | __setup("noapicmaintimer", setup_noapicmaintimer); | 1130 | __setup("noapicmaintimer", setup_noapicmaintimer); |
1117 | 1131 | ||
1132 | static __init int setup_apicpmtimer(char *s) | ||
1133 | { | ||
1134 | apic_calibrate_pmtmr = 1; | ||
1135 | return setup_apicmaintimer(NULL); | ||
1136 | } | ||
1137 | __setup("apicpmtimer", setup_apicpmtimer); | ||
1138 | |||
1118 | /* dummy parsing: see setup.c */ | 1139 | /* dummy parsing: see setup.c */ |
1119 | 1140 | ||
1120 | __setup("disableapic", setup_disableapic); | 1141 | __setup("disableapic", setup_disableapic); |