diff options
-rw-r--r-- | drivers/thermal/intel/Kconfig | 7 | ||||
-rw-r--r-- | drivers/thermal/intel/Makefile | 1 | ||||
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/Kconfig | 1 | ||||
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 10 | ||||
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/processor_thermal_device.c | 119 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_menlow.c | 12 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_soc_dts_iosf.c | 35 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_tcc.c | 139 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_tcc_cooling.c | 37 | ||||
-rw-r--r-- | drivers/thermal/intel/x86_pkg_temp_thermal.c | 60 | ||||
-rw-r--r-- | include/linux/intel_tcc.h | 18 |
11 files changed, 232 insertions, 207 deletions
diff --git a/drivers/thermal/intel/Kconfig b/drivers/thermal/intel/Kconfig index f0c845679250..fd41c810629b 100644 --- a/drivers/thermal/intel/Kconfig +++ b/drivers/thermal/intel/Kconfig @@ -12,11 +12,16 @@ config X86_THERMAL_VECTOR def_bool y depends on X86 && CPU_SUP_INTEL && X86_LOCAL_APIC +config INTEL_TCC + bool + depends on X86 + config X86_PKG_TEMP_THERMAL tristate "X86 package temperature thermal driver" depends on X86_THERMAL_VECTOR select THERMAL_GOV_USER_SPACE select THERMAL_WRITABLE_TRIPS + select INTEL_TCC default m help Enable this to register CPU digital sensor for package temperature as @@ -28,6 +33,7 @@ config INTEL_SOC_DTS_IOSF_CORE tristate depends on X86 && PCI select IOSF_MBI + select INTEL_TCC help This is becoming a common feature for Intel SoCs to expose the additional digital temperature sensors (DTSs) using side band interface (IOSF). This @@ -83,6 +89,7 @@ config INTEL_PCH_THERMAL config INTEL_TCC_COOLING tristate "Intel TCC offset cooling Driver" depends on X86 + select INTEL_TCC help Enable this to support system cooling by adjusting the effective TCC activation temperature via the TCC Offset register, which is widely diff --git a/drivers/thermal/intel/Makefile b/drivers/thermal/intel/Makefile index 9a8d8054f316..5d8833c82ab6 100644 --- a/drivers/thermal/intel/Makefile +++ b/drivers/thermal/intel/Makefile @@ -2,6 +2,7 @@ # # Makefile for various Intel thermal drivers. +obj-$(CONFIG_INTEL_TCC) += intel_tcc.o obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o obj-$(CONFIG_INTEL_SOC_DTS_IOSF_CORE) += intel_soc_dts_iosf.o diff --git a/drivers/thermal/intel/int340x_thermal/Kconfig b/drivers/thermal/intel/int340x_thermal/Kconfig index 5d046de96a5d..0f511917e0e1 100644 --- a/drivers/thermal/intel/int340x_thermal/Kconfig +++ b/drivers/thermal/intel/int340x_thermal/Kconfig @@ -10,6 +10,7 @@ config INT340X_THERMAL select ACPI_THERMAL_REL select ACPI_FAN select INTEL_SOC_DTS_IOSF_CORE + select INTEL_TCC select PROC_THERMAL_MMIO_RAPL if POWERCAP help Newer laptops and tablets that use ACPI may have thermal sensors and diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c index db8a6f63657d..c1fc4a78607c 100644 --- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c @@ -130,10 +130,7 @@ static ssize_t available_uuids_show(struct device *dev, for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; i++) { if (priv->uuid_bitmap & (1 << i)) - length += scnprintf(&buf[length], - PAGE_SIZE - length, - "%s\n", - int3400_thermal_uuids[i]); + length += sysfs_emit_at(buf, length, int3400_thermal_uuids[i]); } return length; @@ -151,10 +148,7 @@ static ssize_t current_uuid_show(struct device *dev, for (i = 0; i <= INT3400_THERMAL_CRITICAL; i++) { if (priv->os_uuid_mask & BIT(i)) - length += scnprintf(&buf[length], - PAGE_SIZE - length, - "%s\n", - int3400_thermal_uuids[i]); + length += sysfs_emit_at(buf, length, int3400_thermal_uuids[i]); } if (length) diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c index 317703027ce9..a1dc18be7609 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c @@ -4,6 +4,7 @@ * Copyright (c) 2014, Intel Corporation. */ #include <linux/acpi.h> +#include <linux/intel_tcc.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> @@ -68,54 +69,17 @@ static const struct attribute_group power_limit_attribute_group = { .name = "power_limits" }; -static int tcc_get_offset(void) -{ - u64 val; - int err; - - err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val); - if (err) - return err; - - return (val >> 24) & 0x3f; -} - static ssize_t tcc_offset_degree_celsius_show(struct device *dev, struct device_attribute *attr, char *buf) { - int tcc; - - tcc = tcc_get_offset(); - if (tcc < 0) - return tcc; + int offset; - return sprintf(buf, "%d\n", tcc); -} - -static int tcc_offset_update(unsigned int tcc) -{ - u64 val; - int err; - - if (tcc > 63) - return -EINVAL; - - err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val); - if (err) - return err; - - if (val & BIT(31)) - return -EPERM; - - val &= ~GENMASK_ULL(29, 24); - val |= (tcc & 0x3f) << 24; - - err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val); - if (err) - return err; + offset = intel_tcc_get_offset(-1); + if (offset < 0) + return offset; - return 0; + return sprintf(buf, "%d\n", offset); } static ssize_t tcc_offset_degree_celsius_store(struct device *dev, @@ -136,7 +100,7 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev, if (kstrtouint(buf, 0, &tcc)) return -EINVAL; - err = tcc_offset_update(tcc); + err = intel_tcc_set_offset(-1, tcc); if (err) return err; @@ -145,66 +109,25 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev, static DEVICE_ATTR_RW(tcc_offset_degree_celsius); -static int stored_tjmax; /* since it is fixed, we can have local storage */ - -static int get_tjmax(void) -{ - u32 eax, edx; - u32 val; - int err; - - err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); - if (err) - return err; - - val = (eax >> 16) & 0xff; - if (val) - return val; - - return -EINVAL; -} - -static int read_temp_msr(int *temp) +static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone, + int *temp) { int cpu; - u32 eax, edx; - int err; - unsigned long curr_temp_off = 0; + int curr_temp; *temp = 0; for_each_online_cpu(cpu) { - err = rdmsr_safe_on_cpu(cpu, MSR_IA32_THERM_STATUS, &eax, - &edx); - if (err) - goto err_ret; - else { - if (eax & 0x80000000) { - curr_temp_off = (eax >> 16) & 0x7f; - if (!*temp || curr_temp_off < *temp) - *temp = curr_temp_off; - } else { - err = -EINVAL; - goto err_ret; - } - } + curr_temp = intel_tcc_get_temp(cpu, false); + if (curr_temp < 0) + return curr_temp; + if (!*temp || curr_temp > *temp) + *temp = curr_temp; } - return 0; -err_ret: - return err; -} - -static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone, - int *temp) -{ - int ret; - - ret = read_temp_msr(temp); - if (!ret) - *temp = (stored_tjmax - *temp) * 1000; + *temp *= 1000; - return ret; + return 0; } static int proc_thermal_read_ppcc(struct proc_thermal_device *proc_priv) @@ -298,8 +221,7 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv) status = acpi_evaluate_integer(adev->handle, "_TMP", NULL, &tmp); if (ACPI_FAILURE(status)) { /* there is no _TMP method, add local method */ - stored_tjmax = get_tjmax(); - if (stored_tjmax > 0) + if (intel_tcc_get_tjmax(-1) > 0) get_temp = proc_thermal_get_zone_temp; } @@ -352,7 +274,7 @@ static int tcc_offset_save = -1; int proc_thermal_suspend(struct device *dev) { - tcc_offset_save = tcc_get_offset(); + tcc_offset_save = intel_tcc_get_offset(-1); if (tcc_offset_save < 0) dev_warn(dev, "failed to save offset (%d)\n", tcc_offset_save); @@ -369,7 +291,7 @@ int proc_thermal_resume(struct device *dev) /* Do not update if saving failed */ if (tcc_offset_save >= 0) - tcc_offset_update(tcc_offset_save); + intel_tcc_set_offset(-1, tcc_offset_save); return 0; } @@ -456,6 +378,7 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device * } EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove); +MODULE_IMPORT_NS(INTEL_TCC); MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/intel/intel_menlow.c b/drivers/thermal/intel/intel_menlow.c index 3f885b08a490..5a6ad0552311 100644 --- a/drivers/thermal/intel/intel_menlow.c +++ b/drivers/thermal/intel/intel_menlow.c @@ -232,9 +232,9 @@ static DEFINE_MUTEX(intel_menlow_attr_lock); /* * sensor_get_auxtrip - get the current auxtrip value from sensor - * @name: Thermalzone name - * @auxtype : AUX0/AUX1 - * @buf: syfs buffer + * @handle: Object handle + * @index : GET_AUX1/GET_AUX0 + * @value : The address will be fill by the value */ static int sensor_get_auxtrip(acpi_handle handle, int index, unsigned long long *value) @@ -254,9 +254,9 @@ static int sensor_get_auxtrip(acpi_handle handle, int index, /* * sensor_set_auxtrip - set the new auxtrip value to sensor - * @name: Thermalzone name - * @auxtype : AUX0/AUX1 - * @buf: syfs buffer + * @handle: Object handle + * @index : GET_AUX1/GET_AUX0 + * @value : The value will be set */ static int sensor_set_auxtrip(acpi_handle handle, int index, int value) { diff --git a/drivers/thermal/intel/intel_soc_dts_iosf.c b/drivers/thermal/intel/intel_soc_dts_iosf.c index 342b0bb5a56d..8c26f7b2316b 100644 --- a/drivers/thermal/intel/intel_soc_dts_iosf.c +++ b/drivers/thermal/intel/intel_soc_dts_iosf.c @@ -7,6 +7,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/bitops.h> +#include <linux/intel_tcc.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/interrupt.h> @@ -45,32 +46,6 @@ /* DTS0 and DTS 1 */ #define SOC_MAX_DTS_SENSORS 2 -static int get_tj_max(u32 *tj_max) -{ - u32 eax, edx; - u32 val; - int err; - - err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); - if (err) - goto err_ret; - else { - val = (eax >> 16) & 0xff; - if (val) - *tj_max = val * 1000; - else { - err = -EINVAL; - goto err_ret; - } - } - - return 0; -err_ret: - *tj_max = 0; - - return err; -} - static int sys_get_trip_temp(struct thermal_zone_device *tzd, int trip, int *temp) { @@ -405,7 +380,7 @@ struct intel_soc_dts_sensors *intel_soc_dts_iosf_init( { struct intel_soc_dts_sensors *sensors; bool notification; - u32 tj_max; + int tj_max; int ret; int i; @@ -415,8 +390,9 @@ struct intel_soc_dts_sensors *intel_soc_dts_iosf_init( if (!trip_count || read_only_trip_count > trip_count) return ERR_PTR(-EINVAL); - if (get_tj_max(&tj_max)) - return ERR_PTR(-EINVAL); + tj_max = intel_tcc_get_tjmax(-1); + if (tj_max < 0) + return ERR_PTR(tj_max); sensors = kzalloc(sizeof(*sensors), GFP_KERNEL); if (!sensors) @@ -475,4 +451,5 @@ void intel_soc_dts_iosf_exit(struct intel_soc_dts_sensors *sensors) } EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_exit); +MODULE_IMPORT_NS(INTEL_TCC); MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/intel/intel_tcc.c b/drivers/thermal/intel/intel_tcc.c new file mode 100644 index 000000000000..2e5c741c41ca --- /dev/null +++ b/drivers/thermal/intel/intel_tcc.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * intel_tcc.c - Library for Intel TCC (thermal control circuitry) MSR access + * Copyright (c) 2022, Intel Corporation. + */ + +#include <linux/errno.h> +#include <linux/intel_tcc.h> +#include <asm/msr.h> + +/** + * intel_tcc_get_tjmax() - returns the default TCC activation Temperature + * @cpu: cpu that the MSR should be run on, nagative value means any cpu. + * + * Get the TjMax value, which is the default thermal throttling or TCC + * activation temperature in degrees C. + * + * Return: Tjmax value in degrees C on success, negative error code otherwise. + */ +int intel_tcc_get_tjmax(int cpu) +{ + u32 low, high; + int val, err; + + if (cpu < 0) + err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &low, &high); + else + err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &low, &high); + if (err) + return err; + + val = (low >> 16) & 0xff; + + return val ? val : -ENODATA; +} +EXPORT_SYMBOL_NS_GPL(intel_tcc_get_tjmax, INTEL_TCC); + +/** + * intel_tcc_get_offset() - returns the TCC Offset value to Tjmax + * @cpu: cpu that the MSR should be run on, nagative value means any cpu. + * + * Get the TCC offset value to Tjmax. The effective thermal throttling or TCC + * activation temperature equals "Tjmax" - "TCC Offset", in degrees C. + * + * Return: Tcc offset value in degrees C on success, negative error code otherwise. + */ +int intel_tcc_get_offset(int cpu) +{ + u32 low, high; + int err; + + if (cpu < 0) + err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &low, &high); + else + err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &low, &high); + if (err) + return err; + + return (low >> 24) & 0x3f; +} +EXPORT_SYMBOL_NS_GPL(intel_tcc_get_offset, INTEL_TCC); + +/** + * intel_tcc_set_offset() - set the TCC offset value to Tjmax + * @cpu: cpu that the MSR should be run on, nagative value means any cpu. + * @offset: TCC offset value in degree C + * + * Set the TCC Offset value to Tjmax. The effective thermal throttling or TCC + * activation temperature equals "Tjmax" - "TCC Offset", in degree C. + * + * Return: On success returns 0, negative error code otherwise. + */ + +int intel_tcc_set_offset(int cpu, int offset) +{ + u32 low, high; + int err; + + if (offset < 0 || offset > 0x3f) + return -EINVAL; + + if (cpu < 0) + err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &low, &high); + else + err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &low, &high); + if (err) + return err; + + /* MSR Locked */ + if (low & BIT(31)) + return -EPERM; + + low &= ~(0x3f << 24); + low |= offset << 24; + + if (cpu < 0) + return wrmsr_safe(MSR_IA32_TEMPERATURE_TARGET, low, high); + else + return wrmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, low, high); +} +EXPORT_SYMBOL_NS_GPL(intel_tcc_set_offset, INTEL_TCC); + +/** + * intel_tcc_get_temp() - returns the current temperature + * @cpu: cpu that the MSR should be run on, nagative value means any cpu. + * @pkg: true: Package Thermal Sensor. false: Core Thermal Sensor. + * + * Get the current temperature returned by the CPU core/package level + * thermal sensor, in degrees C. + * + * Return: Temperature in degrees C on success, negative error code otherwise. + */ +int intel_tcc_get_temp(int cpu, bool pkg) +{ + u32 low, high; + u32 msr = pkg ? MSR_IA32_PACKAGE_THERM_STATUS : MSR_IA32_THERM_STATUS; + int tjmax, temp, err; + + tjmax = intel_tcc_get_tjmax(cpu); + if (tjmax < 0) + return tjmax; + + if (cpu < 0) + err = rdmsr_safe(msr, &low, &high); + else + err = rdmsr_safe_on_cpu(cpu, msr, &low, &high); + if (err) + return err; + + /* Temperature is beyond the valid thermal sensor range */ + if (!(low & BIT(31))) + return -ENODATA; + + temp = tjmax - ((low >> 16) & 0x7f); + + /* Do not allow negative CPU temperature */ + return temp >= 0 ? temp : -ENODATA; +} +EXPORT_SYMBOL_NS_GPL(intel_tcc_get_temp, INTEL_TCC); diff --git a/drivers/thermal/intel/intel_tcc_cooling.c b/drivers/thermal/intel/intel_tcc_cooling.c index a89e7e1890e4..e95f799454fe 100644 --- a/drivers/thermal/intel/intel_tcc_cooling.c +++ b/drivers/thermal/intel/intel_tcc_cooling.c @@ -7,12 +7,11 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/device.h> +#include <linux/intel_tcc.h> #include <linux/module.h> #include <linux/thermal.h> #include <asm/cpu_device_id.h> -#define TCC_SHIFT 24 -#define TCC_MASK (0x3fULL<<24) #define TCC_PROGRAMMABLE BIT(30) #define TCC_LOCKED BIT(31) @@ -21,47 +20,26 @@ static struct thermal_cooling_device *tcc_cdev; static int tcc_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) { - *state = TCC_MASK >> TCC_SHIFT; - return 0; -} - -static int tcc_offset_update(int tcc) -{ - u64 val; - int err; - - err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val); - if (err) - return err; - - val &= ~TCC_MASK; - val |= tcc << TCC_SHIFT; - - err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val); - if (err) - return err; - + *state = 0x3f; return 0; } static int tcc_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) { - u64 val; - int err; + int offset = intel_tcc_get_offset(-1); - err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val); - if (err) - return err; + if (offset < 0) + return offset; - *state = (val & TCC_MASK) >> TCC_SHIFT; + *state = offset; return 0; } static int tcc_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) { - return tcc_offset_update(state); + return intel_tcc_set_offset(-1, (int)state); } static const struct thermal_cooling_device_ops tcc_cooling_ops = { @@ -140,6 +118,7 @@ static void __exit tcc_cooling_exit(void) module_exit(tcc_cooling_exit) +MODULE_IMPORT_NS(INTEL_TCC); MODULE_DESCRIPTION("TCC offset cooling device Driver"); MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index 494f25250c2d..1c2de84742df 100644 --- a/drivers/thermal/intel/x86_pkg_temp_thermal.c +++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c @@ -7,6 +7,7 @@ #include <linux/module.h> #include <linux/init.h> +#include <linux/intel_tcc.h> #include <linux/err.h> #include <linux/param.h> #include <linux/device.h> @@ -48,7 +49,6 @@ MODULE_PARM_DESC(notify_delay_ms, struct zone_device { int cpu; bool work_scheduled; - u32 tj_max; u32 msr_pkg_therm_low; u32 msr_pkg_therm_high; struct delayed_work work; @@ -105,38 +105,18 @@ static struct zone_device *pkg_temp_thermal_get_dev(unsigned int cpu) return NULL; } -/* -* tj-max is interesting because threshold is set relative to this -* temperature. -*/ -static int get_tj_max(int cpu, u32 *tj_max) -{ - u32 eax, edx, val; - int err; - - err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); - if (err) - return err; - - val = (eax >> 16) & 0xff; - *tj_max = val * 1000; - - return val ? 0 : -EINVAL; -} - static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) { struct zone_device *zonedev = tzd->devdata; - u32 eax, edx; + int val; - rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_STATUS, - &eax, &edx); - if (eax & 0x80000000) { - *temp = zonedev->tj_max - ((eax >> 16) & 0x7f) * 1000; - pr_debug("sys_get_curr_temp %d\n", *temp); - return 0; - } - return -EINVAL; + val = intel_tcc_get_temp(zonedev->cpu, true); + if (val < 0) + return val; + + *temp = val * 1000; + pr_debug("sys_get_curr_temp %d\n", *temp); + return 0; } static int @@ -144,9 +124,14 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) { struct zone_device *zonedev = tzd->devdata; u32 l, h, mask, shift, intr; - int ret; + int tj_max, ret; - if (trip >= MAX_NUMBER_OF_TRIPS || temp >= zonedev->tj_max) + tj_max = intel_tcc_get_tjmax(zonedev->cpu); + if (tj_max < 0) + return tj_max; + tj_max *= 1000; + + if (trip >= MAX_NUMBER_OF_TRIPS || temp >= tj_max) return -EINVAL; ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, @@ -171,7 +156,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) if (!temp) { l &= ~intr; } else { - l |= (zonedev->tj_max - temp)/1000 << shift; + l |= (tj_max - temp)/1000 << shift; l |= intr; } @@ -326,9 +311,10 @@ static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int static int pkg_temp_thermal_device_add(unsigned int cpu) { int id = topology_logical_die_id(cpu); - u32 tj_max, eax, ebx, ecx, edx; + u32 eax, ebx, ecx, edx; struct zone_device *zonedev; int thres_count, err; + int tj_max; if (id >= max_id) return -ENOMEM; @@ -340,9 +326,9 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS); - err = get_tj_max(cpu, &tj_max); - if (err) - return err; + tj_max = intel_tcc_get_tjmax(cpu); + if (tj_max < 0) + return tj_max; zonedev = kzalloc(sizeof(*zonedev), GFP_KERNEL); if (!zonedev) @@ -356,7 +342,6 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn); zonedev->cpu = cpu; - zonedev->tj_max = tj_max; zonedev->tzone = thermal_zone_device_register_with_trips("x86_pkg_temp", zonedev->trips, thres_count, (thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01, @@ -545,6 +530,7 @@ static void __exit pkg_temp_thermal_exit(void) } module_exit(pkg_temp_thermal_exit) +MODULE_IMPORT_NS(INTEL_TCC); MODULE_DESCRIPTION("X86 PKG TEMP Thermal Driver"); MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); MODULE_LICENSE("GPL v2"); diff --git a/include/linux/intel_tcc.h b/include/linux/intel_tcc.h new file mode 100644 index 000000000000..f422612c28d6 --- /dev/null +++ b/include/linux/intel_tcc.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * header for Intel TCC (thermal control circuitry) library + * + * Copyright (C) 2022 Intel Corporation. + */ + +#ifndef __INTEL_TCC_H__ +#define __INTEL_TCC_H__ + +#include <linux/types.h> + +int intel_tcc_get_tjmax(int cpu); +int intel_tcc_get_offset(int cpu); +int intel_tcc_set_offset(int cpu, int offset); +int intel_tcc_get_temp(int cpu, bool pkg); + +#endif /* __INTEL_TCC_H__ */ |