summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/driver-api/thermal/intel_dptf.rst3
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_device.c5
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c9
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c57
-rw-r--r--drivers/thermal/intel/int340x_thermal/processor_thermal_wt_req.c7
-rw-r--r--drivers/thermal/intel/intel_pch_thermal.c1
-rw-r--r--drivers/thermal/intel/intel_tcc.c8
-rw-r--r--drivers/thermal/intel/intel_tcc_cooling.c13
-rw-r--r--drivers/thermal/intel/therm_throt.c5
-rw-r--r--drivers/thermal/intel/x86_pkg_temp_thermal.c3
-rw-r--r--tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c74
11 files changed, 133 insertions, 52 deletions
diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst
index 916bf0f36a03..4adfa1eb74db 100644
--- a/Documentation/driver-api/thermal/intel_dptf.rst
+++ b/Documentation/driver-api/thermal/intel_dptf.rst
@@ -375,6 +375,9 @@ based on the processor generation.
``workload_hint_enable`` (RW)
Enable firmware to send workload type hints to user space.
+``workload_slow_hint_enable`` (RW)
+ Enable firmware to send slow workload type hints to user space.
+
``notification_delay_ms`` (RW)
Minimum delay in milliseconds before firmware will notify OS. This is
for the rate control of notifications. This delay is between changing
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
index 48e7849d4816..f80dbe2ca7e4 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/sysfs.h>
#include <linux/thermal.h>
#include <asm/msr.h>
#include "int340x_thermal_zone.h"
@@ -23,7 +24,7 @@ static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \
{ \
struct proc_thermal_device *proc_dev = dev_get_drvdata(dev); \
\
- return sprintf(buf, "%lu\n",\
+ return sysfs_emit(buf, "%lu\n",\
(unsigned long)proc_dev->power_limits[index].suffix * 1000); \
}
@@ -143,7 +144,7 @@ static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
if (offset < 0)
return offset;
- return sprintf(buf, "%d\n", offset);
+ return sysfs_emit(buf, "%d\n", offset);
}
static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
index 589a3a71f0c4..bb9398dfa3c1 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
@@ -7,6 +7,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/sysfs.h>
#include "processor_thermal_device.h"
MODULE_IMPORT_NS("INT340X_THERMAL");
@@ -211,9 +212,9 @@ static ssize_t suffix##_show(struct device *dev,\
ret = (reg_val >> mmio_regs[ret].shift) & mmio_regs[ret].mask;\
err = get_mapped_string(mapping, attr->attr.name, ret, &str);\
if (!err)\
- return sprintf(buf, "%s\n", str);\
+ return sysfs_emit(buf, "%s\n", str);\
if (err == -EOPNOTSUPP)\
- return sprintf(buf, "%u\n", ret);\
+ return sysfs_emit(buf, "%u\n", ret);\
return err;\
}
@@ -398,7 +399,7 @@ static ssize_t rfi_restriction_show(struct device *dev,
if (ret)
return ret;
- return sprintf(buf, "%llu\n", resp);
+ return sysfs_emit(buf, "%llu\n", resp);
}
static ssize_t ddr_data_rate_show(struct device *dev,
@@ -413,7 +414,7 @@ static ssize_t ddr_data_rate_show(struct device *dev,
if (ret)
return ret;
- return sprintf(buf, "%llu\n", resp);
+ return sysfs_emit(buf, "%llu\n", resp);
}
static DEVICE_ATTR_RW(rfi_restriction);
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c
index 68e8391af8f4..f8c33e8e5b7a 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_hint.c
@@ -34,6 +34,7 @@
#define SOC_WT GENMASK_ULL(47, 40)
+#define SOC_WT_SLOW_PREDICTION_INT_ENABLE_BIT 22
#define SOC_WT_PREDICTION_INT_ENABLE_BIT 23
#define SOC_WT_PREDICTION_INT_ACTIVE BIT(2)
@@ -47,6 +48,7 @@ static u16 notify_delay_ms = 1024;
static DEFINE_MUTEX(wt_lock);
static u8 wt_enable;
+static u8 wt_slow_enable;
/* Show current predicted workload type index */
static ssize_t workload_type_index_show(struct device *dev,
@@ -59,7 +61,7 @@ static ssize_t workload_type_index_show(struct device *dev,
int wt;
mutex_lock(&wt_lock);
- if (!wt_enable) {
+ if (!wt_enable && !wt_slow_enable) {
mutex_unlock(&wt_lock);
return -ENODATA;
}
@@ -84,9 +86,9 @@ static ssize_t workload_hint_enable_show(struct device *dev,
return sysfs_emit(buf, "%d\n", wt_enable);
}
-static ssize_t workload_hint_enable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
+static ssize_t workload_hint_enable(struct device *dev, u8 enable_bit, u8 *status,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
struct pci_dev *pdev = to_pci_dev(dev);
u8 mode;
@@ -99,17 +101,17 @@ static ssize_t workload_hint_enable_store(struct device *dev,
if (mode)
ret = processor_thermal_mbox_interrupt_config(pdev, true,
- SOC_WT_PREDICTION_INT_ENABLE_BIT,
+ enable_bit,
notify_delay);
else
ret = processor_thermal_mbox_interrupt_config(pdev, false,
- SOC_WT_PREDICTION_INT_ENABLE_BIT, 0);
+ enable_bit, 0);
if (ret)
goto ret_enable_store;
ret = size;
- wt_enable = mode;
+ *status = mode;
ret_enable_store:
mutex_unlock(&wt_lock);
@@ -117,8 +119,28 @@ ret_enable_store:
return ret;
}
+static ssize_t workload_hint_enable_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ return workload_hint_enable(dev, SOC_WT_PREDICTION_INT_ENABLE_BIT, &wt_enable,
+ attr, buf, size);
+}
static DEVICE_ATTR_RW(workload_hint_enable);
+static ssize_t workload_slow_hint_enable_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sysfs_emit(buf, "%d\n", wt_slow_enable);
+}
+
+static ssize_t workload_slow_hint_enable_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ return workload_hint_enable(dev, SOC_WT_SLOW_PREDICTION_INT_ENABLE_BIT, &wt_slow_enable,
+ attr, buf, size);
+}
+static DEVICE_ATTR_RW(workload_slow_hint_enable);
+
static ssize_t notification_delay_ms_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -178,16 +200,35 @@ static ssize_t notification_delay_ms_store(struct device *dev,
static DEVICE_ATTR_RW(notification_delay_ms);
+static umode_t workload_hint_attr_visible(struct kobject *kobj, struct attribute *attr, int unused)
+{
+ if (attr != &dev_attr_workload_slow_hint_enable.attr)
+ return attr->mode;
+
+ switch (to_pci_dev(kobj_to_dev(kobj))->device) {
+ case PCI_DEVICE_ID_INTEL_LNLM_THERMAL:
+ case PCI_DEVICE_ID_INTEL_MTLP_THERMAL:
+ case PCI_DEVICE_ID_INTEL_ARL_S_THERMAL:
+ return 0;
+ default:
+ break;
+ }
+
+ return attr->mode;
+}
+
static struct attribute *workload_hint_attrs[] = {
&dev_attr_workload_type_index.attr,
&dev_attr_workload_hint_enable.attr,
+ &dev_attr_workload_slow_hint_enable.attr,
&dev_attr_notification_delay_ms.attr,
NULL
};
static const struct attribute_group workload_hint_attribute_group = {
.attrs = workload_hint_attrs,
- .name = "workload_hint"
+ .name = "workload_hint",
+ .is_visible = workload_hint_attr_visible
};
/*
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_req.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_req.c
index b95810f4a011..2372f5202019 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_req.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_wt_req.c
@@ -7,6 +7,7 @@
*/
#include <linux/pci.h>
+#include <linux/sysfs.h>
#include "processor_thermal_device.h"
/* List of workload types */
@@ -28,9 +29,9 @@ static ssize_t workload_available_types_show(struct device *dev,
int ret = 0;
while (workload_types[i] != NULL)
- ret += sprintf(&buf[ret], "%s ", workload_types[i++]);
+ ret += sysfs_emit_at(buf, ret, "%s ", workload_types[i++]);
- ret += sprintf(&buf[ret], "\n");
+ ret += sysfs_emit_at(buf, ret, "\n");
return ret;
}
@@ -85,7 +86,7 @@ static ssize_t workload_type_show(struct device *dev,
if (cmd_resp > ARRAY_SIZE(workload_types) - 1)
return -EINVAL;
- return sprintf(buf, "%s\n", workload_types[cmd_resp]);
+ return sysfs_emit(buf, "%s\n", workload_types[cmd_resp]);
}
static DEVICE_ATTR_RW(workload_type);
diff --git a/drivers/thermal/intel/intel_pch_thermal.c b/drivers/thermal/intel/intel_pch_thermal.c
index fc326985796c..52e71af67dc6 100644
--- a/drivers/thermal/intel/intel_pch_thermal.c
+++ b/drivers/thermal/intel/intel_pch_thermal.c
@@ -269,7 +269,6 @@ static void intel_pch_thermal_remove(struct pci_dev *pdev)
thermal_zone_device_unregister(ptd->tzd);
iounmap(ptd->hw_base);
- pci_set_drvdata(pdev, NULL);
pci_release_regions(pdev);
pci_disable_device(pdev);
}
diff --git a/drivers/thermal/intel/intel_tcc.c b/drivers/thermal/intel/intel_tcc.c
index b2a615aea7c1..ab61fb122937 100644
--- a/drivers/thermal/intel/intel_tcc.c
+++ b/drivers/thermal/intel/intel_tcc.c
@@ -172,7 +172,7 @@ static u32 get_temp_mask(bool pkg)
/**
* intel_tcc_get_tjmax() - returns the default TCC activation Temperature
- * @cpu: cpu that the MSR should be run on, nagative value means any cpu.
+ * @cpu: cpu that the MSR should be run on, negative value means any cpu.
*
* Get the TjMax value, which is the default thermal throttling or TCC
* activation temperature in degrees C.
@@ -199,7 +199,7 @@ 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.
+ * @cpu: cpu that the MSR should be run on, negative 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.
@@ -224,7 +224,7 @@ 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.
+ * @cpu: cpu that the MSR should be run on, negative value means any cpu.
* @offset: TCC offset value in degree C
*
* Set the TCC Offset value to Tjmax. The effective thermal throttling or TCC
@@ -267,7 +267,7 @@ 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.
+ * @cpu: cpu that the MSR should be run on, negative value means any cpu.
* @temp: pointer to the memory for saving cpu temperature.
* @pkg: true: Package Thermal Sensor. false: Core Thermal Sensor.
*
diff --git a/drivers/thermal/intel/intel_tcc_cooling.c b/drivers/thermal/intel/intel_tcc_cooling.c
index f352ecafbedf..6c2ba0ba3178 100644
--- a/drivers/thermal/intel/intel_tcc_cooling.c
+++ b/drivers/thermal/intel/intel_tcc_cooling.c
@@ -65,6 +65,10 @@ static const struct x86_cpu_id tcc_ids[] __initconst = {
X86_MATCH_VFM(INTEL_RAPTORLAKE, NULL),
X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL),
X86_MATCH_VFM(INTEL_RAPTORLAKE_S, NULL),
+ X86_MATCH_VFM(INTEL_PANTHERLAKE_L, NULL),
+ X86_MATCH_VFM(INTEL_WILDCATLAKE_L, NULL),
+ X86_MATCH_VFM(INTEL_NOVALAKE, NULL),
+ X86_MATCH_VFM(INTEL_NOVALAKE_L, NULL),
{}
};
@@ -72,10 +76,8 @@ MODULE_DEVICE_TABLE(x86cpu, tcc_ids);
static int __init tcc_cooling_init(void)
{
- int ret;
u64 val;
const struct x86_cpu_id *id;
-
int err;
id = x86_match_cpu(tcc_ids);
@@ -103,10 +105,9 @@ static int __init tcc_cooling_init(void)
tcc_cdev =
thermal_cooling_device_register("TCC Offset", NULL,
&tcc_cooling_ops);
- if (IS_ERR(tcc_cdev)) {
- ret = PTR_ERR(tcc_cdev);
- return ret;
- }
+ if (IS_ERR(tcc_cdev))
+ return PTR_ERR(tcc_cdev);
+
return 0;
}
diff --git a/drivers/thermal/intel/therm_throt.c b/drivers/thermal/intel/therm_throt.c
index debc94e2dc16..44fa4dd15dd1 100644
--- a/drivers/thermal/intel/therm_throt.c
+++ b/drivers/thermal/intel/therm_throt.c
@@ -23,6 +23,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/smp.h>
+#include <linux/sysfs.h>
#include <linux/cpu.h>
#include <asm/processor.h>
@@ -144,8 +145,8 @@ static ssize_t therm_throt_device_show_##event##_##name( \
\
preempt_disable(); /* CPU hotplug */ \
if (cpu_online(cpu)) { \
- ret = sprintf(buf, "%lu\n", \
- per_cpu(thermal_state, cpu).event.name); \
+ ret = sysfs_emit(buf, "%lu\n", \
+ per_cpu(thermal_state, cpu).event.name); \
} else \
ret = 0; \
preempt_enable(); \
diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c
index 3fc679b6f11b..aab5f9fca9c3 100644
--- a/drivers/thermal/intel/x86_pkg_temp_thermal.c
+++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c
@@ -128,6 +128,9 @@ sys_set_trip_temp(struct thermal_zone_device *tzd,
u32 l, h, mask, shift, intr;
int tj_max, val, ret;
+ if (temp == THERMAL_TEMP_INVALID)
+ temp = 0;
+
tj_max = intel_tcc_get_tjmax(zonedev->cpu);
if (tj_max < 0)
return tj_max;
diff --git a/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c b/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c
index ca2bd03154e4..569d44f22835 100644
--- a/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c
+++ b/tools/testing/selftests/thermal/intel/workload_hint/workload_hint_test.c
@@ -12,6 +12,7 @@
#define WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/notification_delay_ms"
#define WORKLOAD_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_hint_enable"
+#define WORKLOAD_SLOW_ENABLE_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_slow_hint_enable"
#define WORKLOAD_TYPE_INDEX_ATTRIBUTE "/sys/bus/pci/devices/0000:00:04.0/workload_hint/workload_type_index"
static const char * const workload_types[] = {
@@ -22,6 +23,9 @@ static const char * const workload_types[] = {
NULL
};
+static int wlt_slow;
+static char *wlt_enable_attr;
+
#define WORKLOAD_TYPE_MAX_INDEX 3
void workload_hint_exit(int signum)
@@ -30,7 +34,7 @@ void workload_hint_exit(int signum)
/* Disable feature via sysfs knob */
- fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR);
+ fd = open(wlt_enable_attr, O_RDWR);
if (fd < 0) {
perror("Unable to open workload type feature enable file");
exit(1);
@@ -46,6 +50,26 @@ void workload_hint_exit(int signum)
close(fd);
}
+static void update_delay(char *delay_str)
+{
+ int fd;
+
+ printf("Setting notification delay in ms to %s\n", delay_str);
+
+ fd = open(WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE, O_RDWR);
+ if (fd < 0) {
+ perror("Unable to open workload notification delay");
+ exit(1);
+ }
+
+ if (write(fd, delay_str, strlen(delay_str)) < 0) {
+ perror("Can't set delay");
+ exit(1);
+ }
+
+ close(fd);
+}
+
int main(int argc, char **argv)
{
struct pollfd ufd;
@@ -54,32 +78,26 @@ int main(int argc, char **argv)
char delay_str[64];
int delay = 0;
- printf("Usage: workload_hint_test [notification delay in milli seconds]\n");
+ printf("Usage: workload_hint_test [notification delay in milli seconds][slow]\n");
if (argc > 1) {
- ret = sscanf(argv[1], "%d", &delay);
- if (ret < 0) {
- printf("Invalid delay\n");
- exit(1);
- }
+ int i;
- printf("Setting notification delay to %d ms\n", delay);
- if (delay < 0)
- exit(1);
+ for (i = 1; i < argc; ++i) {
+ if (!strcmp(argv[i], "slow")) {
+ wlt_slow = 1;
+ continue;
+ }
- sprintf(delay_str, "%s\n", argv[1]);
- fd = open(WORKLOAD_NOTIFICATION_DELAY_ATTRIBUTE, O_RDWR);
- if (fd < 0) {
- perror("Unable to open workload notification delay");
- exit(1);
- }
+ ret = sscanf(argv[1], "%d", &delay);
+ if (ret < 0) {
+ printf("Invalid delay\n");
+ exit(1);
+ }
- if (write(fd, delay_str, strlen(delay_str)) < 0) {
- perror("Can't set delay");
- exit(1);
+ sprintf(delay_str, "%s\n", argv[1]);
+ update_delay(delay_str);
}
-
- close(fd);
}
if (signal(SIGINT, workload_hint_exit) == SIG_IGN)
@@ -89,8 +107,13 @@ int main(int argc, char **argv)
if (signal(SIGTERM, workload_hint_exit) == SIG_IGN)
signal(SIGTERM, SIG_IGN);
+ if (wlt_slow)
+ wlt_enable_attr = WORKLOAD_SLOW_ENABLE_ATTRIBUTE;
+ else
+ wlt_enable_attr = WORKLOAD_ENABLE_ATTRIBUTE;
+
/* Enable feature via sysfs knob */
- fd = open(WORKLOAD_ENABLE_ATTRIBUTE, O_RDWR);
+ fd = open(wlt_enable_attr, O_RDWR);
if (fd < 0) {
perror("Unable to open workload type feature enable file");
exit(1);
@@ -145,6 +168,13 @@ int main(int argc, char **argv)
if (ret < 0)
break;
+ if (wlt_slow) {
+ if (index & 0x10)
+ printf("workload type slow:%s\n", "power");
+ else
+ printf("workload type slow:%s\n", "performance");
+ }
+
index &= 0x0f;
if (index > WORKLOAD_TYPE_MAX_INDEX)
printf("Invalid workload type index\n");