Merge branches 'thermal-core', 'thermal-intel' and 'thermal-tools' into linux-next

* thermal-core:
  thermal: sysfs: Replace snprintf() with strscpy() in policy_store()
  thermal: debugfs: Use seq_puts() for constant string output
  thermal: Replace sprintf() with sysfs_emit() for sysfs show functions
  thermal: core: Use strnlen() in thermal_zone_device_register_with_trips()

* thermal-intel:
  thermal: intel: Use sysfs_emit() in a sysfs show function
  thermal: intel: fix typo "nagative" in comment for cpu argument
  thermal: intel: int340x: Use sysfs_emit{_at}() in sysfs show functions
  thermal: intel: selftests: workload_hint: Support slow workload hints
  thermal: int340x: processor_thermal: Enable slow workload type hints
  thermal: intel: intel_pch_thermal: Drop explicit driver data clearing
  thermal: intel: intel_tcc_cooling: Add CPU models in the support list

* thermal-tools:
  tools: lib: thermal: Correct CFLAGS and LDFLAGS in pkg-config template
diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst
index 916bf0f..4adfa1e 100644
--- a/Documentation/driver-api/thermal/intel_dptf.rst
+++ b/Documentation/driver-api/thermal/intel_dptf.rst
@@ -375,6 +375,9 @@
 ``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 48e7849..f80dbe2 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 589a3a7..bb9398d 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 68e8391..f8c33e8 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 @@ static ssize_t workload_hint_enable_store(struct device *dev,
 	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 b95810f..2372f52 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 fc32698..52e71af 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 b2a615a..ab61fb1 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 f352eca..92de161 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),
 	{}
 };
 
diff --git a/drivers/thermal/intel/therm_throt.c b/drivers/thermal/intel/therm_throt.c
index debc94e..44fa4dd 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/thermal_core.c b/drivers/thermal/thermal_core.c
index 89758c9..dc9f741 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -1505,15 +1505,19 @@ thermal_zone_device_register_with_trips(const char *type,
 	const struct thermal_trip *trip = trips;
 	struct thermal_zone_device *tz;
 	struct thermal_trip_desc *td;
+	size_t type_len = 0;
 	int id;
 	int result;
 
-	if (!type || strlen(type) == 0) {
+	if (type)
+		type_len = strnlen(type, THERMAL_NAME_LENGTH);
+
+	if (type_len == 0) {
 		pr_err("No thermal zone type defined\n");
 		return ERR_PTR(-EINVAL);
 	}
 
-	if (strlen(type) >= THERMAL_NAME_LENGTH) {
+	if (type_len == THERMAL_NAME_LENGTH) {
 		pr_err("Thermal zone name (%s) too long, should be under %d chars\n",
 		       type, THERMAL_NAME_LENGTH);
 		return ERR_PTR(-EINVAL);
diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c
index 11d34f2..11668f5 100644
--- a/drivers/thermal/thermal_debugfs.c
+++ b/drivers/thermal/thermal_debugfs.c
@@ -807,7 +807,7 @@ static int tze_seq_show(struct seq_file *s, void *v)
 	seq_printf(s, ",-Mitigation at %llums, duration%c%llums, max. temp=%dm°C\n",
 		   ktime_to_ms(tze->timestamp), c, duration_ms, tze->max_temp);
 
-	seq_printf(s, "| trip |     type | temp(m°C) | hyst(m°C) | duration(ms) |  avg(m°C) |  min(m°C) |\n");
+	seq_puts(s, "| trip |     type | temp(m°C) | hyst(m°C) | duration(ms) |  avg(m°C) |  min(m°C) |\n");
 
 	for_each_trip_desc(tz, td) {
 		const struct thermal_trip *trip = &td->trip;
diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
index 64cc3ab..faf1d00 100644
--- a/drivers/thermal/thermal_hwmon.c
+++ b/drivers/thermal/thermal_hwmon.c
@@ -63,7 +63,7 @@ temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
 	if (ret)
 		return ret;
 
-	return sprintf(buf, "%d\n", temperature);
+	return sysfs_emit(buf, "%d\n", temperature);
 }
 
 static ssize_t
@@ -84,7 +84,7 @@ temp_crit_show(struct device *dev, struct device_attribute *attr, char *buf)
 	if (ret)
 		return ret;
 
-	return sprintf(buf, "%d\n", temperature);
+	return sysfs_emit(buf, "%d\n", temperature);
 }
 
 
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
index d806125..2538c2dc 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -29,7 +29,7 @@ type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
 
-	return sprintf(buf, "%s\n", tz->type);
+	return sysfs_emit(buf, "%s\n", tz->type);
 }
 
 static ssize_t
@@ -41,7 +41,7 @@ temp_show(struct device *dev, struct device_attribute *attr, char *buf)
 	ret = thermal_zone_get_temp(tz, &temperature);
 
 	if (!ret)
-		return sprintf(buf, "%d\n", temperature);
+		return sysfs_emit(buf, "%d\n", temperature);
 
 	if (ret == -EAGAIN)
 		return -ENODATA;
@@ -57,9 +57,9 @@ mode_show(struct device *dev, struct device_attribute *attr, char *buf)
 	guard(thermal_zone)(tz);
 
 	if (tz->mode == THERMAL_DEVICE_ENABLED)
-		return sprintf(buf, "enabled\n");
+		return sysfs_emit(buf, "enabled\n");
 
-	return sprintf(buf, "disabled\n");
+	return sysfs_emit(buf, "disabled\n");
 }
 
 static ssize_t
@@ -97,7 +97,7 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
 {
 	struct thermal_trip *trip = thermal_trip_of_attr(attr, type);
 
-	return sprintf(buf, "%s\n", thermal_trip_type_name(trip->type));
+	return sysfs_emit(buf, "%s\n", thermal_trip_type_name(trip->type));
 }
 
 static ssize_t
@@ -142,7 +142,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
 {
 	struct thermal_trip *trip = thermal_trip_of_attr(attr, temp);
 
-	return sprintf(buf, "%d\n", READ_ONCE(trip->temperature));
+	return sysfs_emit(buf, "%d\n", READ_ONCE(trip->temperature));
 }
 
 static ssize_t
@@ -188,7 +188,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
 {
 	struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst);
 
-	return sprintf(buf, "%d\n", READ_ONCE(trip->hysteresis));
+	return sysfs_emit(buf, "%d\n", READ_ONCE(trip->hysteresis));
 }
 
 static ssize_t
@@ -199,7 +199,7 @@ policy_store(struct device *dev, struct device_attribute *attr,
 	char name[THERMAL_NAME_LENGTH];
 	int ret;
 
-	snprintf(name, sizeof(name), "%s", buf);
+	strscpy(name, buf);
 
 	ret = thermal_zone_device_set_policy(tz, name);
 	if (!ret)
@@ -213,7 +213,7 @@ policy_show(struct device *dev, struct device_attribute *devattr, char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
 
-	return sprintf(buf, "%s\n", tz->governor->name);
+	return sysfs_emit(buf, "%s\n", tz->governor->name);
 }
 
 static ssize_t
@@ -260,7 +260,7 @@ sustainable_power_show(struct device *dev, struct device_attribute *devattr,
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
 
 	if (tz->tzp)
-		return sprintf(buf, "%u\n", tz->tzp->sustainable_power);
+		return sysfs_emit(buf, "%u\n", tz->tzp->sustainable_power);
 	else
 		return -EIO;
 }
@@ -291,7 +291,7 @@ sustainable_power_store(struct device *dev, struct device_attribute *devattr,
 	struct thermal_zone_device *tz = to_thermal_zone(dev);		\
 									\
 	if (tz->tzp)							\
-		return sprintf(buf, "%d\n", tz->tzp->name);		\
+		return sysfs_emit(buf, "%d\n", tz->tzp->name);		\
 	else								\
 		return -EIO;						\
 	}								\
@@ -505,7 +505,7 @@ cdev_type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
 
-	return sprintf(buf, "%s\n", cdev->type);
+	return sysfs_emit(buf, "%s\n", cdev->type);
 }
 
 static ssize_t max_state_show(struct device *dev, struct device_attribute *attr,
@@ -513,7 +513,7 @@ static ssize_t max_state_show(struct device *dev, struct device_attribute *attr,
 {
 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
 
-	return sprintf(buf, "%ld\n", cdev->max_state);
+	return sysfs_emit(buf, "%ld\n", cdev->max_state);
 }
 
 static ssize_t cur_state_show(struct device *dev, struct device_attribute *attr,
@@ -526,7 +526,7 @@ static ssize_t cur_state_show(struct device *dev, struct device_attribute *attr,
 	ret = cdev->ops->get_cur_state(cdev, &state);
 	if (ret)
 		return ret;
-	return sprintf(buf, "%ld\n", state);
+	return sysfs_emit(buf, "%ld\n", state);
 }
 
 static ssize_t
@@ -638,7 +638,7 @@ static ssize_t total_trans_show(struct device *dev,
 		return 0;
 
 	spin_lock(&stats->lock);
-	ret = sprintf(buf, "%u\n", stats->total_trans);
+	ret = sysfs_emit(buf, "%u\n", stats->total_trans);
 	spin_unlock(&stats->lock);
 
 	return ret;
@@ -664,8 +664,8 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr,
 	update_time_in_state(stats);
 
 	for (i = 0; i <= cdev->max_state; i++) {
-		len += sprintf(buf + len, "state%u\t%llu\n", i,
-			       ktime_to_ms(stats->time_in_state[i]));
+		len += sysfs_emit_at(buf, len, "state%u\t%llu\n", i,
+				     ktime_to_ms(stats->time_in_state[i]));
 	}
 	spin_unlock(&stats->lock);
 
@@ -846,7 +846,7 @@ trip_point_show(struct device *dev, struct device_attribute *attr, char *buf)
 
 	instance = container_of(attr, struct thermal_instance, attr);
 
-	return sprintf(buf, "%d\n", thermal_zone_trip_id(tz, instance->trip));
+	return sysfs_emit(buf, "%d\n", thermal_zone_trip_id(tz, instance->trip));
 }
 
 ssize_t
@@ -856,7 +856,7 @@ weight_show(struct device *dev, struct device_attribute *attr, char *buf)
 
 	instance = container_of(attr, struct thermal_instance, weight_attr);
 
-	return sprintf(buf, "%d\n", instance->weight);
+	return sysfs_emit(buf, "%d\n", instance->weight);
 }
 
 ssize_t weight_store(struct device *dev, struct device_attribute *attr,
diff --git a/tools/lib/thermal/libthermal.pc.template b/tools/lib/thermal/libthermal.pc.template
index ac24d0a..b984c5e 100644
--- a/tools/lib/thermal/libthermal.pc.template
+++ b/tools/lib/thermal/libthermal.pc.template
@@ -8,5 +8,5 @@
 Description: thermal library
 Requires: libnl-3.0 libnl-genl-3.0
 Version: @VERSION@
-Libs: -L${libdir} -lnl-genl-3 -lnl-3
-Cflags: -I${includedir} -I${include}/libnl3
+Libs: -L${libdir} -lthermal
+Cflags: -I${includedir}
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 ca2bd03..569d44f 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;
+
+		for (i = 1; i < argc; ++i) {
+			if (!strcmp(argv[i], "slow")) {
+				wlt_slow = 1;
+				continue;
+			}
+
+			ret = sscanf(argv[1], "%d", &delay);
+			if (ret < 0) {
+				printf("Invalid delay\n");
+				exit(1);
+			}
+
+			sprintf(delay_str, "%s\n", argv[1]);
+			update_delay(delay_str);
 		}
-
-		printf("Setting notification delay to %d ms\n", delay);
-		if (delay < 0)
-			exit(1);
-
-		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);
-		}
-
-		if (write(fd, delay_str, strlen(delay_str)) < 0) {
-			perror("Can't set delay");
-			exit(1);
-		}
-
-		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");