diff options
Diffstat (limited to 'arch/i386/kernel/cpu/mcheck/p4.c')
-rw-r--r-- | arch/i386/kernel/cpu/mcheck/p4.c | 26 |
1 files changed, 9 insertions, 17 deletions
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c index b95f1b3d53aa..504434a46011 100644 --- a/arch/i386/kernel/cpu/mcheck/p4.c +++ b/arch/i386/kernel/cpu/mcheck/p4.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <asm/msr.h> | 13 | #include <asm/msr.h> |
14 | #include <asm/apic.h> | 14 | #include <asm/apic.h> |
15 | 15 | ||
16 | #include <asm/therm_throt.h> | ||
17 | |||
16 | #include "mce.h" | 18 | #include "mce.h" |
17 | 19 | ||
18 | /* as supported by the P4/Xeon family */ | 20 | /* as supported by the P4/Xeon family */ |
@@ -44,25 +46,12 @@ static void unexpected_thermal_interrupt(struct pt_regs *regs) | |||
44 | /* P4/Xeon Thermal transition interrupt handler */ | 46 | /* P4/Xeon Thermal transition interrupt handler */ |
45 | static void intel_thermal_interrupt(struct pt_regs *regs) | 47 | static void intel_thermal_interrupt(struct pt_regs *regs) |
46 | { | 48 | { |
47 | u32 l, h; | 49 | __u64 msr_val; |
48 | unsigned int cpu = smp_processor_id(); | ||
49 | static unsigned long next[NR_CPUS]; | ||
50 | 50 | ||
51 | ack_APIC_irq(); | 51 | ack_APIC_irq(); |
52 | 52 | ||
53 | if (time_after(next[cpu], jiffies)) | 53 | rdmsrl(MSR_IA32_THERM_STATUS, msr_val); |
54 | return; | 54 | therm_throt_process(msr_val & 0x1); |
55 | |||
56 | next[cpu] = jiffies + HZ*5; | ||
57 | rdmsr(MSR_IA32_THERM_STATUS, l, h); | ||
58 | if (l & 0x1) { | ||
59 | printk(KERN_EMERG "CPU%d: Temperature above threshold\n", cpu); | ||
60 | printk(KERN_EMERG "CPU%d: Running in modulated clock mode\n", | ||
61 | cpu); | ||
62 | add_taint(TAINT_MACHINE_CHECK); | ||
63 | } else { | ||
64 | printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu); | ||
65 | } | ||
66 | } | 55 | } |
67 | 56 | ||
68 | /* Thermal interrupt handler for this CPU setup */ | 57 | /* Thermal interrupt handler for this CPU setup */ |
@@ -122,10 +111,13 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) | |||
122 | 111 | ||
123 | rdmsr (MSR_IA32_MISC_ENABLE, l, h); | 112 | rdmsr (MSR_IA32_MISC_ENABLE, l, h); |
124 | wrmsr (MSR_IA32_MISC_ENABLE, l | (1<<3), h); | 113 | wrmsr (MSR_IA32_MISC_ENABLE, l | (1<<3), h); |
125 | 114 | ||
126 | l = apic_read (APIC_LVTTHMR); | 115 | l = apic_read (APIC_LVTTHMR); |
127 | apic_write_around (APIC_LVTTHMR, l & ~APIC_LVT_MASKED); | 116 | apic_write_around (APIC_LVTTHMR, l & ~APIC_LVT_MASKED); |
128 | printk (KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu); | 117 | printk (KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu); |
118 | |||
119 | /* enable thermal throttle processing */ | ||
120 | atomic_set(&therm_throt_en, 1); | ||
129 | return; | 121 | return; |
130 | } | 122 | } |
131 | #endif /* CONFIG_X86_MCE_P4THERMAL */ | 123 | #endif /* CONFIG_X86_MCE_P4THERMAL */ |