From: Eduardo Valentin <eduval@xxxxxxxxxx> The patch adds a statistic to track the minimum gradient (dT/dt) to the thermal zone stats/ folder. Samples: $ echo 1000 > emul_temp $ cat stats/min_gradient 0 $ echo 2000 > emul_temp $ echo 1000 > emul_temp $ cat stats/min_gradient -3460 Cc: "Rafael J. Wysocki" <rafael@xxxxxxxxxx> (supporter:THERMAL) Cc: Daniel Lezcano <daniel.lezcano@xxxxxxxxxx> (supporter:THERMAL) Cc: Amit Kucheria <amitk@xxxxxxxxxx> (reviewer:THERMAL) Cc: Zhang Rui <rui.zhang@xxxxxxxxx> (reviewer:THERMAL) Cc: Jonathan Corbet <corbet@xxxxxxx> (maintainer:DOCUMENTATION) Cc: linux-pm@xxxxxxxxxxxxxxx (open list:THERMAL) Cc: linux-doc@xxxxxxxxxxxxxxx (open list:DOCUMENTATION) Cc: linux-kernel@xxxxxxxxxxxxxxx (open list) Signed-off-by: Eduardo Valentin <eduval@xxxxxxxxxx> --- .../driver-api/thermal/sysfs-api.rst | 1 + drivers/thermal/thermal_sysfs.c | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/Documentation/driver-api/thermal/sysfs-api.rst b/Documentation/driver-api/thermal/sysfs-api.rst index 18140dbb1ce1..ed5e6ba4e0d7 100644 --- a/Documentation/driver-api/thermal/sysfs-api.rst +++ b/Documentation/driver-api/thermal/sysfs-api.rst @@ -358,6 +358,7 @@ Thermal zone device sys I/F, created once it's registered:: |---stats: Directory containing thermal zone device's stats |---stats/reset_tz_stats: Writes to this file resets the statistics. |---stats/max_gradient: The maximum recorded dT/dt in uC/ms. + |---stats/min_gradient: The minimum recorded dT/dt in uC/ms. Thermal cooling device sys I/F, created once it's registered:: diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index aa28c1cae916..f89ec9a7e8c8 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -542,6 +542,7 @@ static void destroy_trip_attrs(struct thermal_zone_device *tz) struct thermal_zone_device_stats { spinlock_t lock; /* protects this struct */ s64 max_gradient; + s64 min_gradient; ktime_t last_time; }; @@ -569,6 +570,10 @@ static void temperature_stats_update(struct thermal_zone_device *tz) /* update fastest temperature rise from our perspective */ if (cur_gradient > stats->max_gradient) stats->max_gradient = cur_gradient; + + /* update fastest temperature decay from our perspective */ + if (cur_gradient < stats->min_gradient) + stats->min_gradient = cur_gradient; } void thermal_zone_device_stats_update(struct thermal_zone_device *tz) @@ -595,6 +600,21 @@ static ssize_t max_gradient_show(struct device *dev, return ret; } +static ssize_t min_gradient_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct thermal_zone_device *tz = to_thermal_zone(dev); + struct thermal_zone_device_stats *stats = tz->stats; + int ret; + + spin_lock(&stats->lock); + temperature_stats_update(tz); + ret = snprintf(buf, PAGE_SIZE, "%lld\n", stats->min_gradient); + spin_unlock(&stats->lock); + + return ret; +} + static ssize_t reset_tz_stats_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -604,6 +624,7 @@ reset_tz_stats_store(struct device *dev, struct device_attribute *attr, spin_lock(&stats->lock); + stats->min_gradient = 0; stats->max_gradient = 0; stats->last_time = ktime_get(); @@ -612,10 +633,12 @@ reset_tz_stats_store(struct device *dev, struct device_attribute *attr, return count; } +static DEVICE_ATTR_RO(min_gradient); static DEVICE_ATTR_RO(max_gradient); static DEVICE_ATTR_WO(reset_tz_stats); static struct attribute *thermal_zone_device_stats_attrs[] = { + &dev_attr_min_gradient.attr, &dev_attr_max_gradient.attr, &dev_attr_reset_tz_stats.attr, NULL -- 2.34.1