Commit e3ee4ab0 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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
parents f5c05974 54fccad6
Loading
Loading
Loading
Loading
+6 −8
Original line number Diff line number Diff line
@@ -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);
		}
	}

+4 −28
Original line number Diff line number Diff line
@@ -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,14 +1396,9 @@ 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)
	if (polling_delay && passive_delay > polling_delay)
		return ERR_PTR(-EINVAL);

		if (!passive_delay)
			passive_delay = polling_delay;
	}

	if (!thermal_class)
		return ERR_PTR(-ENODEV);

+0 −3
Original line number Diff line number Diff line
@@ -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__ */
+39 −13
Original line number Diff line number Diff line
@@ -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,7 +111,16 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,

	mutex_lock(&tz->lock);

	if (temp != trip->temperature) {
	if (temp == trip->temperature)
		goto unlock;

	/* 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)
@@ -121,7 +130,6 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
	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) {
	if (hyst == trip->hysteresis)
		goto unlock;

	/*
	 * 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