Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[cascardo/linux.git] / arch / i386 / kernel / cpu / mcheck / p4.c
index b95f1b3..1509edf 100644 (file)
@@ -13,6 +13,8 @@
 #include <asm/msr.h>
 #include <asm/apic.h>
 
+#include <asm/therm_throt.h>
+
 #include "mce.h"
 
 /* as supported by the P4/Xeon family */
@@ -44,25 +46,12 @@ static void unexpected_thermal_interrupt(struct pt_regs *regs)
 /* P4/Xeon Thermal transition interrupt handler */
 static void intel_thermal_interrupt(struct pt_regs *regs)
 {
-       u32 l, h;
-       unsigned int cpu = smp_processor_id();
-       static unsigned long next[NR_CPUS];
+       __u64 msr_val;
 
        ack_APIC_irq();
 
-       if (time_after(next[cpu], jiffies))
-               return;
-
-       next[cpu] = jiffies + HZ*5;
-       rdmsr(MSR_IA32_THERM_STATUS, l, h);
-       if (l & 0x1) {
-               printk(KERN_EMERG "CPU%d: Temperature above threshold\n", cpu);
-               printk(KERN_EMERG "CPU%d: Running in modulated clock mode\n",
-                               cpu);
-               add_taint(TAINT_MACHINE_CHECK);
-       } else {
-               printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu);
-       }
+       rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
+       therm_throt_process(msr_val & 0x1);
 }
 
 /* Thermal interrupt handler for this CPU setup */
@@ -122,23 +111,23 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
        
        rdmsr (MSR_IA32_MISC_ENABLE, l, h);
        wrmsr (MSR_IA32_MISC_ENABLE, l | (1<<3), h);
-       
+
        l = apic_read (APIC_LVTTHMR);
        apic_write_around (APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
        printk (KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu);
+
+       /* enable thermal throttle processing */
+       atomic_set(&therm_throt_en, 1);
        return;
 }
 #endif /* CONFIG_X86_MCE_P4THERMAL */
 
 
 /* P4/Xeon Extended MCE MSR retrieval, return 0 if unsupported */
-static inline int intel_get_extended_msrs(struct intel_mce_extended_msrs *r)
+static inline void intel_get_extended_msrs(struct intel_mce_extended_msrs *r)
 {
        u32 h;
 
-       if (mce_num_extended_msrs == 0)
-               goto done;
-
        rdmsr (MSR_IA32_MCG_EAX, r->eax, h);
        rdmsr (MSR_IA32_MCG_EBX, r->ebx, h);
        rdmsr (MSR_IA32_MCG_ECX, r->ecx, h);
@@ -149,12 +138,6 @@ static inline int intel_get_extended_msrs(struct intel_mce_extended_msrs *r)
        rdmsr (MSR_IA32_MCG_ESP, r->esp, h);
        rdmsr (MSR_IA32_MCG_EFLAGS, r->eflags, h);
        rdmsr (MSR_IA32_MCG_EIP, r->eip, h);
-
-       /* can we rely on kmalloc to do a dynamic
-        * allocation for the reserved registers?
-        */
-done:
-       return mce_num_extended_msrs;
 }
 
 static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
@@ -163,7 +146,6 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
        u32 alow, ahigh, high, low;
        u32 mcgstl, mcgsth;
        int i;
-       struct intel_mce_extended_msrs dbg;
 
        rdmsr (MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
        if (mcgstl & (1<<0))    /* Recoverable ? */
@@ -172,7 +154,9 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
        printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
                smp_processor_id(), mcgsth, mcgstl);
 
-       if (intel_get_extended_msrs(&dbg)) {
+       if (mce_num_extended_msrs > 0) {
+               struct intel_mce_extended_msrs dbg;
+               intel_get_extended_msrs(&dbg);
                printk (KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n",
                        smp_processor_id(), dbg.eip, dbg.eflags);
                printk (KERN_DEBUG "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n",