This is a note to let you know that I've just added the patch titled thermal: sysfs: Get to trips via attribute pointers to the 6.11-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: thermal-sysfs-get-to-trips-via-attribute-pointers.patch and it can be found in the queue-6.11 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 4d6569d10c6f8d6d634fd8a2b2dc2af1ce9191dc Author: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> Date: Mon Jul 29 18:25:59 2024 +0200 thermal: sysfs: Get to trips via attribute pointers [ Upstream commit afd84fb10ced3caf53769ba734ea237bde0f69e3 ] The _store() and _show() functions for sysfs attributes corresponding to trip point parameters (type, temperature and hysteresis) read the trip ID from the attribute name and then use the trip ID as the index in the given thermal zone's trips table to get to the trip object they want. Instead of doing this, make them use the attribute pointer they get as the second argument to get to the trip object embedded in the same struct thermal_trip_desc as the struct device_attribute pointed to by it, which is much more straightforward and less overhead. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> Link: https://patch.msgid.link/114841552.nniJfEyVGO@xxxxxxxxxxxxx Stable-dep-of: 874b6476fa88 ("thermal: sysfs: Add sanity checks for trip temperature and hysteresis") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index f12d5d47da9bd..11a34b9fe153d 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -12,6 +12,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/container_of.h> #include <linux/sysfs.h> #include <linux/device.h> #include <linux/err.h> @@ -78,39 +79,38 @@ mode_store(struct device *dev, struct device_attribute *attr, return count; } +#define thermal_trip_of_attr(_ptr_, _attr_) \ + ({ \ + struct thermal_trip_desc *td; \ + \ + td = container_of(_ptr_, struct thermal_trip_desc, \ + trip_attrs._attr_.attr); \ + &td->trip; \ + }) + static ssize_t trip_point_type_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip_id; - - if (sscanf(attr->attr.name, "trip_point_%d_type", &trip_id) != 1) - return -EINVAL; + struct thermal_trip *trip = thermal_trip_of_attr(attr, type); - return sprintf(buf, "%s\n", thermal_trip_type_name(tz->trips[trip_id].trip.type)); + return sprintf(buf, "%s\n", thermal_trip_type_name(trip->type)); } static ssize_t trip_point_temp_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct thermal_trip *trip = thermal_trip_of_attr(attr, temp); struct thermal_zone_device *tz = to_thermal_zone(dev); - struct thermal_trip *trip; - int trip_id, ret; - int temp; + int ret, temp; ret = kstrtoint(buf, 10, &temp); if (ret) return -EINVAL; - if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) - return -EINVAL; - mutex_lock(&tz->lock); - trip = &tz->trips[trip_id].trip; - if (temp != trip->temperature) { if (tz->ops.set_trip_temp) { ret = tz->ops.set_trip_temp(tz, trip, temp); @@ -133,35 +133,25 @@ static ssize_t trip_point_temp_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip_id; + struct thermal_trip *trip = thermal_trip_of_attr(attr, temp); - if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) - return -EINVAL; - - return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.temperature)); + return sprintf(buf, "%d\n", READ_ONCE(trip->temperature)); } static ssize_t trip_point_hyst_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst); struct thermal_zone_device *tz = to_thermal_zone(dev); - struct thermal_trip *trip; - int trip_id, ret; - int hyst; + int ret, hyst; ret = kstrtoint(buf, 10, &hyst); if (ret || hyst < 0) return -EINVAL; - if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) - return -EINVAL; - mutex_lock(&tz->lock); - trip = &tz->trips[trip_id].trip; - if (hyst != trip->hysteresis) { WRITE_ONCE(trip->hysteresis, hyst); @@ -177,13 +167,9 @@ static ssize_t trip_point_hyst_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip_id; - - if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) - return -EINVAL; + struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst); - return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.hysteresis)); + return sprintf(buf, "%d\n", READ_ONCE(trip->hysteresis)); } static ssize_t