mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 13:22:23 +00:00
Thermal control fix for 6.11-rc4
Fix a Bang-bang thermal governor issue causing it to fail to reset the state of cooling devices if they are "on" to start with, but the thermal zone temperature is always below the corresponding trip point (Rafael Wysocki). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAma/fRgSHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRxQfsP/2YtRcpov/GInIuS4oKo9YvrsjzcCrQQ puYrR5JaPpiAoIqcXEva4UQdInr7lyjDcmy9V3lKayZrMwph8nLo4eh665Pp6pDw k1EqKNsu3Id29Xpto1famGvCUrsOHF0QSyVAP4AQNylHhZjDlgBsRvgitrY8Pz3a 91/7u5P5l4xmVsAu9R+v9AfuE1DjDynpp4NY/h7SE3Ytf7KHNra8UThRhXeVqcKt IXgk4GLpZ2mE17AggLrmlY4kToEXQCtgbD9tub0q3x0SoWO0tFuhWLirM4gTcjgm iqByW8t0JDZMHh53ZLxB9C1ycSYzoPm6FPVTYmPss2i/JklO1K/mOybCps+CIvsp ly0o1Q4Vjsub3guPs1sXh2ljHNLwWdzT8xsdqgNTTv3t7PqxM0uV/3T07cXTblxe Xd0InP15hrbqAzJtyZ4tGo4dmV0bmYRxUauVhHIXlK3Nc8Dum2/lFg+y3TNcQQbe sbEc0UPwSpeONWE485u4A4rBLkEWPOlJVucUMlnmTsryGovy/18nOCoY4c+Um9yr QeE6d3u5XH4DblZ2gqJzpKukFl7YSEWRI/Cazd5cQQlfC5QEJRP5f3LmGN9Jc2I8 3DcL/Nwr6i5dgRbcBua1xs0nNS+1T9IwweHHtwrGzw063a7EyhC0gplBHnxCsj/0 ZCac0P2iz4rw =Q7ZJ -----END PGP SIGNATURE----- Merge tag 'thermal-6.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull thermal control fix from Rafael Wysocki: "Fix a Bang-bang thermal governor issue causing it to fail to reset the state of cooling devices if they are 'on' to start with, but the thermal zone temperature is always below the corresponding trip point (Rafael Wysocki)" * tag 'thermal-6.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: thermal: gov_bang_bang: Use governor_data to reduce overhead thermal: gov_bang_bang: Add .manage() callback thermal: gov_bang_bang: Split bang_bang_control() thermal: gov_bang_bang: Call __thermal_cdev_update() directly
This commit is contained in:
commit
296c871d29
@ -13,6 +13,28 @@
|
||||
|
||||
#include "thermal_core.h"
|
||||
|
||||
static void bang_bang_set_instance_target(struct thermal_instance *instance,
|
||||
unsigned int target)
|
||||
{
|
||||
if (instance->target != 0 && instance->target != 1 &&
|
||||
instance->target != THERMAL_NO_TARGET)
|
||||
pr_debug("Unexpected state %ld of thermal instance %s in bang-bang\n",
|
||||
instance->target, instance->name);
|
||||
|
||||
/*
|
||||
* Enable the fan when the trip is crossed on the way up and disable it
|
||||
* when the trip is crossed on the way down.
|
||||
*/
|
||||
instance->target = target;
|
||||
instance->initialized = true;
|
||||
|
||||
dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
|
||||
|
||||
mutex_lock(&instance->cdev->lock);
|
||||
__thermal_cdev_update(instance->cdev);
|
||||
mutex_unlock(&instance->cdev->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* bang_bang_control - controls devices associated with the given zone
|
||||
* @tz: thermal_zone_device
|
||||
@ -54,33 +76,60 @@ static void bang_bang_control(struct thermal_zone_device *tz,
|
||||
tz->temperature, trip->hysteresis);
|
||||
|
||||
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
|
||||
if (instance->trip != trip)
|
||||
if (instance->trip == trip)
|
||||
bang_bang_set_instance_target(instance, crossed_up);
|
||||
}
|
||||
}
|
||||
|
||||
static void bang_bang_manage(struct thermal_zone_device *tz)
|
||||
{
|
||||
const struct thermal_trip_desc *td;
|
||||
struct thermal_instance *instance;
|
||||
|
||||
/* If the code below has run already, nothing needs to be done. */
|
||||
if (tz->governor_data)
|
||||
return;
|
||||
|
||||
for_each_trip_desc(tz, td) {
|
||||
const struct thermal_trip *trip = &td->trip;
|
||||
|
||||
if (tz->temperature >= td->threshold ||
|
||||
trip->temperature == THERMAL_TEMP_INVALID ||
|
||||
trip->type == THERMAL_TRIP_CRITICAL ||
|
||||
trip->type == THERMAL_TRIP_HOT)
|
||||
continue;
|
||||
|
||||
if (instance->target != 0 && instance->target != 1 &&
|
||||
instance->target != THERMAL_NO_TARGET)
|
||||
pr_debug("Unexpected state %ld of thermal instance %s in bang-bang\n",
|
||||
instance->target, instance->name);
|
||||
|
||||
/*
|
||||
* Enable the fan when the trip is crossed on the way up and
|
||||
* disable it when the trip is crossed on the way down.
|
||||
* 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.
|
||||
*/
|
||||
instance->target = crossed_up;
|
||||
|
||||
dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
|
||||
|
||||
mutex_lock(&instance->cdev->lock);
|
||||
instance->cdev->updated = false; /* cdev needs update */
|
||||
mutex_unlock(&instance->cdev->lock);
|
||||
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
|
||||
if (!instance->initialized && instance->trip == trip)
|
||||
bang_bang_set_instance_target(instance, 0);
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(instance, &tz->thermal_instances, tz_node)
|
||||
thermal_cdev_update(instance->cdev);
|
||||
tz->governor_data = (void *)true;
|
||||
}
|
||||
|
||||
static void bang_bang_update_tz(struct thermal_zone_device *tz,
|
||||
enum thermal_notify_event reason)
|
||||
{
|
||||
/*
|
||||
* Let bang_bang_manage() know that it needs to walk trips after binding
|
||||
* a new cdev and after system resume.
|
||||
*/
|
||||
if (reason == THERMAL_TZ_BIND_CDEV || reason == THERMAL_TZ_RESUME)
|
||||
tz->governor_data = NULL;
|
||||
}
|
||||
|
||||
static struct thermal_governor thermal_gov_bang_bang = {
|
||||
.name = "bang_bang",
|
||||
.trip_crossed = bang_bang_control,
|
||||
.manage = bang_bang_manage,
|
||||
.update_tz = bang_bang_update_tz,
|
||||
};
|
||||
THERMAL_GOVERNOR_DECLARE(thermal_gov_bang_bang);
|
||||
|
@ -1728,7 +1728,8 @@ static void thermal_zone_device_resume(struct work_struct *work)
|
||||
|
||||
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;
|
||||
|
@ -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 is resuming after system sleep */
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user