diff options
author | Daniel Lezcano <daniel.lezcano@linaro.org> | 2022-07-07 19:59:38 +0200 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2022-07-07 19:59:38 +0200 |
commit | 8d2f47a16dfb057c99cb78df85f7d24f7975b36d (patch) | |
tree | 09f886af90c753f428e009a3d4c5c7d46e8ff7b5 | |
parent | f180a56ad98f04a224d3e16ffd73c5d082293fab (diff) | |
download | linux-thermal/debugfs-v2.tar.gz |
thermal/core: Fix thermal trip cross pointthermal/debugfs-v2
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r-- | drivers/thermal/thermal_core.c | 32 | ||||
-rw-r--r-- | include/linux/thermal.h | 2 |
2 files changed, 24 insertions, 10 deletions
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index d4207805b6f670..264db84107296a 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -357,19 +357,30 @@ static void handle_critical_trips(struct thermal_zone_device *tz, static void handle_thermal_trip_crossed(struct thermal_zone_device *tz, int trip, int trip_temp, int trip_hyst, enum thermal_trip_type trip_type) { + int trip_low_temp = trip_temp - trip_hyst; + if (tz->last_temperature == THERMAL_TEMP_INVALID) return; - if (tz->last_temperature < trip_temp && - tz->temperature >= trip_temp) { - thermal_notify_tz_trip_up(tz->id, trip, - tz->temperature); - } - - if (tz->last_temperature >= trip_temp && - tz->temperature < (trip_temp - trip_hyst)) { - thermal_notify_tz_trip_down(tz->id, trip, - tz->temperature); + /* + * Due to the hysteresis, a third information is needed to + * detect when the temperature is wavering between the + * trip_low_temp and the trip_temp. A trip point is crossed + * the way up only if the temperature is above it while the + * previous temperature was below *and* we crossed the + * trip_temp_low before. The previous trip point give us the + * previous trip point transition. The similar problem exists + * when crossing the way down. + */ + if (tz->last_temperature < trip_temp && tz->temperature >= trip_temp && + trip != tz->prev_trip) { + thermal_notify_tz_trip_up(tz->id, trip, tz->temperature); + tz->prev_trip = trip; + + } else if (tz->last_temperature >= trip_low_temp && tz->temperature < trip_low_temp && + trip == tz->prev_trip) { + thermal_notify_tz_trip_down(tz->id, trip, tz->temperature); + tz->prev_trip = trip - 1; } } @@ -430,6 +441,7 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz) { struct thermal_instance *pos; tz->temperature = THERMAL_TEMP_INVALID; + tz->prev_trip = -1; tz->prev_low_trip = -INT_MAX; tz->prev_high_trip = INT_MAX; list_for_each_entry(pos, &tz->thermal_instances, tz_node) diff --git a/include/linux/thermal.h b/include/linux/thermal.h index c8528bb6c01cb8..81156c16f8bac4 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -127,6 +127,7 @@ struct thermal_cooling_device { * @last_temperature: previous temperature read * @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION * @passive: 1 if you've crossed a passive trip point, 0 otherwise. + * @prev_trip: previous trip point the thermal zone was, -1 if below all of them * @prev_low_trip: the low current temperature if you've crossed a passive trip point. * @prev_high_trip: the above current temperature if you've crossed a @@ -162,6 +163,7 @@ struct thermal_zone_device { int last_temperature; int emul_temperature; int passive; + int prev_trip; int prev_low_trip; int prev_high_trip; atomic_t need_update; |