Commit be6bb361 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull thermal control fixes from Rafael Wysocki:
 "Fix two issues with the user thermal thresholds feature introduced in
  this development cycle (Daniel Lezcano)"

* tag 'thermal-6.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  thermal/thresholds: Fix boundaries and detection routine
  thermal/thresholds: Fix uapi header macros leading to a compilation error
parents 5100b6f9 4feaedf7
Loading
Loading
Loading
Loading
+36 −32
Original line number Diff line number Diff line
@@ -69,58 +69,60 @@ static struct user_threshold *__thermal_thresholds_find(const struct list_head *
	return NULL;
}

static bool __thermal_threshold_is_crossed(struct user_threshold *threshold, int temperature,
					   int last_temperature, int direction,
					   int *low, int *high)
static bool thermal_thresholds_handle_raising(struct list_head *thresholds, int temperature,
					      int last_temperature)
{
	struct user_threshold *t;

	if (temperature >= threshold->temperature) {
		if (threshold->temperature > *low &&
		    THERMAL_THRESHOLD_WAY_DOWN & threshold->direction)
			*low = threshold->temperature;
	list_for_each_entry(t, thresholds, list_node) {

		if (last_temperature < threshold->temperature &&
		    threshold->direction & direction)
			return true;
	} else {
		if (threshold->temperature < *high && THERMAL_THRESHOLD_WAY_UP
		    & threshold->direction)
			*high = threshold->temperature;
		if (!(t->direction & THERMAL_THRESHOLD_WAY_UP))
		    continue;

		if (last_temperature >= threshold->temperature &&
		    threshold->direction & direction)
		if (temperature >= t->temperature &&
		    last_temperature < t->temperature)
			return true;
	}

	return false;
}

static bool thermal_thresholds_handle_raising(struct list_head *thresholds, int temperature,
					      int last_temperature, int *low, int *high)
static bool thermal_thresholds_handle_dropping(struct list_head *thresholds, int temperature,
					       int last_temperature)
{
	struct user_threshold *t;

	list_for_each_entry(t, thresholds, list_node) {
		if (__thermal_threshold_is_crossed(t, temperature, last_temperature,
						   THERMAL_THRESHOLD_WAY_UP, low, high))
	list_for_each_entry_reverse(t, thresholds, list_node) {

		if (!(t->direction & THERMAL_THRESHOLD_WAY_DOWN))
		    continue;

		if (temperature <= t->temperature &&
		    last_temperature > t->temperature)
			return true;
	}

	return false;
}

static bool thermal_thresholds_handle_dropping(struct list_head *thresholds, int temperature,
					       int last_temperature, int *low, int *high)
static void thermal_threshold_find_boundaries(struct list_head *thresholds, int temperature,
					      int *low, int *high)
{
	struct user_threshold *t;

	list_for_each_entry_reverse(t, thresholds, list_node) {
		if (__thermal_threshold_is_crossed(t, temperature, last_temperature,
						   THERMAL_THRESHOLD_WAY_DOWN, low, high))
			return true;
	list_for_each_entry(t, thresholds, list_node) {
		if (temperature < t->temperature &&
		    (t->direction & THERMAL_THRESHOLD_WAY_UP) &&
		    *high > t->temperature)
			*high = t->temperature;
	}

	return false;
	list_for_each_entry_reverse(t, thresholds, list_node) {
		if (temperature > t->temperature &&
		    (t->direction & THERMAL_THRESHOLD_WAY_DOWN) &&
		    *low < t->temperature)
			*low = t->temperature;
	}
}

void thermal_thresholds_handle(struct thermal_zone_device *tz, int *low, int *high)
@@ -132,6 +134,8 @@ void thermal_thresholds_handle(struct thermal_zone_device *tz, int *low, int *hi

	lockdep_assert_held(&tz->lock);

	thermal_threshold_find_boundaries(thresholds, temperature, low, high);

	/*
	 * We need a second update in order to detect a threshold being crossed
	 */
@@ -151,12 +155,12 @@ void thermal_thresholds_handle(struct thermal_zone_device *tz, int *low, int *hi
	 * - decreased : thresholds are crossed the way down
	 */
	if (temperature > last_temperature) {
		if (thermal_thresholds_handle_raising(thresholds, temperature,
						      last_temperature, low, high))
		if (thermal_thresholds_handle_raising(thresholds,
						      temperature, last_temperature))
			thermal_notify_threshold_up(tz);
	} else {
		if (thermal_thresholds_handle_dropping(thresholds, temperature,
						       last_temperature, low, high))
		if (thermal_thresholds_handle_dropping(thresholds,
						       temperature, last_temperature))
			thermal_notify_threshold_down(tz);
	}
}
+2 −2
Original line number Diff line number Diff line
@@ -3,8 +3,8 @@
#define _UAPI_LINUX_THERMAL_H

#define THERMAL_NAME_LENGTH	20
#define THERMAL_THRESHOLD_WAY_UP	BIT(0)
#define THERMAL_THRESHOLD_WAY_DOWN	BIT(1)
#define THERMAL_THRESHOLD_WAY_UP	0x1
#define THERMAL_THRESHOLD_WAY_DOWN	0x2

enum thermal_device_mode {
	THERMAL_DEVICE_DISABLED = 0,