On Fri, May 19, 2023 at 5:27 AM Eduardo Valentin <evalenti@xxxxxxxxxx> wrote: > > 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> This can be easily folded into the previous patch IMO. > --- > .../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 >