Skip to content

Commit 8c69a77

Browse files
committed
thermal: core: Fix the handling of invalid trip points
Commit 9ad1804 ("thermal: core: Send trip crossing notifications at init time if needed") overlooked the case when a trip point that has started as invalid is set to a valid temperature later. Namely, the initial threshold value for all trips is zero, so if a previously invalid trip becomes valid and its (new) low temperature is above the zone temperature, a spurious trip crossing notification will occur and it may trigger the WARN_ON() in handle_thermal_trip(). To address this, set the initial threshold for all trips to INT_MAX. There is also the case when a valid writable trip becomes invalid that requires special handling. First, in accordance with the change mentioned above, the trip's threshold needs to be set to INT_MAX to avoid the same issue. Second, if the trip in question is passive and it has been crossed by the thermal zone temperature on the way up, the zone's passive count has been incremented and it is in the passive polling mode, so its passive count needs to be adjusted to allow the passive polling to be turned off eventually. Fixes: 9ad1804 ("thermal: core: Send trip crossing notifications at init time if needed") Fixes: 042a3d8 ("thermal: core: Move passive polling management to the core") Reported-by: Zhang Rui <zhang.rui@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Wendy Wang <wendy.wang@intel.com>
1 parent 9dbbcd6 commit 8c69a77

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

drivers/thermal/thermal_core.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1398,8 +1398,15 @@ thermal_zone_device_register_with_trips(const char *type,
13981398
tz->device.class = thermal_class;
13991399
tz->devdata = devdata;
14001400
tz->num_trips = num_trips;
1401-
for_each_trip_desc(tz, td)
1401+
for_each_trip_desc(tz, td) {
14021402
td->trip = *trip++;
1403+
/*
1404+
* Mark all thresholds as invalid to start with even though
1405+
* this only matters for the trips that start as invalid and
1406+
* become valid later.
1407+
*/
1408+
td->threshold = INT_MAX;
1409+
}
14031410

14041411
thermal_set_delay_jiffies(&tz->passive_delay_jiffies, passive_delay);
14051412
thermal_set_delay_jiffies(&tz->polling_delay_jiffies, polling_delay);

drivers/thermal/thermal_trip.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,24 @@ void thermal_zone_set_trip_temp(struct thermal_zone_device *tz,
152152
if (trip->temperature == temp)
153153
return;
154154

155+
if (temp == THERMAL_TEMP_INVALID) {
156+
struct thermal_trip_desc *td = trip_to_trip_desc(trip);
157+
158+
if (trip->type == THERMAL_TRIP_PASSIVE &&
159+
tz->temperature >= td->threshold) {
160+
/*
161+
* The trip has been crossed, so the thermal zone's
162+
* passive count needs to be adjusted.
163+
*/
164+
tz->passive--;
165+
WARN_ON_ONCE(tz->passive < 0);
166+
}
167+
/*
168+
* Invalidate the threshold to avoid triggering a spurious
169+
* trip crossing notification when the trip becomes valid.
170+
*/
171+
td->threshold = INT_MAX;
172+
}
155173
trip->temperature = temp;
156174
thermal_notify_tz_trip_change(tz, trip);
157175
}

0 commit comments

Comments
 (0)