Commit cee84c0b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'thermal-6.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull thermal control fixes from Rafael Wysocki:
 "These fix three issues introduced recently, two related to defects in
  ACPI tables supplied by the platform firmware and one cause by a
  thermal core change that went too far:

   - Prevent the thermal core from failing the registration of a cooling
     device if its .get_cur_state() reports an incorrect state to start
     with which may happen for fans handled through firmware-supplied
     AML in ACPI tables (Rafael Wysocki)

   - Make the ACPI thermal zone driver initialize all trip points with
     temperature of 0 centigrade and below as invalid because such trip
     point temperatures do not make sense on systems with ACPI thermal
     control and they cause performance regressions due to permanent
     thermal mitigations to occur (Rafael Wysocki)

   - Restore passive polling management in the Step-Wise thermal
     governor that uses it to ensure that all cooling devices used for
     thermal mitigation will go back to their initial states eventually
     (Rafael Wysocki)"

* tag 'thermal-6.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  thermal: gov_step_wise: Restore passive polling management
  thermal: ACPI: Invalidate trip points with temperature of 0 or below
  thermal: core: Do not fail cdev registration because of invalid initial state
parents d20f6b3d b6846826
...@@ -168,11 +168,17 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) ...@@ -168,11 +168,17 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k) static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k)
{ {
int temp;
if (temp_deci_k == THERMAL_TEMP_INVALID) if (temp_deci_k == THERMAL_TEMP_INVALID)
return THERMAL_TEMP_INVALID; return THERMAL_TEMP_INVALID;
return deci_kelvin_to_millicelsius_with_offset(temp_deci_k, temp = deci_kelvin_to_millicelsius_with_offset(temp_deci_k,
tz->kelvin_offset); tz->kelvin_offset);
if (temp <= 0)
return THERMAL_TEMP_INVALID;
return temp;
} }
static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip) static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip)
......
...@@ -93,6 +93,23 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, ...@@ -93,6 +93,23 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
if (instance->initialized && old_target == instance->target) if (instance->initialized && old_target == instance->target)
continue; continue;
if (trip->type == THERMAL_TRIP_PASSIVE) {
/*
* If the target state for this thermal instance
* changes from THERMAL_NO_TARGET to something else,
* ensure that the zone temperature will be updated
* (assuming enabled passive cooling) until it becomes
* THERMAL_NO_TARGET again, or the cooling device may
* not be reset to its initial state.
*/
if (old_target == THERMAL_NO_TARGET &&
instance->target != THERMAL_NO_TARGET)
tz->passive++;
else if (old_target != THERMAL_NO_TARGET &&
instance->target == THERMAL_NO_TARGET)
tz->passive--;
}
instance->initialized = true; instance->initialized = true;
mutex_lock(&instance->cdev->lock); mutex_lock(&instance->cdev->lock);
......
...@@ -999,9 +999,17 @@ __thermal_cooling_device_register(struct device_node *np, ...@@ -999,9 +999,17 @@ __thermal_cooling_device_register(struct device_node *np,
if (ret) if (ret)
goto out_cdev_type; goto out_cdev_type;
/*
* The cooling device's current state is only needed for debug
* initialization below, so a failure to get it does not cause
* the entire cooling device initialization to fail. However,
* the debug will not work for the device if its initial state
* cannot be determined and drivers are responsible for ensuring
* that this will not happen.
*/
ret = cdev->ops->get_cur_state(cdev, &current_state); ret = cdev->ops->get_cur_state(cdev, &current_state);
if (ret) if (ret)
goto out_cdev_type; current_state = ULONG_MAX;
thermal_cooling_device_setup_sysfs(cdev); thermal_cooling_device_setup_sysfs(cdev);
...@@ -1016,7 +1024,8 @@ __thermal_cooling_device_register(struct device_node *np, ...@@ -1016,7 +1024,8 @@ __thermal_cooling_device_register(struct device_node *np,
return ERR_PTR(ret); return ERR_PTR(ret);
} }
thermal_debug_cdev_add(cdev, current_state); if (current_state <= cdev->max_state)
thermal_debug_cdev_add(cdev, current_state);
/* Add 'this' new cdev to the global cdev list */ /* Add 'this' new cdev to the global cdev list */
mutex_lock(&thermal_list_lock); mutex_lock(&thermal_list_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment