Loading Documentation/thermal/x86_pkg_temperature_thermal 0 → 100644 +47 −0 Original line number Diff line number Diff line Kernel driver: x86_pkg_temp_thermal =================== Supported chips: * x86: with package level thermal management (Verify using: CPUID.06H:EAX[bit 6] =1) Authors: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Reference --- Intel® 64 and IA-32 Architectures Software Developer’s Manual (Jan, 2013): Chapter 14.6: PACKAGE LEVEL THERMAL MANAGEMENT Description --------- This driver register CPU digital temperature package level sensor as a thermal zone with maximum two user mode configurable trip points. Number of trip points depends on the capability of the package. Once the trip point is violated, user mode can receive notification via thermal notification mechanism and can take any action to control temperature. Threshold management -------------------- Each package will register as a thermal zone under /sys/class/thermal. Example: /sys/class/thermal/thermal_zone1 This contains two trip points: - trip_point_0_temp - trip_point_1_temp User can set any temperature between 0 to TJ-Max temperature. Temperature units are in milli-degree Celsius. Refer to "Documentation/thermal/sysfs-api.txt" for thermal sys-fs details. Any value other than 0 in these trip points, can trigger thermal notifications. Setting 0, stops sending thermal notifications. Thermal notifications: To get kobject-uevent notifications, set the thermal zone policy to "user_space". For example: echo -n "user_space" > policy arch/x86/include/asm/mce.h +7 −0 Original line number Diff line number Diff line Loading @@ -214,6 +214,13 @@ void mce_log_therm_throt_event(__u64 status); /* Interrupt Handler for core thermal thresholds */ extern int (*platform_thermal_notify)(__u64 msr_val); /* Interrupt Handler for package thermal thresholds */ extern int (*platform_thermal_package_notify)(__u64 msr_val); /* Callback support of rate control, return true, if * callback has rate control */ extern bool (*platform_thermal_package_rate_control)(void); #ifdef CONFIG_X86_THERMAL_VECTOR extern void mcheck_intel_therm_init(void); #else Loading arch/x86/kernel/cpu/mcheck/therm_throt.c +59 −4 Original line number Diff line number Diff line Loading @@ -54,12 +54,24 @@ struct thermal_state { struct _thermal_state package_power_limit; struct _thermal_state core_thresh0; struct _thermal_state core_thresh1; struct _thermal_state pkg_thresh0; struct _thermal_state pkg_thresh1; }; /* Callback to handle core threshold interrupts */ int (*platform_thermal_notify)(__u64 msr_val); EXPORT_SYMBOL(platform_thermal_notify); /* Callback to handle core package threshold_interrupts */ int (*platform_thermal_package_notify)(__u64 msr_val); EXPORT_SYMBOL_GPL(platform_thermal_package_notify); /* Callback support of rate control, return true, if * callback has rate control */ bool (*platform_thermal_package_rate_control)(void); EXPORT_SYMBOL_GPL(platform_thermal_package_rate_control); static DEFINE_PER_CPU(struct thermal_state, thermal_state); static atomic_t therm_throt_en = ATOMIC_INIT(0); Loading Loading @@ -203,19 +215,25 @@ static int therm_throt_process(bool new_event, int event, int level) return 0; } static int thresh_event_valid(int event) static int thresh_event_valid(int level, int event) { struct _thermal_state *state; unsigned int this_cpu = smp_processor_id(); struct thermal_state *pstate = &per_cpu(thermal_state, this_cpu); u64 now = get_jiffies_64(); state = (event == 0) ? &pstate->core_thresh0 : &pstate->core_thresh1; if (level == PACKAGE_LEVEL) state = (event == 0) ? &pstate->pkg_thresh0 : &pstate->pkg_thresh1; else state = (event == 0) ? &pstate->core_thresh0 : &pstate->core_thresh1; if (time_before64(now, state->next_check)) return 0; state->next_check = now + CHECK_INTERVAL; return 1; } Loading Loading @@ -321,6 +339,39 @@ device_initcall(thermal_throttle_init_device); #endif /* CONFIG_SYSFS */ static void notify_package_thresholds(__u64 msr_val) { bool notify_thres_0 = false; bool notify_thres_1 = false; if (!platform_thermal_package_notify) return; /* lower threshold check */ if (msr_val & THERM_LOG_THRESHOLD0) notify_thres_0 = true; /* higher threshold check */ if (msr_val & THERM_LOG_THRESHOLD1) notify_thres_1 = true; if (!notify_thres_0 && !notify_thres_1) return; if (platform_thermal_package_rate_control && platform_thermal_package_rate_control()) { /* Rate control is implemented in callback */ platform_thermal_package_notify(msr_val); return; } /* lower threshold reached */ if (notify_thres_0 && thresh_event_valid(PACKAGE_LEVEL, 0)) platform_thermal_package_notify(msr_val); /* higher threshold reached */ if (notify_thres_1 && thresh_event_valid(PACKAGE_LEVEL, 1)) platform_thermal_package_notify(msr_val); } static void notify_thresholds(__u64 msr_val) { /* check whether the interrupt handler is defined; Loading @@ -330,10 +381,12 @@ static void notify_thresholds(__u64 msr_val) return; /* lower threshold reached */ if ((msr_val & THERM_LOG_THRESHOLD0) && thresh_event_valid(0)) if ((msr_val & THERM_LOG_THRESHOLD0) && thresh_event_valid(CORE_LEVEL, 0)) platform_thermal_notify(msr_val); /* higher threshold reached */ if ((msr_val & THERM_LOG_THRESHOLD1) && thresh_event_valid(1)) if ((msr_val & THERM_LOG_THRESHOLD1) && thresh_event_valid(CORE_LEVEL, 1)) platform_thermal_notify(msr_val); } Loading @@ -359,6 +412,8 @@ static void intel_thermal_interrupt(void) if (this_cpu_has(X86_FEATURE_PTS)) { rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val); /* check violations of package thermal thresholds */ notify_package_thresholds(msr_val); therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT, THERMAL_THROTTLING_EVENT, PACKAGE_LEVEL); Loading drivers/thermal/Kconfig +13 −0 Original line number Diff line number Diff line Loading @@ -169,7 +169,20 @@ config INTEL_POWERCLAMP enforce idle time which results in more package C-state residency. The user interface is exposed via generic thermal framework. config X86_PKG_TEMP_THERMAL tristate "X86 package temperature thermal driver" depends on THERMAL depends on X86 select THERMAL_GOV_USER_SPACE default m help Enable this to register CPU digital sensor for package temperature as thermal zone. Each package will have its own thermal zone. There are two trip points which can be set by user to get notifications via thermal notification methods. menu "Texas Instruments thermal drivers" source "drivers/thermal/ti-soc-thermal/Kconfig" endmenu endif drivers/thermal/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -23,4 +23,5 @@ obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ Loading
Documentation/thermal/x86_pkg_temperature_thermal 0 → 100644 +47 −0 Original line number Diff line number Diff line Kernel driver: x86_pkg_temp_thermal =================== Supported chips: * x86: with package level thermal management (Verify using: CPUID.06H:EAX[bit 6] =1) Authors: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Reference --- Intel® 64 and IA-32 Architectures Software Developer’s Manual (Jan, 2013): Chapter 14.6: PACKAGE LEVEL THERMAL MANAGEMENT Description --------- This driver register CPU digital temperature package level sensor as a thermal zone with maximum two user mode configurable trip points. Number of trip points depends on the capability of the package. Once the trip point is violated, user mode can receive notification via thermal notification mechanism and can take any action to control temperature. Threshold management -------------------- Each package will register as a thermal zone under /sys/class/thermal. Example: /sys/class/thermal/thermal_zone1 This contains two trip points: - trip_point_0_temp - trip_point_1_temp User can set any temperature between 0 to TJ-Max temperature. Temperature units are in milli-degree Celsius. Refer to "Documentation/thermal/sysfs-api.txt" for thermal sys-fs details. Any value other than 0 in these trip points, can trigger thermal notifications. Setting 0, stops sending thermal notifications. Thermal notifications: To get kobject-uevent notifications, set the thermal zone policy to "user_space". For example: echo -n "user_space" > policy
arch/x86/include/asm/mce.h +7 −0 Original line number Diff line number Diff line Loading @@ -214,6 +214,13 @@ void mce_log_therm_throt_event(__u64 status); /* Interrupt Handler for core thermal thresholds */ extern int (*platform_thermal_notify)(__u64 msr_val); /* Interrupt Handler for package thermal thresholds */ extern int (*platform_thermal_package_notify)(__u64 msr_val); /* Callback support of rate control, return true, if * callback has rate control */ extern bool (*platform_thermal_package_rate_control)(void); #ifdef CONFIG_X86_THERMAL_VECTOR extern void mcheck_intel_therm_init(void); #else Loading
arch/x86/kernel/cpu/mcheck/therm_throt.c +59 −4 Original line number Diff line number Diff line Loading @@ -54,12 +54,24 @@ struct thermal_state { struct _thermal_state package_power_limit; struct _thermal_state core_thresh0; struct _thermal_state core_thresh1; struct _thermal_state pkg_thresh0; struct _thermal_state pkg_thresh1; }; /* Callback to handle core threshold interrupts */ int (*platform_thermal_notify)(__u64 msr_val); EXPORT_SYMBOL(platform_thermal_notify); /* Callback to handle core package threshold_interrupts */ int (*platform_thermal_package_notify)(__u64 msr_val); EXPORT_SYMBOL_GPL(platform_thermal_package_notify); /* Callback support of rate control, return true, if * callback has rate control */ bool (*platform_thermal_package_rate_control)(void); EXPORT_SYMBOL_GPL(platform_thermal_package_rate_control); static DEFINE_PER_CPU(struct thermal_state, thermal_state); static atomic_t therm_throt_en = ATOMIC_INIT(0); Loading Loading @@ -203,19 +215,25 @@ static int therm_throt_process(bool new_event, int event, int level) return 0; } static int thresh_event_valid(int event) static int thresh_event_valid(int level, int event) { struct _thermal_state *state; unsigned int this_cpu = smp_processor_id(); struct thermal_state *pstate = &per_cpu(thermal_state, this_cpu); u64 now = get_jiffies_64(); state = (event == 0) ? &pstate->core_thresh0 : &pstate->core_thresh1; if (level == PACKAGE_LEVEL) state = (event == 0) ? &pstate->pkg_thresh0 : &pstate->pkg_thresh1; else state = (event == 0) ? &pstate->core_thresh0 : &pstate->core_thresh1; if (time_before64(now, state->next_check)) return 0; state->next_check = now + CHECK_INTERVAL; return 1; } Loading Loading @@ -321,6 +339,39 @@ device_initcall(thermal_throttle_init_device); #endif /* CONFIG_SYSFS */ static void notify_package_thresholds(__u64 msr_val) { bool notify_thres_0 = false; bool notify_thres_1 = false; if (!platform_thermal_package_notify) return; /* lower threshold check */ if (msr_val & THERM_LOG_THRESHOLD0) notify_thres_0 = true; /* higher threshold check */ if (msr_val & THERM_LOG_THRESHOLD1) notify_thres_1 = true; if (!notify_thres_0 && !notify_thres_1) return; if (platform_thermal_package_rate_control && platform_thermal_package_rate_control()) { /* Rate control is implemented in callback */ platform_thermal_package_notify(msr_val); return; } /* lower threshold reached */ if (notify_thres_0 && thresh_event_valid(PACKAGE_LEVEL, 0)) platform_thermal_package_notify(msr_val); /* higher threshold reached */ if (notify_thres_1 && thresh_event_valid(PACKAGE_LEVEL, 1)) platform_thermal_package_notify(msr_val); } static void notify_thresholds(__u64 msr_val) { /* check whether the interrupt handler is defined; Loading @@ -330,10 +381,12 @@ static void notify_thresholds(__u64 msr_val) return; /* lower threshold reached */ if ((msr_val & THERM_LOG_THRESHOLD0) && thresh_event_valid(0)) if ((msr_val & THERM_LOG_THRESHOLD0) && thresh_event_valid(CORE_LEVEL, 0)) platform_thermal_notify(msr_val); /* higher threshold reached */ if ((msr_val & THERM_LOG_THRESHOLD1) && thresh_event_valid(1)) if ((msr_val & THERM_LOG_THRESHOLD1) && thresh_event_valid(CORE_LEVEL, 1)) platform_thermal_notify(msr_val); } Loading @@ -359,6 +412,8 @@ static void intel_thermal_interrupt(void) if (this_cpu_has(X86_FEATURE_PTS)) { rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val); /* check violations of package thermal thresholds */ notify_package_thresholds(msr_val); therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT, THERMAL_THROTTLING_EVENT, PACKAGE_LEVEL); Loading
drivers/thermal/Kconfig +13 −0 Original line number Diff line number Diff line Loading @@ -169,7 +169,20 @@ config INTEL_POWERCLAMP enforce idle time which results in more package C-state residency. The user interface is exposed via generic thermal framework. config X86_PKG_TEMP_THERMAL tristate "X86 package temperature thermal driver" depends on THERMAL depends on X86 select THERMAL_GOV_USER_SPACE default m help Enable this to register CPU digital sensor for package temperature as thermal zone. Each package will have its own thermal zone. There are two trip points which can be set by user to get notifications via thermal notification methods. menu "Texas Instruments thermal drivers" source "drivers/thermal/ti-soc-thermal/Kconfig" endmenu endif
drivers/thermal/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -23,4 +23,5 @@ obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/