diff options
Diffstat (limited to 'arch/x86_64/kernel/apic.c')
-rw-r--r-- | arch/x86_64/kernel/apic.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 5d3c5b07b8db..14751dda7dcf 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
@@ -35,8 +35,11 @@ | |||
35 | #include <asm/mach_apic.h> | 35 | #include <asm/mach_apic.h> |
36 | #include <asm/nmi.h> | 36 | #include <asm/nmi.h> |
37 | #include <asm/idle.h> | 37 | #include <asm/idle.h> |
38 | #include <asm/proto.h> | ||
39 | #include <asm/timex.h> | ||
38 | 40 | ||
39 | int apic_verbosity; | 41 | int apic_verbosity; |
42 | int apic_runs_main_timer; | ||
40 | 43 | ||
41 | int disable_apic_timer __initdata; | 44 | int disable_apic_timer __initdata; |
42 | 45 | ||
@@ -702,9 +705,17 @@ static void setup_APIC_timer(unsigned int clocks) | |||
702 | c2 |= inb_p(0x40) << 8; | 705 | c2 |= inb_p(0x40) << 8; |
703 | } while (c2 - c1 < 300); | 706 | } while (c2 - c1 < 300); |
704 | } | 707 | } |
705 | |||
706 | __setup_APIC_LVTT(clocks); | 708 | __setup_APIC_LVTT(clocks); |
707 | 709 | /* Turn off PIT interrupt if we use APIC timer as main timer. | |
710 | Only works with the PM timer right now | ||
711 | TBD fix it for HPET too. */ | ||
712 | if (vxtime.mode == VXTIME_PMTMR && | ||
713 | smp_processor_id() == boot_cpu_id && | ||
714 | apic_runs_main_timer == 1 && | ||
715 | !cpu_isset(boot_cpu_id, timer_interrupt_broadcast_ipi_mask)) { | ||
716 | stop_timer_interrupt(); | ||
717 | apic_runs_main_timer++; | ||
718 | } | ||
708 | local_irq_restore(flags); | 719 | local_irq_restore(flags); |
709 | } | 720 | } |
710 | 721 | ||
@@ -872,6 +883,8 @@ void smp_local_timer_interrupt(struct pt_regs *regs) | |||
872 | #ifdef CONFIG_SMP | 883 | #ifdef CONFIG_SMP |
873 | update_process_times(user_mode(regs)); | 884 | update_process_times(user_mode(regs)); |
874 | #endif | 885 | #endif |
886 | if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id) | ||
887 | main_timer_handler(regs); | ||
875 | /* | 888 | /* |
876 | * We take the 'long' return path, and there every subsystem | 889 | * We take the 'long' return path, and there every subsystem |
877 | * grabs the appropriate locks (kernel lock/ irq lock). | 890 | * grabs the appropriate locks (kernel lock/ irq lock). |
@@ -1081,10 +1094,27 @@ static __init int setup_nolapic(char *str) | |||
1081 | 1094 | ||
1082 | static __init int setup_noapictimer(char *str) | 1095 | static __init int setup_noapictimer(char *str) |
1083 | { | 1096 | { |
1097 | if (str[0] != ' ' && str[0] != 0) | ||
1098 | return -1; | ||
1084 | disable_apic_timer = 1; | 1099 | disable_apic_timer = 1; |
1085 | return 0; | 1100 | return 0; |
1086 | } | 1101 | } |
1087 | 1102 | ||
1103 | static __init int setup_apicmaintimer(char *str) | ||
1104 | { | ||
1105 | apic_runs_main_timer = 1; | ||
1106 | nohpet = 1; | ||
1107 | return 0; | ||
1108 | } | ||
1109 | __setup("apicmaintimer", setup_apicmaintimer); | ||
1110 | |||
1111 | static __init int setup_noapicmaintimer(char *str) | ||
1112 | { | ||
1113 | apic_runs_main_timer = -1; | ||
1114 | return 0; | ||
1115 | } | ||
1116 | __setup("noapicmaintimer", setup_noapicmaintimer); | ||
1117 | |||
1088 | /* dummy parsing: see setup.c */ | 1118 | /* dummy parsing: see setup.c */ |
1089 | 1119 | ||
1090 | __setup("disableapic", setup_disableapic); | 1120 | __setup("disableapic", setup_disableapic); |