Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

thermal: trip: Trigger trip down notifications when trips involved in mitigation become invalid

When a trip point becomes invalid after being crossed on the way up,
it is involved in a mitigation episode that needs to be adjusted to
compensate for the trip going away.

For this reason, introduce thermal_zone_trip_down() as a wrapper
around thermal_trip_crossed() and make thermal_zone_set_trip_temp()
call it if the new temperature of the trip at hand is equal to
THERMAL_TEMP_INVALID and it has been crossed on the way up to trigger
all of the necessary adjustments in user space, the thermal debug
code and the zone governor.

Fixes: 8c69a777e480 ("thermal: core: Fix the handling of invalid trip points")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

+20 -8
+6
drivers/thermal/thermal_core.c
··· 602 602 } 603 603 EXPORT_SYMBOL_GPL(thermal_zone_device_update); 604 604 605 + void thermal_zone_trip_down(struct thermal_zone_device *tz, 606 + const struct thermal_trip *trip) 607 + { 608 + thermal_trip_crossed(tz, trip, thermal_get_tz_governor(tz), false); 609 + } 610 + 605 611 int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *), 606 612 void *data) 607 613 {
+2
drivers/thermal/thermal_core.h
··· 246 246 void thermal_zone_trip_updated(struct thermal_zone_device *tz, 247 247 const struct thermal_trip *trip); 248 248 int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); 249 + void thermal_zone_trip_down(struct thermal_zone_device *tz, 250 + const struct thermal_trip *trip); 249 251 250 252 /* sysfs I/F */ 251 253 int thermal_zone_create_device_groups(struct thermal_zone_device *tz);
+12 -8
drivers/thermal/thermal_trip.c
··· 152 152 if (trip->temperature == temp) 153 153 return; 154 154 155 + trip->temperature = temp; 156 + thermal_notify_tz_trip_change(tz, trip); 157 + 155 158 if (temp == THERMAL_TEMP_INVALID) { 156 159 struct thermal_trip_desc *td = trip_to_trip_desc(trip); 157 160 158 - if (trip->type == THERMAL_TRIP_PASSIVE && 159 - tz->temperature >= td->threshold) { 161 + if (tz->temperature >= td->threshold) { 160 162 /* 161 - * The trip has been crossed, so the thermal zone's 162 - * passive count needs to be adjusted. 163 + * The trip has been crossed on the way up, so some 164 + * adjustments are needed to compensate for the lack 165 + * of it going forward. 163 166 */ 164 - tz->passive--; 165 - WARN_ON_ONCE(tz->passive < 0); 167 + if (trip->type == THERMAL_TRIP_PASSIVE) { 168 + tz->passive--; 169 + WARN_ON_ONCE(tz->passive < 0); 170 + } 171 + thermal_zone_trip_down(tz, trip); 166 172 } 167 173 /* 168 174 * Invalidate the threshold to avoid triggering a spurious ··· 176 170 */ 177 171 td->threshold = INT_MAX; 178 172 } 179 - trip->temperature = temp; 180 - thermal_notify_tz_trip_change(tz, trip); 181 173 } 182 174 EXPORT_SYMBOL_GPL(thermal_zone_set_trip_temp);