Merge branch 'devel' into next
[pandora-kernel.git] / arch / x86 / kernel / nmi.c
index 69a839f..ec024b3 100644 (file)
@@ -11,6 +11,8 @@
  *  Mikael Pettersson  : PM converted to driver model. Disable/enable API.
  */
 
+#include <asm/apic.h>
+
 #include <linux/nmi.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/cpumask.h>
 #include <linux/kernel_stat.h>
 #include <linux/kdebug.h>
+#include <linux/smp.h>
 
+#include <asm/i8259.h>
+#include <asm/io_apic.h>
 #include <asm/smp.h>
 #include <asm/nmi.h>
 #include <asm/proto.h>
@@ -45,13 +50,16 @@ static cpumask_t backtrace_mask = CPU_MASK_NONE;
  *  0: the lapic NMI watchdog is disabled, but can be enabled
  */
 atomic_t nmi_active = ATOMIC_INIT(0);          /* oprofile uses this */
-static int panic_on_timeout;
+EXPORT_SYMBOL(nmi_active);
 
-unsigned int nmi_watchdog = NMI_DEFAULT;
+unsigned int nmi_watchdog = NMI_NONE;
+EXPORT_SYMBOL(nmi_watchdog);
+
+static int panic_on_timeout;
 
 static unsigned int nmi_hz = HZ;
 static DEFINE_PER_CPU(short, wd_enabled);
-static int endflag __initdata = 0;
+static int endflag __initdata;
 
 static inline unsigned int get_nmi_count(int cpu)
 {
@@ -64,7 +72,7 @@ static inline unsigned int get_nmi_count(int cpu)
 
 static inline int mce_in_progress(void)
 {
-#if defined(CONFIX_X86_64) && defined(CONFIG_X86_MCE)
+#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
        return atomic_read(&mce_entry) > 0;
 #endif
        return 0;
@@ -84,21 +92,6 @@ static inline unsigned int get_timer_irqs(int cpu)
 #endif
 }
 
-/* Run after command line and cpu_init init, but before all other checks */
-void nmi_watchdog_default(void)
-{
-       if (nmi_watchdog != NMI_DEFAULT)
-               return;
-#ifdef CONFIG_X86_64
-       nmi_watchdog = NMI_NONE;
-#else
-       if (lapic_watchdog_ok())
-               nmi_watchdog = NMI_LOCAL_APIC;
-       else
-               nmi_watchdog = NMI_IO_APIC;
-#endif
-}
-
 #ifdef CONFIG_SMP
 /*
  * The performance counters used by NMI_LOCAL_APIC don't trigger when
@@ -126,13 +119,10 @@ int __init check_nmi_watchdog(void)
        unsigned int *prev_nmi_count;
        int cpu;
 
-       if (nmi_watchdog == NMI_NONE || nmi_watchdog == NMI_DISABLED)
+       if (!nmi_watchdog_active() || !atomic_read(&nmi_active))
                return 0;
 
-       if (!atomic_read(&nmi_active))
-               return 0;
-
-       prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
+       prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(int), GFP_KERNEL);
        if (!prev_nmi_count)
                goto error;
 
@@ -140,7 +130,7 @@ int __init check_nmi_watchdog(void)
 
 #ifdef CONFIG_SMP
        if (nmi_watchdog == NMI_LOCAL_APIC)
-               smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
+               smp_call_function(nmi_cpu_busy, (void *)&endflag, 0);
 #endif
 
        for_each_possible_cpu(cpu)
@@ -178,17 +168,18 @@ int __init check_nmi_watchdog(void)
 
        kfree(prev_nmi_count);
        return 0;
-
 error:
+       if (nmi_watchdog == NMI_IO_APIC && !timer_through_8259)
+               disable_8259A_irq(0);
 #ifdef CONFIG_X86_32
-       timer_ack = !cpu_has_tsc;
+       timer_ack = 0;
 #endif
        return -1;
 }
 
 static int __init setup_nmi_watchdog(char *str)
 {
-       int nmi;
+       unsigned int nmi;
 
        if (!strncmp(str, "panic", 5)) {
                panic_on_timeout = 1;
@@ -200,7 +191,7 @@ static int __init setup_nmi_watchdog(char *str)
 
        get_option(&str, &nmi);
 
-       if (nmi >= NMI_INVALID || nmi < NMI_NONE)
+       if (nmi >= NMI_INVALID)
                return 0;
 
        nmi_watchdog = nmi;
@@ -281,7 +272,7 @@ static void __acpi_nmi_enable(void *__unused)
 void acpi_nmi_enable(void)
 {
        if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
-               on_each_cpu(__acpi_nmi_enable, NULL, 0, 1);
+               on_each_cpu(__acpi_nmi_enable, NULL, 1);
 }
 
 static void __acpi_nmi_disable(void *__unused)
@@ -295,7 +286,7 @@ static void __acpi_nmi_disable(void *__unused)
 void acpi_nmi_disable(void)
 {
        if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
-               on_each_cpu(__acpi_nmi_disable, NULL, 0, 1);
+               on_each_cpu(__acpi_nmi_disable, NULL, 1);
 }
 
 void setup_apic_nmi_watchdog(void *unused)
@@ -326,8 +317,7 @@ void setup_apic_nmi_watchdog(void *unused)
 void stop_apic_nmi_watchdog(void *unused)
 {
        /* only support LOCAL and IO APICs for now */
-       if (nmi_watchdog != NMI_LOCAL_APIC &&
-           nmi_watchdog != NMI_IO_APIC)
+       if (!nmi_watchdog_active())
                return;
        if (__get_cpu_var(wd_enabled) == 0)
                return;
@@ -357,7 +347,7 @@ static DEFINE_PER_CPU(int, nmi_touch);
 
 void touch_nmi_watchdog(void)
 {
-       if (nmi_watchdog > 0) {
+       if (nmi_watchdog_active()) {
                unsigned cpu;
 
                /*
@@ -409,7 +399,7 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
                static DEFINE_SPINLOCK(lock);   /* Serialise the printks */
 
                spin_lock(&lock);
-               printk("NMI backtrace for cpu %d\n", cpu);
+               printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
                dump_stack();
                spin_unlock(&lock);
                cpu_clear(cpu, backtrace_mask);
@@ -482,15 +472,12 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
        if (!!old_state == !!nmi_watchdog_enabled)
                return 0;
 
-       if (atomic_read(&nmi_active) < 0 || nmi_watchdog == NMI_DISABLED) {
+       if (atomic_read(&nmi_active) < 0 || !nmi_watchdog_active()) {
                printk(KERN_WARNING
                        "NMI watchdog is permanently disabled\n");
                return -EIO;
        }
 
-       /* if nmi_watchdog is not set yet, then set it */
-       nmi_watchdog_default();
-
        if (nmi_watchdog == NMI_LOCAL_APIC) {
                if (nmi_watchdog_enabled)
                        enable_lapic_nmi_watchdog();
@@ -527,7 +514,3 @@ void __trigger_all_cpu_backtrace(void)
                mdelay(1);
        }
 }
-
-EXPORT_SYMBOL(nmi_active);
-EXPORT_SYMBOL(nmi_watchdog);
-