--- zzzz-none-000/linux-4.4.60/drivers/thermal/fair_share.c 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-1750e-727/linux-4.4.60/drivers/thermal/fair_share.c 2021-02-04 17:41:59.000000000 +0000 @@ -23,39 +23,72 @@ */ #include +#include #include #include "thermal_core.h" +struct avm_fair_share_data { + int current_trip; +}; + /** * get_trip_level: - obtains the current trip level for a zone * @tz: thermal zone device */ static int get_trip_level(struct thermal_zone_device *tz) { - int count = 0; - int trip_temp; + int trip = 0; + int trip_temp, trip_hyst; enum thermal_trip_type trip_type; + struct avm_fair_share_data *data = tz->governor_data; if (tz->trips == 0 || !tz->ops->get_trip_temp) return 0; - for (count = 0; count < tz->trips; count++) { - tz->ops->get_trip_temp(tz, count, &trip_temp); - if (tz->temperature < trip_temp) - break; + trip = data->current_trip; + + while (trip >= -1 && trip < tz->trips) { + // Check if we need to raise the trip level + if (trip + 1 < tz->trips) { + tz->ops->get_trip_temp(tz, trip + 1, &trip_temp); + + // Raise it and try again + if (tz->temperature >= trip_temp) { + trip++; + continue; + } + } + + if (trip >= 0) { + // Check if we need to lower the trip and try agian + tz->ops->get_trip_temp(tz, trip, &trip_temp); + tz->ops->get_trip_hyst(tz, trip, &trip_hyst); + + if (tz->temperature < trip_temp - trip_hyst) { + trip--; + continue; + } + } + + break; } /* * count > 0 only if temperature is greater than first trip * point, in which case, trip_point = count - 1 */ - if (count > 0) { - tz->ops->get_trip_type(tz, count - 1, &trip_type); - trace_thermal_zone_trip(tz, count - 1, trip_type); + if (trip >= 0) { + tz->ops->get_trip_type(tz, trip, &trip_type); + trace_thermal_zone_trip(tz, trip, trip_type); } - return count; + if (data->current_trip != trip) + pr_err("[avm_fair_share] change trip level %d -> %d for temp %d\n", + data->current_trip, trip, tz->temperature); + data->current_trip = trip; + + return trip + 1; } static long get_target_state(struct thermal_zone_device *tz, @@ -122,8 +155,22 @@ return 0; } +static int avm_fair_share_bind(struct thermal_zone_device *tz) +{ + tz->governor_data = kzalloc(sizeof(struct avm_fair_share_data), GFP_KERNEL); + + return 0; +} + +static void avm_fair_share_unbind(struct thermal_zone_device *tz) +{ + kfree(tz->governor_data); +} + static struct thermal_governor thermal_gov_fair_share = { .name = "fair_share", + .bind_to_tz = avm_fair_share_bind, + .unbind_from_tz = avm_fair_share_unbind, .throttle = fair_share_throttle, };