Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
[cascardo/linux.git] / arch / x86 / kernel / cpu / mcheck / therm_throt.c
index 4131c03..41e8e00 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/idle.h>
 #include <asm/mce.h>
 #include <asm/msr.h>
+#include <asm/trace/irq_vectors.h>
 
 /* How long to wait between reporting thermal events */
 #define CHECK_INTERVAL         (300 * HZ)
@@ -193,11 +194,6 @@ static int therm_throt_process(bool new_event, int event, int level)
                                this_cpu,
                                level == CORE_LEVEL ? "Core" : "Package",
                                state->count);
-               else
-                       printk(KERN_CRIT "CPU%d: %s power limit notification (total events = %lu)\n",
-                               this_cpu,
-                               level == CORE_LEVEL ? "Core" : "Package",
-                               state->count);
                return 1;
        }
        if (old_event) {
@@ -205,10 +201,6 @@ static int therm_throt_process(bool new_event, int event, int level)
                        printk(KERN_INFO "CPU%d: %s temperature/speed normal\n",
                                this_cpu,
                                level == CORE_LEVEL ? "Core" : "Package");
-               else
-                       printk(KERN_INFO "CPU%d: %s power limit normal\n",
-                               this_cpu,
-                               level == CORE_LEVEL ? "Core" : "Package");
                return 1;
        }
 
@@ -237,6 +229,15 @@ static int thresh_event_valid(int level, int event)
        return 1;
 }
 
+static bool int_pln_enable;
+static int __init int_pln_enable_setup(char *s)
+{
+       int_pln_enable = true;
+
+       return 1;
+}
+__setup("int_pln_enable", int_pln_enable_setup);
+
 #ifdef CONFIG_SYSFS
 /* Add/Remove thermal_throttle interface for CPU device: */
 static __cpuinit int thermal_throttle_add_dev(struct device *dev,
@@ -249,7 +250,7 @@ static __cpuinit int thermal_throttle_add_dev(struct device *dev,
        if (err)
                return err;
 
-       if (cpu_has(c, X86_FEATURE_PLN))
+       if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
                err = sysfs_add_file_to_group(&dev->kobj,
                                              &dev_attr_core_power_limit_count.attr,
                                              thermal_attr_group.name);
@@ -257,7 +258,7 @@ static __cpuinit int thermal_throttle_add_dev(struct device *dev,
                err = sysfs_add_file_to_group(&dev->kobj,
                                              &dev_attr_package_throttle_count.attr,
                                              thermal_attr_group.name);
-               if (cpu_has(c, X86_FEATURE_PLN))
+               if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
                        err = sysfs_add_file_to_group(&dev->kobj,
                                        &dev_attr_package_power_limit_count.attr,
                                        thermal_attr_group.name);
@@ -405,7 +406,7 @@ static void intel_thermal_interrupt(void)
                                CORE_LEVEL) != 0)
                mce_log_therm_throt_event(msr_val);
 
-       if (this_cpu_has(X86_FEATURE_PLN))
+       if (this_cpu_has(X86_FEATURE_PLN) && int_pln_enable)
                therm_throt_process(msr_val & THERM_STATUS_POWER_LIMIT,
                                        POWER_LIMIT_EVENT,
                                        CORE_LEVEL);
@@ -417,7 +418,7 @@ static void intel_thermal_interrupt(void)
                therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT,
                                        THERMAL_THROTTLING_EVENT,
                                        PACKAGE_LEVEL);
-               if (this_cpu_has(X86_FEATURE_PLN))
+               if (this_cpu_has(X86_FEATURE_PLN) && int_pln_enable)
                        therm_throt_process(msr_val &
                                        PACKAGE_THERM_STATUS_POWER_LIMIT,
                                        POWER_LIMIT_EVENT,
@@ -433,15 +434,26 @@ static void unexpected_thermal_interrupt(void)
 
 static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt;
 
-asmlinkage void smp_thermal_interrupt(struct pt_regs *regs)
+static inline void __smp_thermal_interrupt(void)
 {
-       irq_enter();
-       exit_idle();
        inc_irq_stat(irq_thermal_count);
        smp_thermal_vector();
-       irq_exit();
-       /* Ack only at the end to avoid potential reentry */
-       ack_APIC_irq();
+}
+
+asmlinkage void smp_thermal_interrupt(struct pt_regs *regs)
+{
+       entering_irq();
+       __smp_thermal_interrupt();
+       exiting_ack_irq();
+}
+
+asmlinkage void smp_trace_thermal_interrupt(struct pt_regs *regs)
+{
+       entering_irq();
+       trace_thermal_apic_entry(THERMAL_APIC_VECTOR);
+       __smp_thermal_interrupt();
+       trace_thermal_apic_exit(THERMAL_APIC_VECTOR);
+       exiting_ack_irq();
 }
 
 /* Thermal monitoring depends on APIC, ACPI and clock modulation */
@@ -525,9 +537,13 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
        apic_write(APIC_LVTTHMR, h);
 
        rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
-       if (cpu_has(c, X86_FEATURE_PLN))
+       if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable)
+               wrmsr(MSR_IA32_THERM_INTERRUPT,
+                       (l | (THERM_INT_LOW_ENABLE
+                       | THERM_INT_HIGH_ENABLE)) & ~THERM_INT_PLN_ENABLE, h);
+       else if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
                wrmsr(MSR_IA32_THERM_INTERRUPT,
-                     l | (THERM_INT_LOW_ENABLE
+                       l | (THERM_INT_LOW_ENABLE
                        | THERM_INT_HIGH_ENABLE | THERM_INT_PLN_ENABLE), h);
        else
                wrmsr(MSR_IA32_THERM_INTERRUPT,
@@ -535,9 +551,14 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
 
        if (cpu_has(c, X86_FEATURE_PTS)) {
                rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
-               if (cpu_has(c, X86_FEATURE_PLN))
+               if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable)
                        wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
-                             l | (PACKAGE_THERM_INT_LOW_ENABLE
+                               (l | (PACKAGE_THERM_INT_LOW_ENABLE
+                               | PACKAGE_THERM_INT_HIGH_ENABLE))
+                               & ~PACKAGE_THERM_INT_PLN_ENABLE, h);
+               else if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
+                       wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
+                               l | (PACKAGE_THERM_INT_LOW_ENABLE
                                | PACKAGE_THERM_INT_HIGH_ENABLE
                                | PACKAGE_THERM_INT_PLN_ENABLE), h);
                else