--- drivers/thermal/gov_bang_bang.c | 34 ++++++++++++++++++++++++++++++++++ drivers/thermal/thermal_core.c | 3 ++- include/linux/thermal.h | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) Index: linux-pm/drivers/thermal/gov_bang_bang.c =================================================================== --- linux-pm.orig/drivers/thermal/gov_bang_bang.c +++ linux-pm/drivers/thermal/gov_bang_bang.c @@ -79,8 +79,42 @@ static void bang_bang_control(struct the thermal_cdev_update(instance->cdev); } +static void bang_bang_update_tz(struct thermal_zone_device *tz, + enum thermal_notify_event reason) +{ + struct thermal_instance *instance; + + lockdep_assert_held(&tz->lock); + + if (reason != THERMAL_TZ_BIND_CDEV && reason != THERMAL_TZ_RESUME) + return; + + list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + const struct thermal_trip *trip = instance->trip; + + if (instance->initialized) + continue; + + /* + * If the initial cooling device state is "on", but the zone + * temperature is not above the trip point, the core will not + * call bang_bang_control() until the zone temperature reaches + * the trip point temperature which may be never. In those + * cases, set the initial state of the cooling device to 0. + */ + if (tz->temperature < trip->temperature) + bang_bang_control(tz, trip, 0); + + instance->initialized = true; + } + + list_for_each_entry(instance, &tz->thermal_instances, tz_node) + thermal_cdev_update(instance->cdev); +} + static struct thermal_governor thermal_gov_bang_bang = { .name = "bang_bang", .trip_crossed = bang_bang_control, + .update_tz = bang_bang_update_tz, }; THERMAL_GOVERNOR_DECLARE(thermal_gov_bang_bang); Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -1711,7 +1711,8 @@ static void thermal_zone_device_resume(s thermal_debug_tz_resume(tz); thermal_zone_device_init(tz); - __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + thermal_governor_update_tz(tz, THERMAL_TZ_RESUME); + __thermal_zone_device_update(tz, THERMAL_TZ_RESUME); complete(&tz->resume); tz->resuming = false; Index: linux-pm/include/linux/thermal.h =================================================================== --- linux-pm.orig/include/linux/thermal.h +++ linux-pm/include/linux/thermal.h @@ -55,6 +55,7 @@ enum thermal_notify_event { THERMAL_TZ_BIND_CDEV, /* Cooling dev is bind to the thermal zone */ THERMAL_TZ_UNBIND_CDEV, /* Cooling dev is unbind from the thermal zone */ THERMAL_INSTANCE_WEIGHT_CHANGED, /* Thermal instance weight changed */ + THERMAL_TZ_RESUME, /* Thermal zone resume after system sleep */ }; /**