x86, hwmon: Add core threshold notification to therm_throt.c

This patch adds code to therm_throt.c to notify core thermal threshold
events. These thresholds are supported by the IA32_THERM_INTERRUPT register.
The status/log for the same is monitored using the IA32_THERM_STATUS register.
The necessary #defines are in msr-index.h. A call back is added to mce.h, to
further notify the thermal stack, about the threshold events.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
LKML-Reference: <D6D887BA8C9DFF48B5233887EF04654105C1251710@bgsmsx502.gar.corp.intel.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>

authored by R, Durgadoss and committed by H. Peter Anvin 9e76a97e 387c31c7

+55
+3
arch/x86/include/asm/mce.h
··· 223 223 224 224 void mce_log_therm_throt_event(__u64 status); 225 225 226 + /* Interrupt Handler for core thermal thresholds */ 227 + extern int (*platform_thermal_notify)(__u64 msr_val); 228 + 226 229 #ifdef CONFIG_X86_THERMAL_VECTOR 227 230 extern void mcheck_intel_therm_init(void); 228 231 #else
+12
arch/x86/include/asm/msr-index.h
··· 253 253 #define PACKAGE_THERM_INT_LOW_ENABLE (1 << 1) 254 254 #define PACKAGE_THERM_INT_PLN_ENABLE (1 << 24) 255 255 256 + /* Thermal Thresholds Support */ 257 + #define THERM_INT_THRESHOLD0_ENABLE (1 << 15) 258 + #define THERM_SHIFT_THRESHOLD0 8 259 + #define THERM_MASK_THRESHOLD0 (0x7f << THERM_SHIFT_THRESHOLD0) 260 + #define THERM_INT_THRESHOLD1_ENABLE (1 << 23) 261 + #define THERM_SHIFT_THRESHOLD1 16 262 + #define THERM_MASK_THRESHOLD1 (0x7f << THERM_SHIFT_THRESHOLD1) 263 + #define THERM_STATUS_THRESHOLD0 (1 << 6) 264 + #define THERM_LOG_THRESHOLD0 (1 << 7) 265 + #define THERM_STATUS_THRESHOLD1 (1 << 8) 266 + #define THERM_LOG_THRESHOLD1 (1 << 9) 267 + 256 268 /* MISC_ENABLE bits: architectural */ 257 269 #define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) 258 270 #define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1)
+40
arch/x86/kernel/cpu/mcheck/therm_throt.c
··· 53 53 struct _thermal_state core_power_limit; 54 54 struct _thermal_state package_throttle; 55 55 struct _thermal_state package_power_limit; 56 + struct _thermal_state core_thresh0; 57 + struct _thermal_state core_thresh1; 56 58 }; 59 + 60 + /* Callback to handle core threshold interrupts */ 61 + int (*platform_thermal_notify)(__u64 msr_val); 57 62 58 63 static DEFINE_PER_CPU(struct thermal_state, thermal_state); 59 64 ··· 205 200 return 0; 206 201 } 207 202 203 + static int thresh_event_valid(int event) 204 + { 205 + struct _thermal_state *state; 206 + unsigned int this_cpu = smp_processor_id(); 207 + struct thermal_state *pstate = &per_cpu(thermal_state, this_cpu); 208 + u64 now = get_jiffies_64(); 209 + 210 + state = (event == 0) ? &pstate->core_thresh0 : &pstate->core_thresh1; 211 + 212 + if (time_before64(now, state->next_check)) 213 + return 0; 214 + 215 + state->next_check = now + CHECK_INTERVAL; 216 + return 1; 217 + } 218 + 208 219 #ifdef CONFIG_SYSFS 209 220 /* Add/Remove thermal_throttle interface for CPU device: */ 210 221 static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev, ··· 334 313 #define PACKAGE_THROTTLED ((__u64)2 << 62) 335 314 #define PACKAGE_POWER_LIMIT ((__u64)3 << 62) 336 315 316 + static void notify_thresholds(__u64 msr_val) 317 + { 318 + /* check whether the interrupt handler is defined; 319 + * otherwise simply return 320 + */ 321 + if (!platform_thermal_notify) 322 + return; 323 + 324 + /* lower threshold reached */ 325 + if ((msr_val & THERM_LOG_THRESHOLD0) && thresh_event_valid(0)) 326 + platform_thermal_notify(msr_val); 327 + /* higher threshold reached */ 328 + if ((msr_val & THERM_LOG_THRESHOLD1) && thresh_event_valid(1)) 329 + platform_thermal_notify(msr_val); 330 + } 331 + 337 332 /* Thermal transition interrupt handler */ 338 333 static void intel_thermal_interrupt(void) 339 334 { ··· 357 320 struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); 358 321 359 322 rdmsrl(MSR_IA32_THERM_STATUS, msr_val); 323 + 324 + /* Check for violation of core thermal thresholds*/ 325 + notify_thresholds(msr_val); 360 326 361 327 if (therm_throt_process(msr_val & THERM_STATUS_PROCHOT, 362 328 THERMAL_THROTTLING_EVENT,