aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/apic.c')
-rw-r--r--arch/i386/kernel/apic.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 8c844d07862f..2fd4b7d927c2 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -52,7 +52,18 @@ static cpumask_t timer_bcast_ipi;
/*
* Knob to control our willingness to enable the local APIC.
*/
-int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
+static int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
+
+static inline void lapic_disable(void)
+{
+ enable_local_apic = -1;
+ clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+}
+
+static inline void lapic_enable(void)
+{
+ enable_local_apic = 1;
+}
/*
* Debug level
@@ -586,8 +597,7 @@ void __devinit setup_local_APIC(void)
printk("No ESR for 82489DX.\n");
}
- if (nmi_watchdog == NMI_LOCAL_APIC)
- setup_apic_nmi_watchdog();
+ setup_apic_nmi_watchdog(NULL);
apic_pm_activate();
}
@@ -1183,11 +1193,11 @@ EXPORT_SYMBOL(switch_ipi_to_APIC_timer);
* value into /proc/profile.
*/
-inline void smp_local_timer_interrupt(struct pt_regs * regs)
+inline void smp_local_timer_interrupt(void)
{
- profile_tick(CPU_PROFILING, regs);
+ profile_tick(CPU_PROFILING);
#ifdef CONFIG_SMP
- update_process_times(user_mode_vm(regs));
+ update_process_times(user_mode_vm(get_irq_regs()));
#endif
/*
@@ -1213,6 +1223,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs)
fastcall void smp_apic_timer_interrupt(struct pt_regs *regs)
{
+ struct pt_regs *old_regs = set_irq_regs(regs);
int cpu = smp_processor_id();
/*
@@ -1231,12 +1242,13 @@ fastcall void smp_apic_timer_interrupt(struct pt_regs *regs)
* interrupt lock, which is the WrongThing (tm) to do.
*/
irq_enter();
- smp_local_timer_interrupt(regs);
+ smp_local_timer_interrupt();
irq_exit();
+ set_irq_regs(old_regs);
}
#ifndef CONFIG_SMP
-static void up_apic_timer_interrupt_call(struct pt_regs *regs)
+static void up_apic_timer_interrupt_call(void)
{
int cpu = smp_processor_id();
@@ -1245,11 +1257,11 @@ static void up_apic_timer_interrupt_call(struct pt_regs *regs)
*/
per_cpu(irq_stat, cpu).apic_timer_irqs++;
- smp_local_timer_interrupt(regs);
+ smp_local_timer_interrupt();
}
#endif
-void smp_send_timer_broadcast_ipi(struct pt_regs *regs)
+void smp_send_timer_broadcast_ipi(void)
{
cpumask_t mask;
@@ -1262,7 +1274,7 @@ void smp_send_timer_broadcast_ipi(struct pt_regs *regs)
* We can directly call the apic timer interrupt handler
* in UP case. Minus all irq related functions
*/
- up_apic_timer_interrupt_call(regs);
+ up_apic_timer_interrupt_call();
#endif
}
}
@@ -1373,3 +1385,18 @@ int __init APIC_init_uniprocessor (void)
return 0;
}
+
+static int __init parse_lapic(char *arg)
+{
+ lapic_enable();
+ return 0;
+}
+early_param("lapic", parse_lapic);
+
+static int __init parse_nolapic(char *arg)
+{
+ lapic_disable();
+ return 0;
+}
+early_param("nolapic", parse_nolapic);
+