Commit ae2170d6 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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: 8c69a777 ("thermal: core: Fix the handling of invalid trip points")
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent cb573eec
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -602,6 +602,12 @@ void thermal_zone_device_update(struct thermal_zone_device *tz,
}
EXPORT_SYMBOL_GPL(thermal_zone_device_update);

void thermal_zone_trip_down(struct thermal_zone_device *tz,
			    const struct thermal_trip *trip)
{
	thermal_trip_crossed(tz, trip, thermal_get_tz_governor(tz), false);
}

int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
			      void *data)
{
+2 −0
Original line number Diff line number Diff line
@@ -246,6 +246,8 @@ int thermal_zone_trip_id(const struct thermal_zone_device *tz,
void thermal_zone_trip_updated(struct thermal_zone_device *tz,
			       const struct thermal_trip *trip);
int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
void thermal_zone_trip_down(struct thermal_zone_device *tz,
			    const struct thermal_trip *trip);

/* sysfs I/F */
int thermal_zone_create_device_groups(struct thermal_zone_device *tz);
+12 −8
Original line number Diff line number Diff line
@@ -152,25 +152,29 @@ void thermal_zone_set_trip_temp(struct thermal_zone_device *tz,
	if (trip->temperature == temp)
		return;

	trip->temperature = temp;
	thermal_notify_tz_trip_change(tz, trip);

	if (temp == THERMAL_TEMP_INVALID) {
		struct thermal_trip_desc *td = trip_to_trip_desc(trip);

		if (trip->type == THERMAL_TRIP_PASSIVE &&
		    tz->temperature >= td->threshold) {
		if (tz->temperature >= td->threshold) {
			/*
			 * The trip has been crossed, so the thermal zone's
			 * passive count needs to be adjusted.
			 * The trip has been crossed on the way up, so some
			 * adjustments are needed to compensate for the lack
			 * of it going forward.
			 */
			if (trip->type == THERMAL_TRIP_PASSIVE) {
				tz->passive--;
				WARN_ON_ONCE(tz->passive < 0);
			}
			thermal_zone_trip_down(tz, trip);
		}
		/*
		 * Invalidate the threshold to avoid triggering a spurious
		 * trip crossing notification when the trip becomes valid.
		 */
		td->threshold = INT_MAX;
	}
	trip->temperature = temp;
	thermal_notify_tz_trip_change(tz, trip);
}
EXPORT_SYMBOL_GPL(thermal_zone_set_trip_temp);