Merge branch 'thermal-core'

Merge thermal core fixes and cleanups for 6.12:

 - Refuse to accept trip point temperature or hysteresis that would lead
   to an invalid threshold value when setting them via sysfs (Rafael
   Wysocki).

 - Adjust states of all uninitialized instances in the .manage()
   callback of the Bang-bang thermal governor (Rafael Wysocki).

 - Drop a couple of redundant checks along with the code depending on
   them from the thermal core (Rafael Wysocki).

 - Rearrange the thermal core to avoid redundant checks and simplify
   control flow in a couple of code paths (Rafael Wysocki).

* thermal-core:
  thermal: core: Drop thermal_zone_device_is_enabled()
  thermal: core: Check passive delay in monitor_thermal_zone()
  thermal: core: Drop dead code from monitor_thermal_zone()
  thermal: core: Drop redundant lockdep_assert_held()
  thermal: gov_bang_bang: Adjust states of all uninitialized instances
  thermal: sysfs: Add sanity checks for trip temperature and hysteresis
This commit is contained in:
Rafael J. Wysocki 2024-09-09 18:18:49 +02:00
commit e3ee4ab0fd
4 changed files with 50 additions and 53 deletions

View File

@ -92,23 +92,21 @@ static void bang_bang_manage(struct thermal_zone_device *tz)
for_each_trip_desc(tz, td) {
const struct thermal_trip *trip = &td->trip;
bool turn_on;
if (tz->temperature >= td->threshold ||
trip->temperature == THERMAL_TEMP_INVALID ||
if (trip->temperature == THERMAL_TEMP_INVALID ||
trip->type == THERMAL_TRIP_CRITICAL ||
trip->type == THERMAL_TRIP_HOT)
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.
* Adjust the target states for uninitialized thermal instances
* to the thermal zone temperature and the trip point threshold.
*/
turn_on = tz->temperature >= td->threshold;
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
if (!instance->initialized && instance->trip == trip)
bang_bang_set_instance_target(instance, 0);
bang_bang_set_instance_target(instance, turn_on);
}
}

View File

@ -323,11 +323,6 @@ static void thermal_zone_broken_disable(struct thermal_zone_device *tz)
static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
unsigned long delay)
{
if (!delay) {
cancel_delayed_work(&tz->poll_queue);
return;
}
if (delay > HZ)
delay = round_jiffies_relative(delay);
@ -364,9 +359,7 @@ static void thermal_zone_recheck(struct thermal_zone_device *tz, int error)
static void monitor_thermal_zone(struct thermal_zone_device *tz)
{
if (tz->mode != THERMAL_DEVICE_ENABLED)
thermal_zone_device_set_polling(tz, 0);
else if (tz->passive > 0)
if (tz->passive > 0 && tz->passive_delay_jiffies)
thermal_zone_device_set_polling(tz, tz->passive_delay_jiffies);
else if (tz->polling_delay_jiffies)
thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies);
@ -554,10 +547,7 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz,
int low = -INT_MAX, high = INT_MAX;
int temp, ret;
if (tz->suspended)
return;
if (!thermal_zone_device_is_enabled(tz))
if (tz->suspended || tz->mode != THERMAL_DEVICE_ENABLED)
return;
ret = __thermal_zone_get_temp(tz, &temp);
@ -659,13 +649,6 @@ int thermal_zone_device_disable(struct thermal_zone_device *tz)
}
EXPORT_SYMBOL_GPL(thermal_zone_device_disable);
int thermal_zone_device_is_enabled(struct thermal_zone_device *tz)
{
lockdep_assert_held(&tz->lock);
return tz->mode == THERMAL_DEVICE_ENABLED;
}
static bool thermal_zone_is_present(struct thermal_zone_device *tz)
{
return !list_empty(&tz->node);
@ -891,8 +874,6 @@ static void thermal_unbind_cdev_from_trip(struct thermal_zone_device *tz,
{
struct thermal_instance *pos, *next;
lockdep_assert_held(&tz->lock);
mutex_lock(&cdev->lock);
list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
if (pos->trip == trip && pos->cdev == cdev) {
@ -1415,13 +1396,8 @@ thermal_zone_device_register_with_trips(const char *type,
if (num_trips > 0 && !trips)
return ERR_PTR(-EINVAL);
if (polling_delay) {
if (passive_delay > polling_delay)
return ERR_PTR(-EINVAL);
if (!passive_delay)
passive_delay = polling_delay;
}
if (polling_delay && passive_delay > polling_delay)
return ERR_PTR(-EINVAL);
if (!thermal_class)
return ERR_PTR(-ENODEV);

View File

@ -284,7 +284,4 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
unsigned long new_state) {}
#endif /* CONFIG_THERMAL_STATISTICS */
/* device tree support */
int thermal_zone_device_is_enabled(struct thermal_zone_device *tz);
#endif /* __THERMAL_CORE_H__ */

View File

@ -53,7 +53,7 @@ mode_show(struct device *dev, struct device_attribute *attr, char *buf)
int enabled;
mutex_lock(&tz->lock);
enabled = thermal_zone_device_is_enabled(tz);
enabled = tz->mode == THERMAL_DEVICE_ENABLED;
mutex_unlock(&tz->lock);
return sprintf(buf, "%s\n", enabled ? "enabled" : "disabled");
@ -111,18 +111,26 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
mutex_lock(&tz->lock);
if (temp != trip->temperature) {
if (tz->ops.set_trip_temp) {
ret = tz->ops.set_trip_temp(tz, trip, temp);
if (ret)
goto unlock;
}
if (temp == trip->temperature)
goto unlock;
thermal_zone_set_trip_temp(tz, trip, temp);
__thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
/* Arrange the condition to avoid integer overflows. */
if (temp != THERMAL_TEMP_INVALID &&
temp <= trip->hysteresis + THERMAL_TEMP_INVALID) {
ret = -EINVAL;
goto unlock;
}
if (tz->ops.set_trip_temp) {
ret = tz->ops.set_trip_temp(tz, trip, temp);
if (ret)
goto unlock;
}
thermal_zone_set_trip_temp(tz, trip, temp);
__thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
unlock:
mutex_unlock(&tz->lock);
@ -152,15 +160,33 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
mutex_lock(&tz->lock);
if (hyst != trip->hysteresis) {
thermal_zone_set_trip_hyst(tz, trip, hyst);
if (hyst == trip->hysteresis)
goto unlock;
__thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
/*
* Allow the hysteresis to be updated when the temperature is invalid
* to allow user space to avoid having to adjust hysteresis after a
* valid temperature has been set, but in that case just change the
* value and do nothing else.
*/
if (trip->temperature == THERMAL_TEMP_INVALID) {
WRITE_ONCE(trip->hysteresis, hyst);
goto unlock;
}
if (trip->temperature - hyst <= THERMAL_TEMP_INVALID) {
ret = -EINVAL;
goto unlock;
}
thermal_zone_set_trip_hyst(tz, trip, hyst);
__thermal_zone_device_update(tz, THERMAL_TRIP_CHANGED);
unlock:
mutex_unlock(&tz->lock);
return count;
return ret ? ret : count;
}
static ssize_t