From 2d213f2cda357bcf618bfd8e53d6025ea9f9a7cc Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 19 Sep 2023 20:54:37 +0200 Subject: [PATCH 01/25] thermal: core: Drop trips_disabled bitmask ANBZ: #32620 commit 950210887670cbb7d2eb9af6fb743b70f1a1ebdc upstream. After recent changes, thermal_zone_get_trip() cannot fail, as invoked from thermal_zone_device_register_with_trips(), so the only role of the trips_disabled bitmask is struct thermal_zone_device is to make handle_thermal_trip() skip trip points whose temperature was initially zero. However, since the unit of temperature in the thermal core is millicelsius, zero may very well be a valid temperature value at least in some usage scenarios and the trip temperature may as well change later. Thus there is no reason to permanently disable trip points with initial temperature equal to zero. Accordingly, drop the trips_disabled bitmask along with the code related to it. Signed-off-by: Rafael J. Wysocki Tested-by: Ido Schimmel Acked-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/thermal/thermal_core.c | 13 ------------- include/linux/thermal.h | 2 -- 2 files changed, 15 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index dad909547179..292de863b5d7 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -345,10 +345,6 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip_id) { struct thermal_trip trip; - /* Ignore disabled trip points */ - if (test_bit(trip_id, &tz->trips_disabled)) - return; - __thermal_zone_get_trip(tz, trip_id, &trip); if (trip.temperature == THERMAL_TEMP_INVALID) @@ -1241,7 +1237,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t struct thermal_zone_device *tz; int id; int result; - int count; struct thermal_governor *governor; if (!type || strlen(type) == 0) { @@ -1341,14 +1336,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t if (result) goto release_device; - for (count = 0; count < num_trips; count++) { - struct thermal_trip trip; - - result = thermal_zone_get_trip(tz, count, &trip); - if (result || !trip.temperature) - set_bit(count, &tz->trips_disabled); - } - /* Update 'this' zone's governor information */ mutex_lock(&thermal_governor_lock); diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 2e9d18ba4653..0cb15afbf458 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -123,7 +123,6 @@ struct thermal_cooling_device { * @devdata: private pointer for device private data * @trips: an array of struct thermal_trip * @num_trips: number of trip points the thermal zone supports - * @trips_disabled; bitmap for disabled trips * @passive_delay_jiffies: number of jiffies to wait between polls when * performing passive cooling. * @polling_delay_jiffies: number of jiffies to wait between polls when @@ -166,7 +165,6 @@ struct thermal_zone_device { void *devdata; struct thermal_trip *trips; int num_trips; - unsigned long trips_disabled; /* bitmap for disabled trips */ unsigned long passive_delay_jiffies; unsigned long polling_delay_jiffies; int temperature; -- Gitee From f07c4a5015d2e601ed3ebc8ea7e9e1236b7b4d1e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 20:01:43 +0200 Subject: [PATCH 02/25] thermal: core: Allow trip pointers to be used for cooling device binding ANBZ: #32620 commit d069ed6b752f91cea6341a9c60be42837678a7f5 upstream. Add new helper functions, thermal_bind_cdev_to_trip() and thermal_unbind_cdev_from_trip(), to allow a trip pointer to be used for binding a cooling device to a trip point and unbinding it, respectively, and redefine the existing helpers, thermal_zone_bind_cooling_device() and thermal_zone_unbind_cooling_device(), as wrappers around the new ones, respectively. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/thermal/thermal_core.c | 54 +++++++++++++++++++++------------- include/linux/thermal.h | 8 +++++ 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 292de863b5d7..3ef4a7c36cd1 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -603,10 +603,9 @@ struct thermal_zone_device *thermal_zone_get_by_id(int id) */ /** - * thermal_zone_bind_cooling_device() - bind a cooling device to a thermal zone + * thermal_bind_cdev_to_trip - bind a cooling device to a thermal zone * @tz: pointer to struct thermal_zone_device - * @trip_index: indicates which trip point the cooling devices is - * associated with in this thermal zone. + * @trip: trip point the cooling devices is associated with in this zone. * @cdev: pointer to struct thermal_cooling_device * @upper: the Maximum cooling state for this trip point. * THERMAL_NO_LIMIT means no upper limit, @@ -624,8 +623,8 @@ struct thermal_zone_device *thermal_zone_get_by_id(int id) * * Return: 0 on success, the proper error value otherwise. */ -int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, - int trip_index, +int thermal_bind_cdev_to_trip(struct thermal_zone_device *tz, + const struct thermal_trip *trip, struct thermal_cooling_device *cdev, unsigned long upper, unsigned long lower, unsigned int weight) @@ -634,15 +633,9 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, struct thermal_instance *pos; struct thermal_zone_device *pos1; struct thermal_cooling_device *pos2; - const struct thermal_trip *trip; bool upper_no_limit; int result; - if (trip_index >= tz->num_trips || trip_index < 0) - return -EINVAL; - - trip = &tz->trips[trip_index]; - list_for_each_entry(pos1, &thermal_tz_list, node) { if (pos1 == tz) break; @@ -741,14 +734,26 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, kfree(dev); return result; } +EXPORT_SYMBOL_GPL(thermal_bind_cdev_to_trip); + +int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, + int trip_index, + struct thermal_cooling_device *cdev, + unsigned long upper, unsigned long lower, + unsigned int weight) +{ + if (trip_index < 0 || trip_index >= tz->num_trips) + return -EINVAL; + + return thermal_bind_cdev_to_trip(tz, &tz->trips[trip_index], cdev, + upper, lower, weight); +} EXPORT_SYMBOL_GPL(thermal_zone_bind_cooling_device); /** - * thermal_zone_unbind_cooling_device() - unbind a cooling device from a - * thermal zone. + * thermal_unbind_cdev_from_trip - unbind a cooling device from a thermal zone. * @tz: pointer to a struct thermal_zone_device. - * @trip_index: indicates which trip point the cooling devices is - * associated with in this thermal zone. + * @trip: trip point the cooling devices is associated with in this zone. * @cdev: pointer to a struct thermal_cooling_device. * * This interface function unbind a thermal cooling device from the certain @@ -757,16 +762,14 @@ EXPORT_SYMBOL_GPL(thermal_zone_bind_cooling_device); * * Return: 0 on success, the proper error value otherwise. */ -int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, - int trip_index, - struct thermal_cooling_device *cdev) +int thermal_unbind_cdev_from_trip(struct thermal_zone_device *tz, + const struct thermal_trip *trip, + struct thermal_cooling_device *cdev) { struct thermal_instance *pos, *next; - const struct thermal_trip *trip; mutex_lock(&tz->lock); mutex_lock(&cdev->lock); - trip = &tz->trips[trip_index]; list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) { if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { list_del(&pos->tz_node); @@ -789,6 +792,17 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, kfree(pos); return 0; } +EXPORT_SYMBOL_GPL(thermal_unbind_cdev_from_trip); + +int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, + int trip_index, + struct thermal_cooling_device *cdev) +{ + if (trip_index < 0 || trip_index >= tz->num_trips) + return -EINVAL; + + return thermal_unbind_cdev_from_trip(tz, &tz->trips[trip_index], cdev); +} EXPORT_SYMBOL_GPL(thermal_zone_unbind_cooling_device); static void thermal_release(struct device *dev) diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 0cb15afbf458..77e6b0fc4481 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -324,10 +324,18 @@ const char *thermal_zone_device_type(struct thermal_zone_device *tzd); int thermal_zone_device_id(struct thermal_zone_device *tzd); struct device *thermal_zone_device(struct thermal_zone_device *tzd); +int thermal_bind_cdev_to_trip(struct thermal_zone_device *tz, + const struct thermal_trip *trip, + struct thermal_cooling_device *cdev, + unsigned long upper, unsigned long lower, + unsigned int weight); int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, struct thermal_cooling_device *, unsigned long, unsigned long, unsigned int); +int thermal_unbind_cdev_from_trip(struct thermal_zone_device *tz, + const struct thermal_trip *trip, + struct thermal_cooling_device *cdev); int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, struct thermal_cooling_device *); void thermal_zone_device_update(struct thermal_zone_device *, -- Gitee From cfe7ffd88c396f668e93116afa218b5315d24faa Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 20:02:59 +0200 Subject: [PATCH 03/25] ACPI: thermal: Do not use trip indices for cooling device binding ANBZ: #32620 commit d5ea889246b112e228433a5f27f57af90ca0c1fb upstream. Rearrange the ACPI thermal driver's callback functions used for cooling device binding and unbinding, acpi_thermal_bind_cooling_device() and acpi_thermal_unbind_cooling_device(), respectively, so that they use trip pointers instead of trip indices which is more straightforward and allows the driver to become independent of the ordering of trips in the thermal zone structure. The general functionality is not expected to be changed. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/acpi/thermal.c | 110 +++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 66 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 4148a79125ad..860b0fc2846b 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -577,94 +577,72 @@ static void acpi_thermal_zone_device_critical(struct thermal_zone_device *therma thermal_zone_device_critical(thermal); } -static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, - struct thermal_cooling_device *cdev, - bool bind) +struct acpi_thermal_bind_data { + struct thermal_zone_device *thermal; + struct thermal_cooling_device *cdev; + bool bind; +}; + +static int bind_unbind_cdev_cb(struct thermal_trip *trip, void *arg) { - struct acpi_device *device = cdev->devdata; - struct acpi_thermal *tz = thermal_zone_device_priv(thermal); - struct acpi_thermal_trip *acpi_trip; - struct acpi_device *dev; - acpi_handle handle; + struct acpi_thermal_trip *acpi_trip = trip->priv; + struct acpi_thermal_bind_data *bd = arg; + struct thermal_zone_device *thermal = bd->thermal; + struct thermal_cooling_device *cdev = bd->cdev; + struct acpi_device *cdev_adev = cdev->devdata; int i; - int j; - int trip = -1; - int result = 0; - if (tz->trips.critical_valid) - trip++; + /* Skip critical and hot trips. */ + if (!acpi_trip) + return 0; - if (tz->trips.hot_valid) - trip++; + for (i = 0; i < acpi_trip->devices.count; i++) { + acpi_handle handle = acpi_trip->devices.handles[i]; + struct acpi_device *adev = acpi_fetch_acpi_dev(handle); - acpi_trip = &tz->trips.passive.trip; - if (acpi_thermal_trip_valid(acpi_trip)) { - trip++; - for (i = 0; i < acpi_trip->devices.count; i++) { - handle = acpi_trip->devices.handles[i]; - dev = acpi_fetch_acpi_dev(handle); - if (dev != device) - continue; - - if (bind) - result = thermal_zone_bind_cooling_device( - thermal, trip, cdev, - THERMAL_NO_LIMIT, - THERMAL_NO_LIMIT, - THERMAL_WEIGHT_DEFAULT); - else - result = - thermal_zone_unbind_cooling_device( - thermal, trip, cdev); - - if (result) - goto failed; - } - } + if (adev != cdev_adev) + continue; - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - acpi_trip = &tz->trips.active[i].trip; - if (!acpi_thermal_trip_valid(acpi_trip)) - break; + if (bd->bind) { + int ret; - trip++; - for (j = 0; j < acpi_trip->devices.count; j++) { - handle = acpi_trip->devices.handles[j]; - dev = acpi_fetch_acpi_dev(handle); - if (dev != device) - continue; - - if (bind) - result = thermal_zone_bind_cooling_device( - thermal, trip, cdev, - THERMAL_NO_LIMIT, - THERMAL_NO_LIMIT, - THERMAL_WEIGHT_DEFAULT); - else - result = thermal_zone_unbind_cooling_device( - thermal, trip, cdev); - - if (result) - goto failed; + ret = thermal_bind_cdev_to_trip(thermal, trip, cdev, + THERMAL_NO_LIMIT, + THERMAL_NO_LIMIT, + THERMAL_WEIGHT_DEFAULT); + if (ret) + return ret; + } else { + thermal_unbind_cdev_from_trip(thermal, trip, cdev); } } -failed: - return result; + return 0; +} + +static int acpi_thermal_bind_unbind_cdev(struct thermal_zone_device *thermal, + struct thermal_cooling_device *cdev, + bool bind) +{ + struct acpi_thermal_bind_data bd = { + .thermal = thermal, .cdev = cdev, .bind = bind + }; + + return for_each_thermal_trip(thermal, bind_unbind_cdev_cb, &bd); } static int acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) { - return acpi_thermal_cooling_device_cb(thermal, cdev, true); + return acpi_thermal_bind_unbind_cdev(thermal, cdev, true); } static int acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) { - return acpi_thermal_cooling_device_cb(thermal, cdev, false); + return acpi_thermal_bind_unbind_cdev(thermal, cdev, false); } static struct thermal_zone_device_ops acpi_thermal_zone_ops = { -- Gitee From 122b83e181de57a922cb6ca29689b25dc957d40b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 20:04:49 +0200 Subject: [PATCH 04/25] ACPI: thermal: Drop critical_valid and hot_valid trip flags ANBZ: #32620 commit c8f46f43a1db7a9a46cd9313aa434380238e874f upstream. The critical_valid and hot_valid flags in struct acpi_thermal_trips are only used during initialization and they are only false if the corresponding trip temperatures are equal to THERMAL_TEMP_INVALID, so drop them and use THERMAL_TEMP_INVALID checks instead of them where applicable. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/acpi/thermal.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 860b0fc2846b..7bbe889d7674 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -100,8 +100,6 @@ struct acpi_thermal_active { struct acpi_thermal_trips { struct acpi_thermal_passive passive; struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; - bool critical_valid; - bool hot_valid; }; struct acpi_thermal { @@ -355,13 +353,13 @@ static long acpi_thermal_get_critical_trip(struct acpi_thermal *tz) } if (crt == -1) { acpi_handle_debug(tz->device->handle, "Critical threshold disabled\n"); - goto fail; + return THERMAL_TEMP_INVALID; } status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, &tmp); if (ACPI_FAILURE(status)) { acpi_handle_debug(tz->device->handle, "No critical threshold\n"); - goto fail; + return THERMAL_TEMP_INVALID; } if (tmp <= 2732) { /* @@ -369,17 +367,12 @@ static long acpi_thermal_get_critical_trip(struct acpi_thermal *tz) * so discard them as invalid. */ pr_info(FW_BUG "Invalid critical threshold (%llu)\n", tmp); - goto fail; + return THERMAL_TEMP_INVALID; } set: - tz->trips.critical_valid = true; acpi_handle_debug(tz->device->handle, "Critical threshold [%llu]\n", tmp); return tmp; - -fail: - tz->trips.critical_valid = false; - return THERMAL_TEMP_INVALID; } static long acpi_thermal_get_hot_trip(struct acpi_thermal *tz) @@ -389,12 +382,10 @@ static long acpi_thermal_get_hot_trip(struct acpi_thermal *tz) status = acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, &tmp); if (ACPI_FAILURE(status)) { - tz->trips.hot_valid = false; acpi_handle_debug(tz->device->handle, "No hot threshold\n"); return THERMAL_TEMP_INVALID; } - tz->trips.hot_valid = true; acpi_handle_debug(tz->device->handle, "Hot threshold [%llu]\n", tmp); return tmp; } @@ -798,7 +789,7 @@ static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) */ static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp) { - if (tz->trips.critical_valid && crit_temp % 5 == 1) + if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1) tz->kelvin_offset = 273100; else tz->kelvin_offset = 273200; @@ -859,11 +850,11 @@ static int acpi_thermal_add(struct acpi_device *device) trip_count = acpi_thermal_get_trip_points(tz); crit_temp = acpi_thermal_get_critical_trip(tz); - if (tz->trips.critical_valid) + if (crit_temp != THERMAL_TEMP_INVALID) trip_count++; hot_temp = acpi_thermal_get_hot_trip(tz); - if (tz->trips.hot_valid) + if (hot_temp != THERMAL_TEMP_INVALID) trip_count++; if (!trip_count) { @@ -897,13 +888,13 @@ static int acpi_thermal_add(struct acpi_device *device) tz->trip_table = trip; - if (tz->trips.critical_valid) { + if (crit_temp != THERMAL_TEMP_INVALID) { trip->type = THERMAL_TRIP_CRITICAL; trip->temperature = acpi_thermal_temp(tz, crit_temp); trip++; } - if (tz->trips.hot_valid) { + if (hot_temp != THERMAL_TEMP_INVALID) { trip->type = THERMAL_TRIP_HOT; trip->temperature = acpi_thermal_temp(tz, hot_temp); trip++; -- Gitee From a69bda78a00c7ae0bec7ee6e9f551973a07bfe9f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 20:06:58 +0200 Subject: [PATCH 05/25] ACPI: thermal: Rename structure fields holding temperature in deci-Kelvin ANBZ: #32620 commit 03a6d5986c9dea51f05c66a5f2fee6a15e498160 upstream. Rename structure fields holding temperature values in deci-Kelvin so as to avoid temperature units confusion. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/acpi/thermal.c | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 7bbe889d7674..75a2ef3683c3 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -82,7 +82,7 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); static struct workqueue_struct *acpi_thermal_pm_queue; struct acpi_thermal_trip { - unsigned long temperature; + unsigned long temp_dk; struct acpi_handle_list devices; }; @@ -105,8 +105,8 @@ struct acpi_thermal_trips { struct acpi_thermal { struct acpi_device *device; acpi_bus_id name; - unsigned long temperature; - unsigned long last_temperature; + unsigned long temp_dk; + unsigned long last_temp_dk; unsigned long polling_frequency; volatile u8 zombie; struct acpi_thermal_trips trips; @@ -131,16 +131,16 @@ static int acpi_thermal_get_temperature(struct acpi_thermal *tz) if (!tz) return -EINVAL; - tz->last_temperature = tz->temperature; + tz->last_temp_dk = tz->temp_dk; status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp); if (ACPI_FAILURE(status)) return -ENODEV; - tz->temperature = tmp; + tz->temp_dk = tmp; acpi_handle_debug(tz->device->handle, "Temperature is %lu dK\n", - tz->temperature); + tz->temp_dk); return 0; } @@ -175,7 +175,7 @@ static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k) static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip) { - return acpi_trip->temperature != THERMAL_TEMP_INVALID; + return acpi_trip->temp_dk != THERMAL_TEMP_INVALID; } static long get_passive_temp(struct acpi_thermal *tz) @@ -197,7 +197,7 @@ static void acpi_thermal_update_passive_trip(struct acpi_thermal *tz) if (!acpi_thermal_trip_valid(acpi_trip) || psv > 0) return; - acpi_trip->temperature = get_passive_temp(tz); + acpi_trip->temp_dk = get_passive_temp(tz); if (!acpi_thermal_trip_valid(acpi_trip)) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } @@ -244,7 +244,7 @@ static void acpi_thermal_update_trip_devices(struct acpi_thermal *tz, int index) return; } - acpi_trip->temperature = THERMAL_TEMP_INVALID; + acpi_trip->temp_dk = THERMAL_TEMP_INVALID; ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } @@ -278,7 +278,7 @@ static void acpi_thermal_update_active_trip(struct acpi_thermal *tz, int index) if (!acpi_thermal_trip_valid(acpi_trip)) return; - acpi_trip->temperature = get_active_temp(tz, index); + acpi_trip->temp_dk = get_active_temp(tz, index); if (!acpi_thermal_trip_valid(acpi_trip)) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } @@ -292,7 +292,7 @@ static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) return 0; if (acpi_thermal_trip_valid(acpi_trip)) - trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); + trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); else trip->temperature = THERMAL_TEMP_INVALID; @@ -453,11 +453,11 @@ static bool acpi_thermal_init_trip(struct acpi_thermal *tz, int index) if (!update_trip_devices(tz, acpi_trip, index, false)) goto fail; - acpi_trip->temperature = temp; + acpi_trip->temp_dk = temp; return true; fail: - acpi_trip->temperature = THERMAL_TEMP_INVALID; + acpi_trip->temp_dk = THERMAL_TEMP_INVALID; return false; } @@ -478,7 +478,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) } while (++i < ACPI_THERMAL_MAX_ACTIVE) - tz->trips.active[i].trip.temperature = THERMAL_TEMP_INVALID; + tz->trips.active[i].trip.temp_dk = THERMAL_TEMP_INVALID; return count; } @@ -497,7 +497,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) if (result) return result; - *temp = deci_kelvin_to_millicelsius_with_offset(tz->temperature, + *temp = deci_kelvin_to_millicelsius_with_offset(tz->temp_dk, tz->kelvin_offset); return 0; } @@ -519,10 +519,10 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, switch (trip->type) { case THERMAL_TRIP_PASSIVE: - t = tz->trips.passive.tc1 * (tz->temperature - - tz->last_temperature) + - tz->trips.passive.tc2 * (tz->temperature - - acpi_trip->temperature); + t = tz->trips.passive.tc1 * (tz->temp_dk - + tz->last_temp_dk) + + tz->trips.passive.tc2 * (tz->temp_dk - + acpi_trip->temp_dk); if (t > 0) *trend = THERMAL_TREND_RAISING; else if (t < 0) @@ -533,7 +533,7 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, return 0; case THERMAL_TRIP_ACTIVE: - t = acpi_thermal_temp(tz, tz->temperature); + t = acpi_thermal_temp(tz, tz->temp_dk); if (t <= trip->temperature) break; @@ -905,7 +905,7 @@ static int acpi_thermal_add(struct acpi_device *device) passive_delay = tz->trips.passive.delay; trip->type = THERMAL_TRIP_PASSIVE; - trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); + trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); trip->priv = acpi_trip; trip++; } @@ -917,7 +917,7 @@ static int acpi_thermal_add(struct acpi_device *device) break; trip->type = THERMAL_TRIP_ACTIVE; - trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); + trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); trip->priv = acpi_trip; trip++; } @@ -931,7 +931,7 @@ static int acpi_thermal_add(struct acpi_device *device) INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); pr_info("%s [%s] (%ld C)\n", acpi_device_name(device), - acpi_device_bid(device), deci_kelvin_to_celsius(tz->temperature)); + acpi_device_bid(device), deci_kelvin_to_celsius(tz->temp_dk)); result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, acpi_thermal_notify); -- Gitee From ba940a24534c6cb5ed2ed3cedb2a3eb223fe5abc Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 27 Sep 2023 13:17:25 -0700 Subject: [PATCH 06/25] ACPI: utils: Dynamically determine acpi_handle_list size ANBZ: #32620 commit 2e57d10a6591560724b80a628235559571f4cb8d upstream. Address a long-standing "TBD" comment in the ACPI headers regarding the number of handles in struct acpi_handle_list. The number 10, which along with the comment dates back to 2.4.23, seems like it may have been arbitrarily chosen and isn't sufficient in all cases [1]. Finally change the code to dynamically determine the size of the handles table in struct acpi_handle_list and allocate it accordingly. Update the users of to struct acpi_handle_list to take the additional dynamic allocation into account. Link: https://lore.kernel.org/linux-acpi/20230809094451.15473-1-ivan.hu@canonical.com # [1] Co-developed-by: Vicki Pfau Signed-off-by: Vicki Pfau Signed-off-by: Rafael J. Wysocki [Ruidong: conflict with merged upstream patch] Signed-off-by: Ruidong Tian --- drivers/acpi/acpi_lpss.c | 10 ++- drivers/acpi/thermal.c | 28 ++++++--- drivers/acpi/utils.c | 61 ++++++++++++++++++- .../platform/surface/surface_acpi_notify.c | 10 ++- include/acpi/acpi_bus.h | 9 ++- 5 files changed, 100 insertions(+), 18 deletions(-) diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 98a2ab3b6844..7c3d1aae31ea 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -580,6 +580,7 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle) { struct acpi_handle_list dep_devices; acpi_status status; + bool ret = false; int i; if (!acpi_has_method(adev->handle, "_DEP")) @@ -593,11 +594,14 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle) } for (i = 0; i < dep_devices.count; i++) { - if (dep_devices.handles[i] == handle) - return true; + if (dep_devices.handles[i] == handle) { + ret = true; + break; + } } - return false; + acpi_handle_list_free(&dep_devices); + return ret; } static void acpi_lpss_link_consumer(struct device *dev1, diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 75a2ef3683c3..73d43049a896 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -206,7 +206,7 @@ static bool update_trip_devices(struct acpi_thermal *tz, struct acpi_thermal_trip *acpi_trip, int index, bool compare) { - struct acpi_handle_list devices; + struct acpi_handle_list devices = { 0 }; char method[] = "_PSL"; acpi_status status; @@ -216,18 +216,21 @@ static bool update_trip_devices(struct acpi_thermal *tz, method[3] = '0' + index; } - memset(&devices, 0, sizeof(devices)); - status = acpi_evaluate_reference(tz->device->handle, method, NULL, &devices); if (ACPI_FAILURE(status)) { acpi_handle_info(tz->device->handle, "%s evaluation failure\n", method); return false; } - if (compare && memcmp(&acpi_trip->devices, &devices, sizeof(devices))) + if (acpi_handle_list_equal(&acpi_trip->devices, &devices)) { + acpi_handle_list_free(&devices); + return true; + } + + if (compare) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); - memcpy(&acpi_trip->devices, &devices, sizeof(devices)); + acpi_handle_list_replace(&acpi_trip->devices, &devices); return true; } @@ -820,6 +823,17 @@ static void acpi_thermal_check_fn(struct work_struct *work) mutex_unlock(&tz->thermal_check_lock); } +static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz) +{ + int i; + + acpi_handle_list_free(&tz->trips.passive.trip.devices); + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) + acpi_handle_list_free(&tz->trips.active[i].trip.devices); + + kfree(tz); +} + static int acpi_thermal_add(struct acpi_device *device) { struct acpi_thermal_trip *acpi_trip; @@ -946,7 +960,7 @@ static int acpi_thermal_add(struct acpi_device *device) free_trips: kfree(tz->trip_table); free_memory: - kfree(tz); + acpi_thermal_free_thermal_zone(tz); return result; } @@ -966,7 +980,7 @@ static void acpi_thermal_remove(struct acpi_device *device) flush_workqueue(acpi_thermal_pm_queue); acpi_thermal_unregister_thermal_zone(tz); kfree(tz->trip_table); - kfree(tz); + acpi_thermal_free_thermal_zone(tz); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index bf09c72e5bd6..b021a9aacabb 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -370,7 +370,8 @@ acpi_evaluate_reference(acpi_handle handle, goto end; } - if (package->package.count > ACPI_MAX_HANDLES) { + list->handles = kcalloc(package->package.count, sizeof(*list->handles), GFP_KERNEL); + if (!list->handles) { kfree(package); return AE_NO_MEMORY; } @@ -402,7 +403,8 @@ acpi_evaluate_reference(acpi_handle handle, end: if (ACPI_FAILURE(status)) { list->count = 0; - //kfree(list->handles); + kfree(list->handles); + list->handles = NULL; } kfree(buffer.pointer); @@ -412,6 +414,61 @@ acpi_evaluate_reference(acpi_handle handle, EXPORT_SYMBOL(acpi_evaluate_reference); +/** + * acpi_handle_list_equal - Check if two ACPI handle lists are the same + * @list1: First list to compare. + * @list2: Second list to compare. + * + * Return true if the given ACPI handle lists are of the same size and + * contain the same ACPI handles in the same order. Otherwise, return false. + */ +bool acpi_handle_list_equal(struct acpi_handle_list *list1, + struct acpi_handle_list *list2) +{ + return list1->count == list2->count && + !memcmp(list1->handles, list2->handles, + list1->count * sizeof(acpi_handle)); +} +EXPORT_SYMBOL_GPL(acpi_handle_list_equal); + +/** + * acpi_handle_list_replace - Replace one ACPI handle list with another + * @dst: ACPI handle list to replace. + * @src: Source ACPI handle list. + * + * Free the handles table in @dst, move the handles table from @src to @dst, + * copy count from @src to @dst and clear @src. + */ +void acpi_handle_list_replace(struct acpi_handle_list *dst, + struct acpi_handle_list *src) +{ + if (dst->count) + kfree(dst->handles); + + dst->count = src->count; + dst->handles = src->handles; + + src->handles = NULL; + src->count = 0; +} +EXPORT_SYMBOL_GPL(acpi_handle_list_replace); + +/** + * acpi_handle_list_free - Free the handles table in an ACPI handle list + * @list: ACPI handle list to free. + * + * Free the handles table in @list and clear its count field. + */ +void acpi_handle_list_free(struct acpi_handle_list *list) +{ + if (!list->count) + return; + + kfree(list->handles); + list->count = 0; +} +EXPORT_SYMBOL_GPL(acpi_handle_list_free); + acpi_status acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld) { diff --git a/drivers/platform/surface/surface_acpi_notify.c b/drivers/platform/surface/surface_acpi_notify.c index 897cdd9c3aae..0412a644fece 100644 --- a/drivers/platform/surface/surface_acpi_notify.c +++ b/drivers/platform/surface/surface_acpi_notify.c @@ -741,6 +741,7 @@ static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle) struct acpi_handle_list dep_devices; acpi_handle supplier = ACPI_HANDLE(&pdev->dev); acpi_status status; + bool ret = false; int i; if (!acpi_has_method(handle, "_DEP")) @@ -753,11 +754,14 @@ static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle) } for (i = 0; i < dep_devices.count; i++) { - if (dep_devices.handles[i] == supplier) - return true; + if (dep_devices.handles[i] == supplier) { + ret = true; + break; + } } - return false; + acpi_handle_list_free(&dep_devices); + return ret; } static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl, diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 9cb733b2329e..146c17ddbbe1 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -17,11 +17,9 @@ #include #include -/* TBD: Make dynamic */ -#define ACPI_MAX_HANDLES 10 struct acpi_handle_list { u32 count; - acpi_handle handles[ACPI_MAX_HANDLES]; + acpi_handle* handles; }; /* acpi_utils.h */ @@ -37,6 +35,11 @@ acpi_evaluate_reference(acpi_handle handle, acpi_string pathname, struct acpi_object_list *arguments, struct acpi_handle_list *list); +bool acpi_handle_list_equal(struct acpi_handle_list *list1, + struct acpi_handle_list *list2); +void acpi_handle_list_replace(struct acpi_handle_list *dst, + struct acpi_handle_list *src); +void acpi_handle_list_free(struct acpi_handle_list *list); acpi_status acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, struct acpi_buffer *status_buf); -- Gitee From 766cd7fbe671baa34c282f36dcda246803ab6c85 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 28 Sep 2023 20:47:31 +0200 Subject: [PATCH 07/25] ACPI: thermal: Drop list of device ACPI handles from struct acpi_thermal ANBZ: #32620 commit c6767334185e50121b66eae9f882d2832d2d2ad1 upstream. Notice that the list of device ACPI handles in struct acpi_thermal is not used and drop it. No functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/acpi/thermal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 73d43049a896..2f6f03c79ef5 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -111,7 +111,6 @@ struct acpi_thermal { volatile u8 zombie; struct acpi_thermal_trips trips; struct thermal_trip *trip_table; - struct acpi_handle_list devices; struct thermal_zone_device *thermal_zone; int kelvin_offset; /* in millidegrees */ struct work_struct thermal_check_work; -- Gitee From f4f2a96036c35af097cd4c781d12cf8b58410a4a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:18:31 +0200 Subject: [PATCH 08/25] ACPI: thermal: Move get_active_temp() ANBZ: #32620 commit 44babd829a7e0c13b57040fc8234f64fabab1efd upstream. Put the get_active_temp() function next to the analogous get_passive_temp() one to allow subsequent changes to be easier to follow. No functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/acpi/thermal.c | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 2f6f03c79ef5..3cab05634915 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -189,6 +189,29 @@ static long get_passive_temp(struct acpi_thermal *tz) return tmp; } +static long get_active_temp(struct acpi_thermal *tz, int index) +{ + char method[] = { '_', 'A', 'C', '0' + index, '\0' }; + unsigned long long tmp; + acpi_status status; + + status = acpi_evaluate_integer(tz->device->handle, method, NULL, &tmp); + if (ACPI_FAILURE(status)) + return THERMAL_TEMP_INVALID; + + /* + * If an override has been provided, apply it so there are no active + * trips with thresholds greater than the override. + */ + if (act > 0) { + unsigned long long override = celsius_to_deci_kelvin(act); + + if (tmp > override) + tmp = override; + } + return tmp; +} + static void acpi_thermal_update_passive_trip(struct acpi_thermal *tz) { struct acpi_thermal_trip *acpi_trip = &tz->trips.passive.trip; @@ -250,29 +273,6 @@ static void acpi_thermal_update_trip_devices(struct acpi_thermal *tz, int index) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } -static long get_active_temp(struct acpi_thermal *tz, int index) -{ - char method[] = { '_', 'A', 'C', '0' + index, '\0' }; - unsigned long long tmp; - acpi_status status; - - status = acpi_evaluate_integer(tz->device->handle, method, NULL, &tmp); - if (ACPI_FAILURE(status)) - return THERMAL_TEMP_INVALID; - - /* - * If an override has been provided, apply it so there are no active - * trips with thresholds greater than the override. - */ - if (act > 0) { - unsigned long long override = celsius_to_deci_kelvin(act); - - if (tmp > override) - tmp = override; - } - return tmp; -} - static void acpi_thermal_update_active_trip(struct acpi_thermal *tz, int index) { struct acpi_thermal_trip *acpi_trip = &tz->trips.active[index].trip; -- Gitee From 54567be5de4b829b2f779648ff312e46f6dc9ddd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:21:30 +0200 Subject: [PATCH 09/25] ACPI: thermal: Combine passive and active trip update functions ANBZ: #32620 commit 4f9cf91e4102fe77ef3393febab72612b594172f upstream. Combine acpi_thermal_update_passive_trip() and acpi_thermal_update_active_trip() into one common function called acpi_thermal_update_trip(), so as to reduce code duplication and prepare the code in question for subsequent changes. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/acpi/thermal.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 3cab05634915..95d7568d4d39 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -212,14 +212,25 @@ static long get_active_temp(struct acpi_thermal *tz, int index) return tmp; } -static void acpi_thermal_update_passive_trip(struct acpi_thermal *tz) +static void acpi_thermal_update_trip(struct acpi_thermal *tz, + int index) { - struct acpi_thermal_trip *acpi_trip = &tz->trips.passive.trip; + struct acpi_thermal_trip *acpi_trip; - if (!acpi_thermal_trip_valid(acpi_trip) || psv > 0) + acpi_trip = index == ACPI_THERMAL_TRIP_PASSIVE ? + &tz->trips.passive.trip : &tz->trips.active[index].trip; + if (!acpi_thermal_trip_valid(acpi_trip)) return; - acpi_trip->temp_dk = get_passive_temp(tz); + if (index == ACPI_THERMAL_TRIP_PASSIVE) { + if (psv > 0) + return; + + acpi_trip->temp_dk = get_passive_temp(tz); + } else { + acpi_trip->temp_dk = get_active_temp(tz, index); + } + if (!acpi_thermal_trip_valid(acpi_trip)) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } @@ -273,18 +284,6 @@ static void acpi_thermal_update_trip_devices(struct acpi_thermal *tz, int index) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } -static void acpi_thermal_update_active_trip(struct acpi_thermal *tz, int index) -{ - struct acpi_thermal_trip *acpi_trip = &tz->trips.active[index].trip; - - if (!acpi_thermal_trip_valid(acpi_trip)) - return; - - acpi_trip->temp_dk = get_active_temp(tz, index); - if (!acpi_thermal_trip_valid(acpi_trip)) - ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); -} - static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) { struct acpi_thermal_trip *acpi_trip = trip->priv; @@ -308,9 +307,9 @@ static void acpi_thermal_adjust_thermal_zone(struct thermal_zone_device *thermal int i; if (data == ACPI_THERMAL_NOTIFY_THRESHOLDS) { - acpi_thermal_update_passive_trip(tz); + acpi_thermal_update_trip(tz, ACPI_THERMAL_TRIP_PASSIVE); for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) - acpi_thermal_update_active_trip(tz, i); + acpi_thermal_update_trip(tz, i); } else { acpi_thermal_update_trip_devices(tz, ACPI_THERMAL_TRIP_PASSIVE); for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) -- Gitee From e1607549deab2de92f9f9ce8e203e1b2822027af Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:24:12 +0200 Subject: [PATCH 10/25] ACPI: thermal: Use thermal_zone_for_each_trip() for updating trips ANBZ: #32620 commit b251ab28caeb5a4a63d832dcd53d29ad2dd5318f upstream. Rearrange the code handling notifications from the platform firmware regarding trip point updates to carry out one loop over trip points instead of two of them by using thermal_zone_for_each_trip() for that, which is more straightforward than using a combination of thermal_zone_device_exec() and for_each_thermal_trip(), each with its own callback function. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/acpi/thermal.c | 78 ++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 95d7568d4d39..0770034d8cfe 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -177,6 +177,15 @@ static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip) return acpi_trip->temp_dk != THERMAL_TEMP_INVALID; } +static int active_trip_index(struct acpi_thermal *tz, + struct acpi_thermal_trip *acpi_trip) +{ + struct acpi_thermal_active *active; + + active = container_of(acpi_trip, struct acpi_thermal_active, trip); + return active - tz->trips.active; +} + static long get_passive_temp(struct acpi_thermal *tz) { unsigned long long tmp; @@ -213,21 +222,18 @@ static long get_active_temp(struct acpi_thermal *tz, int index) } static void acpi_thermal_update_trip(struct acpi_thermal *tz, - int index) + const struct thermal_trip *trip) { - struct acpi_thermal_trip *acpi_trip; - - acpi_trip = index == ACPI_THERMAL_TRIP_PASSIVE ? - &tz->trips.passive.trip : &tz->trips.active[index].trip; - if (!acpi_thermal_trip_valid(acpi_trip)) - return; + struct acpi_thermal_trip *acpi_trip = trip->priv; - if (index == ACPI_THERMAL_TRIP_PASSIVE) { + if (trip->type == THERMAL_TRIP_PASSIVE) { if (psv > 0) return; acpi_trip->temp_dk = get_passive_temp(tz); } else { + int index = active_trip_index(tz, acpi_trip); + acpi_trip->temp_dk = get_active_temp(tz, index); } @@ -267,31 +273,39 @@ static bool update_trip_devices(struct acpi_thermal *tz, return true; } -static void acpi_thermal_update_trip_devices(struct acpi_thermal *tz, int index) +static void acpi_thermal_update_trip_devices(struct acpi_thermal *tz, + const struct thermal_trip *trip) { - struct acpi_thermal_trip *acpi_trip; - - acpi_trip = index == ACPI_THERMAL_TRIP_PASSIVE ? - &tz->trips.passive.trip : &tz->trips.active[index].trip; - if (!acpi_thermal_trip_valid(acpi_trip)) - return; + struct acpi_thermal_trip *acpi_trip = trip->priv; + int index = trip->type == THERMAL_TRIP_PASSIVE ? + ACPI_THERMAL_TRIP_PASSIVE : active_trip_index(tz, acpi_trip); - if (update_trip_devices(tz, acpi_trip, index, true)) { + if (update_trip_devices(tz, acpi_trip, index, true)) return; - } acpi_trip->temp_dk = THERMAL_TEMP_INVALID; ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } +struct adjust_trip_data { + struct acpi_thermal *tz; + u32 event; +}; + static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) { struct acpi_thermal_trip *acpi_trip = trip->priv; - struct acpi_thermal *tz = data; + struct adjust_trip_data *atd = data; + struct acpi_thermal *tz = atd->tz; - if (!acpi_trip) + if (!acpi_trip || !acpi_thermal_trip_valid(acpi_trip)) return 0; + if (atd->event == ACPI_THERMAL_NOTIFY_THRESHOLDS) + acpi_thermal_update_trip(tz, trip); + else + acpi_thermal_update_trip_devices(tz, trip); + if (acpi_thermal_trip_valid(acpi_trip)) trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); else @@ -300,25 +314,6 @@ static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) return 0; } -static void acpi_thermal_adjust_thermal_zone(struct thermal_zone_device *thermal, - unsigned long data) -{ - struct acpi_thermal *tz = thermal_zone_device_priv(thermal); - int i; - - if (data == ACPI_THERMAL_NOTIFY_THRESHOLDS) { - acpi_thermal_update_trip(tz, ACPI_THERMAL_TRIP_PASSIVE); - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) - acpi_thermal_update_trip(tz, i); - } else { - acpi_thermal_update_trip_devices(tz, ACPI_THERMAL_TRIP_PASSIVE); - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) - acpi_thermal_update_trip_devices(tz, i); - } - - for_each_thermal_trip(tz->thermal_zone, acpi_thermal_adjust_trip, tz); -} - static void acpi_queue_thermal_check(struct acpi_thermal *tz) { if (!work_pending(&tz->thermal_check_work)) @@ -327,17 +322,18 @@ static void acpi_queue_thermal_check(struct acpi_thermal *tz) static void acpi_thermal_trips_update(struct acpi_thermal *tz, u32 event) { + struct adjust_trip_data atd = { .tz = tz, .event = event }; struct acpi_device *adev = tz->device; /* - * Use thermal_zone_device_exec() to carry out the trip points + * Use thermal_zone_for_each_trip() to carry out the trip points * update, so as to protect thermal_get_trend() from getting stale * trip point temperatures and to prevent thermal_zone_device_update() * invoked from acpi_thermal_check_fn() from producing inconsistent * results. */ - thermal_zone_device_exec(tz->thermal_zone, - acpi_thermal_adjust_thermal_zone, event); + thermal_zone_for_each_trip(tz->thermal_zone, + acpi_thermal_adjust_trip, &atd); acpi_queue_thermal_check(tz); acpi_bus_generate_netlink_event(adev->pnp.device_class, dev_name(&adev->dev), event, 0); -- Gitee From a218143fcd15c08339f2dec183f9eb10c8d68ab2 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 7 Oct 2023 13:29:22 +0200 Subject: [PATCH 11/25] thermal: trip: Remove lockdep assertion from for_each_thermal_trip() ANBZ: #32620 commit b44444027ce7714f309e96b804b7fb088a40d708 upstream. The lockdep assertion in for_each_thermal_trip() was added to possibly catch incorrect usage of that function without the thermal zone lock. However, it turns out that the ACPI thermal driver has a legitimate reason to call for_each_thermal_trip() without locking. Namely, it is called by acpi_thermal_bind_unbind_cdev() in the thermal zone registration and unregistration paths. That function cannot acquire the thermal zone lock by itself, because it calls functions that acquire it, thermal_bind_cdev_to_trip() or thermal_unbind_cdev_from_trip(). However, it is invoked when the ACPI notify handler for the thermal zone in question has not been registered yet (in the registration path) or after that handler has been unregistered (in the unregistration path). Therefore, when for_each_thermal_trip() is called by acpi_thermal_bind_unbind_cdev(), thermal trip changes induced by the platform firmware cannot take place and so the thermal zone's trips[] table is effectively immutable. Hence, it is valid to call for_each_thermal_trip() from acpi_thermal_bind_unbind_cdev() without locking and the lockdep assertion in the former is in fact incorrect, so remove it. Fixes: d5ea889246b1 ("ACPI: thermal: Do not use trip indices for cooling device binding") Signed-off-by: Rafael J. Wysocki Signed-off-by: Ruidong Tian --- drivers/thermal/thermal_trip.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index afc9499128c2..5c7455ab5900 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -15,8 +15,6 @@ int for_each_thermal_trip(struct thermal_zone_device *tz, { int i, ret; - lockdep_assert_held(&tz->lock); - for (i = 0; i < tz->num_trips; i++) { ret = cb(&tz->trips[i], data); if (ret) -- Gitee From 73e3a41192b961e493fe03a7553d1d750a231ca8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:17:24 +0200 Subject: [PATCH 12/25] thermal: core: Add function to walk trips under zone lock ANBZ: #32620 commit a56cc0a8338523f709892696cc229527617c1316 upstream. Add a wrapper around for_each_thermal_trip(), called thermal_zone_for_each_trip(), that will invoke the former under the thermal zone lock and pass its return value to the caller. Two drivers will be modified subsequently to use this new function. No functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/thermal/thermal_trip.c | 14 ++++++++++++++ include/linux/thermal.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 5c7455ab5900..94b74f1fd400 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -25,6 +25,20 @@ int for_each_thermal_trip(struct thermal_zone_device *tz, } EXPORT_SYMBOL_GPL(for_each_thermal_trip); +int thermal_zone_for_each_trip(struct thermal_zone_device *tz, + int (*cb)(struct thermal_trip *, void *), + void *data) +{ + int ret; + + mutex_lock(&tz->lock); + ret = for_each_thermal_trip(tz, cb, data); + mutex_unlock(&tz->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(thermal_zone_for_each_trip); + int thermal_zone_get_num_trips(struct thermal_zone_device *tz) { return tz->num_trips; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 77e6b0fc4481..c495f60cf2f3 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -290,6 +290,9 @@ int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id, int for_each_thermal_trip(struct thermal_zone_device *tz, int (*cb)(struct thermal_trip *, void *), void *data); +int thermal_zone_for_each_trip(struct thermal_zone_device *tz, + int (*cb)(struct thermal_trip *, void *), + void *data); int thermal_zone_get_num_trips(struct thermal_zone_device *tz); int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp); -- Gitee From e8313668ada48814ca47d9c51393e5d5f0099122 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:25:33 +0200 Subject: [PATCH 13/25] thermal: core: Drop thermal_zone_device_exec() ANBZ: #32620 commit 4963e34ce7b95237021575d208fa576f88697839 upstream. Because thermal_zone_device_exec() has no users any more and there are no plans to use it anywhere, revert commit 9a99a996d1ec ("thermal: core: Introduce thermal_zone_device_exec()") that introduced it. No functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/thermal/thermal_core.c | 19 ------------------- include/linux/thermal.h | 4 ---- 2 files changed, 23 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 3ef4a7c36cd1..ab43438dea35 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -498,25 +498,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz, } EXPORT_SYMBOL_GPL(thermal_zone_device_update); -/** - * thermal_zone_device_exec - Run a callback under the zone lock. - * @tz: Thermal zone. - * @cb: Callback to run. - * @data: Data to pass to the callback. - */ -void thermal_zone_device_exec(struct thermal_zone_device *tz, - void (*cb)(struct thermal_zone_device *, - unsigned long), - unsigned long data) -{ - mutex_lock(&tz->lock); - - cb(tz, data); - - mutex_unlock(&tz->lock); -} -EXPORT_SYMBOL_GPL(thermal_zone_device_exec); - static void thermal_zone_device_check(struct work_struct *work) { struct thermal_zone_device *tz = container_of(work, struct diff --git a/include/linux/thermal.h b/include/linux/thermal.h index c495f60cf2f3..fc9a9101e1b0 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -343,10 +343,6 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, struct thermal_cooling_device *); void thermal_zone_device_update(struct thermal_zone_device *, enum thermal_notify_event); -void thermal_zone_device_exec(struct thermal_zone_device *tz, - void (*cb)(struct thermal_zone_device *, - unsigned long), - unsigned long data); struct thermal_cooling_device *thermal_cooling_device_register(const char *, void *, const struct thermal_cooling_device_ops *); -- Gitee From 2f9abaa05551ed4683dad0ce53a5772ec81ec3e7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:26:35 +0200 Subject: [PATCH 14/25] thermal: int340x: Use thermal_zone_for_each_trip() ANBZ: #32620 commit cd3c00e7760905270541981f4c5d1e31f38c2e47 upstream. Modify int340x_thermal_update_trips() to use thermal_zone_for_each_trip() for walking trips instead of using the trips[] table passed to the thermal zone registration function. For this purpose, store active trip point indices in the priv fieids of the corresponding thermal_trip structures. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- .../int340x_thermal/int340x_thermal_zone.c | 78 ++++++++++--------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c index 89cf007146ea..a03b67579dd9 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c @@ -67,6 +67,16 @@ static struct thermal_zone_device_ops int340x_thermal_zone_ops = { .critical = int340x_thermal_critical, }; +static inline void *int_to_trip_priv(int i) +{ + return (void *)(long)i; +} + +static inline int trip_priv_to_int(const struct thermal_trip *trip) +{ + return (long)trip->priv; +} + static int int340x_thermal_read_trips(struct acpi_device *zone_adev, struct thermal_trip *zone_trips, int trip_cnt) @@ -101,6 +111,7 @@ static int int340x_thermal_read_trips(struct acpi_device *zone_adev, break; zone_trips[trip_cnt].type = THERMAL_TRIP_ACTIVE; + zone_trips[trip_cnt].priv = int_to_trip_priv(i); trip_cnt++; } @@ -212,45 +223,40 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone *int34x_zone) } EXPORT_SYMBOL_GPL(int340x_thermal_zone_remove); -void int340x_thermal_update_trips(struct int34x_thermal_zone *int34x_zone) +static int int340x_update_one_trip(struct thermal_trip *trip, void *arg) { - struct acpi_device *zone_adev = int34x_zone->adev; - struct thermal_trip *zone_trips = int34x_zone->trips; - int trip_cnt = int34x_zone->zone->num_trips; - int act_trip_nr = 0; - int i; - - mutex_lock(&int34x_zone->zone->lock); - - for (i = int34x_zone->aux_trip_nr; i < trip_cnt; i++) { - int temp, err; - - switch (zone_trips[i].type) { - case THERMAL_TRIP_CRITICAL: - err = thermal_acpi_critical_trip_temp(zone_adev, &temp); - break; - case THERMAL_TRIP_HOT: - err = thermal_acpi_hot_trip_temp(zone_adev, &temp); - break; - case THERMAL_TRIP_PASSIVE: - err = thermal_acpi_passive_trip_temp(zone_adev, &temp); - break; - case THERMAL_TRIP_ACTIVE: - err = thermal_acpi_active_trip_temp(zone_adev, act_trip_nr++, - &temp); - break; - default: - err = -ENODEV; - } - if (err) { - zone_trips[i].temperature = THERMAL_TEMP_INVALID; - continue; - } - - zone_trips[i].temperature = temp; + struct acpi_device *zone_adev = arg; + int temp, err; + + switch (trip->type) { + case THERMAL_TRIP_CRITICAL: + err = thermal_acpi_critical_trip_temp(zone_adev, &temp); + break; + case THERMAL_TRIP_HOT: + err = thermal_acpi_hot_trip_temp(zone_adev, &temp); + break; + case THERMAL_TRIP_PASSIVE: + err = thermal_acpi_passive_trip_temp(zone_adev, &temp); + break; + case THERMAL_TRIP_ACTIVE: + err = thermal_acpi_active_trip_temp(zone_adev, + trip_priv_to_int(trip), + &temp); + break; + default: + err = -ENODEV; } + if (err) + temp = THERMAL_TEMP_INVALID; - mutex_unlock(&int34x_zone->zone->lock); + trip->temperature = temp; + return 0; +} + +void int340x_thermal_update_trips(struct int34x_thermal_zone *int34x_zone) +{ + thermal_zone_for_each_trip(int34x_zone->zone, int340x_update_one_trip, + int34x_zone->adev); } EXPORT_SYMBOL_GPL(int340x_thermal_update_trips); -- Gitee From f888365c9d2f342162b7aaeff87ff6051be98690 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 Oct 2023 20:25:06 +0200 Subject: [PATCH 15/25] thermal: trip: Simplify computing trip indices ANBZ: #32620 commit 78869767f2ad3a98d2c830b718a503d8b0a94b26 upstream. A trip index can be computed right away as a difference between the value of a trip pointer pointing to the given trip object and the start of the trips[] table in the given thermal zone, so change thermal_zone_trip_id() accordingly. No intentional functional impact (except for some speedup). Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Reviewed-by: Lukasz Luba Tested-by: Lukasz Luba Signed-off-by: Ruidong Tian --- drivers/thermal/thermal_trip.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 94b74f1fd400..753d47332eda 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -188,12 +188,9 @@ int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id, int thermal_zone_trip_id(struct thermal_zone_device *tz, const struct thermal_trip *trip) { - int i; - - for (i = 0; i < tz->num_trips; i++) { - if (&tz->trips[i] == trip) - return i; - } - - return -ENODATA; + /* + * Assume the trip to be located within the bounds of the thermal + * zone's trips[] table. + */ + return trip - tz->trips; } -- Gitee From 87c99cf01f0a68c6ca064ffa1b2b4738e050c0f7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 Oct 2023 20:26:46 +0200 Subject: [PATCH 16/25] thermal: trip: Define for_each_trip() macro ANBZ: #32620 commit 234ed6f5fbedf7bc84f9adc08c3e11ca8588ffd8 upstream. Define a new macro for_each_trip() to be used by the thermal core code and thermal governors for walking trips in a given thermal zone. Modify for_each_thermal_trip() to use this macro instead of an open- coded loop over trips. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Reviewed-by: Lukasz Luba Signed-off-by: Ruidong Tian --- drivers/thermal/thermal_core.h | 3 +++ drivers/thermal/thermal_trip.c | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 024e82ebf592..4702d3a152f9 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -116,6 +116,9 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, enum thermal_notify_event event); /* Helpers */ +#define for_each_trip(__tz, __trip) \ + for (__trip = __tz->trips; __trip - __tz->trips < __tz->num_trips; __trip++) + void __thermal_zone_set_trips(struct thermal_zone_device *tz); int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, struct thermal_trip *trip); diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 753d47332eda..e42456442c68 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -13,10 +13,11 @@ int for_each_thermal_trip(struct thermal_zone_device *tz, int (*cb)(struct thermal_trip *, void *), void *data) { - int i, ret; + struct thermal_trip *trip; + int ret; - for (i = 0; i < tz->num_trips; i++) { - ret = cb(&tz->trips[i], data); + for_each_trip(tz, trip) { + ret = cb(trip, data); if (ret) return ret; } -- Gitee From 2663073423c4cbd91978d90ff87edfa1013db52b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 Oct 2023 20:29:43 +0200 Subject: [PATCH 17/25] thermal: gov_fair_share: Rearrange get_trip_level() ANBZ: #32620 commit 276f1ede95164b54f55c82d40e9df218109704d6 upstream. Make get_trip_level() use for_each_trip() to iterate over trip points and make it call thermal_zone_trip_id() to obtain the integer ID of a given trip point so as to avoid relying on the knowledge of struct thermal_zone_device internals. The general functionality is not expected to be changed. This change causes the governor to use trip pointers instead of trip indices everywhere except for the fair_share_throttle() second argument that will be modified subsequently along with the definition of the governor .throttle() callback. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/thermal/gov_fair_share.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c index 2abeb8979f50..41effa87d3cd 100644 --- a/drivers/thermal/gov_fair_share.c +++ b/drivers/thermal/gov_fair_share.c @@ -15,29 +15,27 @@ #include "thermal_core.h" -/** - * get_trip_level: - obtains the current trip level for a zone - * @tz: thermal zone device - */ static int get_trip_level(struct thermal_zone_device *tz) { - struct thermal_trip trip; - int count; + const struct thermal_trip *trip, *level_trip = NULL; + int trip_level; - for (count = 0; count < tz->num_trips; count++) { - __thermal_zone_get_trip(tz, count, &trip); - if (tz->temperature < trip.temperature) + for_each_trip(tz, trip) { + if (trip->temperature >= tz->temperature) break; + + level_trip = trip; } - /* - * count > 0 only if temperature is greater than first trip - * point, in which case, trip_point = count - 1 - */ - if (count > 0) - trace_thermal_zone_trip(tz, count - 1, trip.type); + /* Bail out if the temperature is not greater than any trips. */ + if (!level_trip) + return 0; + + trip_level = thermal_zone_trip_id(tz, level_trip); + + trace_thermal_zone_trip(tz, trip_level, level_trip->type); - return count; + return trip_level; } static long get_target_state(struct thermal_zone_device *tz, -- Gitee From 990f3dec3a63fa286ade009d287adc319338fab0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 Oct 2023 20:31:38 +0200 Subject: [PATCH 18/25] thermal: gov_power_allocator: Use trip pointers instead of trip indices ANBZ: #32620 commit 94be1d27aa8d6f0a9e09517445abf468de24fab3 upstream. Modify the power allocator thermal governor to use trip pointers instead of trip indices everywhere except for the power_allocator_throttle() second argument that will be changed subsequently along with the definition of the .throttle() governor callback. The general functionality is not expected to be changed. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Reviewed-by: Lukasz Luba Tested-by: Lukasz Luba [Ruidong: Conflicts: resolve: drivers/thermal/gov_power_allocator.c reason: Merged with updated upstream patch: thermal: gov_power_allocator: avoid inability to reset a cdev ] Signed-off-by: Ruidong Tian --- drivers/thermal/gov_power_allocator.c | 125 ++++++++++---------------- 1 file changed, 48 insertions(+), 77 deletions(-) diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index fc969642f70b..b87c695f7d27 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -16,8 +16,6 @@ #include "thermal_core.h" -#define INVALID_TRIP -1 - #define FRAC_BITS 10 #define int_to_frac(x) ((x) << FRAC_BITS) #define frac_to_int(x) ((x) >> FRAC_BITS) @@ -55,23 +53,23 @@ static inline s64 div_frac(s64 x, s64 y) * @err_integral: accumulated error in the PID controller. * @prev_err: error in the previous iteration of the PID controller. * Used to calculate the derivative term. + * @sustainable_power: Sustainable power (heat) that this thermal zone can + * dissipate * @trip_switch_on: first passive trip point of the thermal zone. The * governor switches on when this trip point is crossed. * If the thermal zone only has one passive trip point, - * @trip_switch_on should be INVALID_TRIP. + * @trip_switch_on should be NULL. * @trip_max_desired_temperature: last passive trip point of the thermal * zone. The temperature we are * controlling for. - * @sustainable_power: Sustainable power (heat) that this thermal zone can - * dissipate */ struct power_allocator_params { bool allocated_tzp; s64 err_integral; s32 prev_err; - int trip_switch_on; - int trip_max_desired_temperature; u32 sustainable_power; + const struct thermal_trip *trip_switch_on; + const struct thermal_trip *trip_max_desired_temperature; }; /** @@ -90,14 +88,12 @@ static u32 estimate_sustainable_power(struct thermal_zone_device *tz) u32 sustainable_power = 0; struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; - const struct thermal_trip *trip_max_desired_temperature = - &tz->trips[params->trip_max_desired_temperature]; list_for_each_entry(instance, &tz->thermal_instances, tz_node) { struct thermal_cooling_device *cdev = instance->cdev; u32 min_power; - if (instance->trip != trip_max_desired_temperature) + if (instance->trip != params->trip_max_desired_temperature) continue; if (!cdev_is_power_actor(cdev)) @@ -116,24 +112,22 @@ static u32 estimate_sustainable_power(struct thermal_zone_device *tz) * estimate_pid_constants() - Estimate the constants for the PID controller * @tz: thermal zone for which to estimate the constants * @sustainable_power: sustainable power for the thermal zone - * @trip_switch_on: trip point number for the switch on temperature + * @trip_switch_on: trip point for the switch on temperature * @control_temp: target temperature for the power allocator governor * * This function is used to update the estimation of the PID * controller constants in struct thermal_zone_parameters. */ static void estimate_pid_constants(struct thermal_zone_device *tz, - u32 sustainable_power, int trip_switch_on, + u32 sustainable_power, + const struct thermal_trip *trip_switch_on, int control_temp) { - struct thermal_trip trip; u32 temperature_threshold = control_temp; - int ret; s32 k_i; - ret = __thermal_zone_get_trip(tz, trip_switch_on, &trip); - if (!ret) - temperature_threshold -= trip.temperature; + if (trip_switch_on) + temperature_threshold -= trip_switch_on->temperature; /* * estimate_pid_constants() tries to find appropriate default @@ -386,7 +380,7 @@ static int allocate_power(struct thermal_zone_device *tz, struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; const struct thermal_trip *trip_max_desired_temperature = - &tz->trips[params->trip_max_desired_temperature]; + params->trip_max_desired_temperature; u32 *req_power, *max_power, *granted_power, *extra_actor_power; u32 *weighted_req_power; u32 total_req_power, max_allocatable_power, total_weighted_req_power; @@ -496,7 +490,7 @@ static int allocate_power(struct thermal_zone_device *tz, } /** - * get_governor_trips() - get the number of the two trip points that are key for this governor + * get_governor_trips() - get the two trip points that are key for this governor * @tz: thermal zone to operate on * @params: pointer to private data for this governor * @@ -513,46 +507,36 @@ static int allocate_power(struct thermal_zone_device *tz, static void get_governor_trips(struct thermal_zone_device *tz, struct power_allocator_params *params) { - int i, last_active, last_passive; - bool found_first_passive; - - found_first_passive = false; - last_active = INVALID_TRIP; - last_passive = INVALID_TRIP; - - for (i = 0; i < tz->num_trips; i++) { - struct thermal_trip trip; - int ret; - - ret = __thermal_zone_get_trip(tz, i, &trip); - if (ret) { - dev_warn(&tz->device, - "Failed to get trip point %d type: %d\n", i, - ret); - continue; - } - - if (trip.type == THERMAL_TRIP_PASSIVE) { - if (!found_first_passive) { - params->trip_switch_on = i; - found_first_passive = true; - } else { - last_passive = i; + const struct thermal_trip *first_passive = NULL; + const struct thermal_trip *last_passive = NULL; + const struct thermal_trip *last_active = NULL; + const struct thermal_trip *trip; + + for_each_trip(tz, trip) { + switch (trip->type) { + case THERMAL_TRIP_PASSIVE: + if (!first_passive) { + first_passive = trip; + break; } - } else if (trip.type == THERMAL_TRIP_ACTIVE) { - last_active = i; - } else { + last_passive = trip; + break; + case THERMAL_TRIP_ACTIVE: + last_active = trip; + break; + default: break; } } - if (last_passive != INVALID_TRIP) { + if (last_passive) { + params->trip_switch_on = first_passive; params->trip_max_desired_temperature = last_passive; - } else if (found_first_passive) { - params->trip_max_desired_temperature = params->trip_switch_on; - params->trip_switch_on = INVALID_TRIP; + } else if (first_passive) { + params->trip_switch_on = NULL; + params->trip_max_desired_temperature = first_passive; } else { - params->trip_switch_on = INVALID_TRIP; + params->trip_switch_on = NULL; params->trip_max_desired_temperature = last_active; } } @@ -567,14 +551,12 @@ static void allow_maximum_power(struct thermal_zone_device *tz, bool update) { struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; - const struct thermal_trip *trip_max_desired_temperature = - &tz->trips[params->trip_max_desired_temperature]; u32 req_power; list_for_each_entry(instance, &tz->thermal_instances, tz_node) { struct thermal_cooling_device *cdev = instance->cdev; - if ((instance->trip != trip_max_desired_temperature) || + if (instance->trip != params->trip_max_desired_temperature || (!cdev_is_power_actor(instance->cdev))) continue; @@ -636,7 +618,6 @@ static int power_allocator_bind(struct thermal_zone_device *tz) { int ret; struct power_allocator_params *params; - struct thermal_trip trip; ret = check_power_actors(tz); if (ret) @@ -661,13 +642,11 @@ static int power_allocator_bind(struct thermal_zone_device *tz) get_governor_trips(tz, params); - if (tz->num_trips > 0) { - ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, - &trip); - if (!ret) - estimate_pid_constants(tz, tz->tzp->sustainable_power, - params->trip_switch_on, - trip.temperature); + if (params->trip_max_desired_temperature) { + int temp = params->trip_max_desired_temperature->temperature; + + estimate_pid_constants(tz, tz->tzp->sustainable_power, + params->trip_switch_on, temp); } reset_pid_controller(params); @@ -697,11 +676,10 @@ static void power_allocator_unbind(struct thermal_zone_device *tz) tz->governor_data = NULL; } -static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id) +static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_index) { struct power_allocator_params *params = tz->governor_data; - struct thermal_trip trip; - int ret; + const struct thermal_trip *trip = &tz->trips[trip_index]; bool update; lockdep_assert_held(&tz->lock); @@ -710,11 +688,11 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id) * We get called for every trip point but we only need to do * our calculations once */ - if (trip_id != params->trip_max_desired_temperature) + if (trip != params->trip_max_desired_temperature) return 0; - ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip); - if (!ret && (tz->temperature < trip.temperature)) { + trip = params->trip_switch_on; + if (trip && tz->temperature < trip->temperature) { update = tz->passive; tz->passive = 0; reset_pid_controller(params); @@ -724,14 +702,7 @@ static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id) tz->passive = 1; - ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, &trip); - if (ret) { - dev_warn(&tz->device, "Failed to get the maximum desired temperature: %d\n", - ret); - return ret; - } - - return allocate_power(tz, trip.temperature); + return allocate_power(tz, params->trip_max_desired_temperature->temperature); } static struct thermal_governor thermal_gov_power_allocator = { -- Gitee From 2689afa2d80d94ae76cd503e61039944246e3d8f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 Oct 2023 20:33:28 +0200 Subject: [PATCH 19/25] thermal: gov_step_wise: Fold update_passive_instance() into its caller ANBZ: #32620 commit fdcf70ed4e1606cd5a5a48f666583053ae4c3978 upstream. Fold update_passive_instance() into thermal_zone_trip_update() that is its only caller so as to make the code in question easier to follow. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano Reviewed-by: Lukasz Luba Signed-off-by: Ruidong Tian --- drivers/thermal/gov_step_wise.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/thermal/gov_step_wise.c b/drivers/thermal/gov_step_wise.c index 849dc1ec8d27..8bc63a1d361e 100644 --- a/drivers/thermal/gov_step_wise.c +++ b/drivers/thermal/gov_step_wise.c @@ -68,17 +68,6 @@ static unsigned long get_target_state(struct thermal_instance *instance, return next_target; } -static void update_passive_instance(struct thermal_zone_device *tz, - enum thermal_trip_type type, int value) -{ - /* - * If value is +1, activate a passive instance. - * If value is -1, deactivate a passive instance. - */ - if (type == THERMAL_TRIP_PASSIVE) - tz->passive += value; -} - static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id) { const struct thermal_trip *trip = &tz->trips[trip_id]; @@ -109,14 +98,17 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id if (instance->initialized && old_target == instance->target) continue; - /* Activate a passive thermal instance */ if (old_target == THERMAL_NO_TARGET && - instance->target != THERMAL_NO_TARGET) - update_passive_instance(tz, trip->type, 1); - /* Deactivate a passive thermal instance */ - else if (old_target != THERMAL_NO_TARGET && - instance->target == THERMAL_NO_TARGET) - update_passive_instance(tz, trip->type, -1); + instance->target != THERMAL_NO_TARGET) { + /* Activate a passive thermal instance */ + if (trip->type == THERMAL_TRIP_PASSIVE) + tz->passive++; + } else if (old_target != THERMAL_NO_TARGET && + instance->target == THERMAL_NO_TARGET) { + /* Deactivate a passive thermal instance */ + if (trip->type == THERMAL_TRIP_PASSIVE) + tz->passive--; + } instance->initialized = true; mutex_lock(&instance->cdev->lock); -- Gitee From 25a65b67f4102c775532ba406d385ba6535997f5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 Oct 2023 20:34:50 +0200 Subject: [PATCH 20/25] thermal: core: Pass trip pointer to governor throttle callback ANBZ: #32620 commit 8c35b1f472533b0df1b8f1f1afcaf4395cdb2256 upstream. Modify the governor .throttle() callback definition so that it takes a trip pointer instead of a trip index as its second argument, adjust the governors accordingly and update the core code invoking .throttle(). This causes the governors to become independent of the representation of the list of trips in the thermal zone structure. This change is not expected to alter the general functionality. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano Signed-off-by: Ruidong Tian --- drivers/thermal/gov_bang_bang.c | 8 +++-- drivers/thermal/gov_fair_share.c | 6 ++-- drivers/thermal/gov_power_allocator.c | 4 +-- drivers/thermal/gov_step_wise.c | 12 ++++--- drivers/thermal/gov_user_space.c | 8 +++-- drivers/thermal/thermal_core.c | 50 +++++++++++++-------------- drivers/thermal/thermal_core.h | 2 +- drivers/thermal/thermal_helpers.c | 3 +- include/linux/thermal.h | 3 +- 9 files changed, 51 insertions(+), 45 deletions(-) diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c index 49cdfaa3a927..6ddf0accdc98 100644 --- a/drivers/thermal/gov_bang_bang.c +++ b/drivers/thermal/gov_bang_bang.c @@ -13,9 +13,10 @@ #include "thermal_core.h" -static int thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_index) +static int thermal_zone_trip_update(struct thermal_zone_device *tz, + const struct thermal_trip *trip) { - const struct thermal_trip *trip = &tz->trips[trip_index]; + int trip_index = thermal_zone_trip_id(tz, trip); struct thermal_instance *instance; if (!trip->hysteresis) @@ -89,7 +90,8 @@ static int thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_ind * (trip_temp - hyst) so that the fan gets turned off again. * */ -static int bang_bang_control(struct thermal_zone_device *tz, int trip) +static int bang_bang_control(struct thermal_zone_device *tz, + const struct thermal_trip *trip) { struct thermal_instance *instance; int ret; diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c index 41effa87d3cd..538abb7de4e2 100644 --- a/drivers/thermal/gov_fair_share.c +++ b/drivers/thermal/gov_fair_share.c @@ -47,7 +47,7 @@ static long get_target_state(struct thermal_zone_device *tz, /** * fair_share_throttle - throttles devices associated with the given zone * @tz: thermal_zone_device - * @trip_index: trip point index + * @trip: trip point * * Throttling Logic: This uses three parameters to calculate the new * throttle state of the cooling devices associated with the given zone. @@ -63,9 +63,9 @@ static long get_target_state(struct thermal_zone_device *tz, * (Heavily assumes the trip points are in ascending order) * new_state of cooling device = P3 * P2 * P1 */ -static int fair_share_throttle(struct thermal_zone_device *tz, int trip_index) +static int fair_share_throttle(struct thermal_zone_device *tz, + const struct thermal_trip *trip) { - const struct thermal_trip *trip = &tz->trips[trip_index]; struct thermal_instance *instance; int total_weight = 0; int total_instance = 0; diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index b87c695f7d27..931cd88425e4 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -676,10 +676,10 @@ static void power_allocator_unbind(struct thermal_zone_device *tz) tz->governor_data = NULL; } -static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_index) +static int power_allocator_throttle(struct thermal_zone_device *tz, + const struct thermal_trip *trip) { struct power_allocator_params *params = tz->governor_data; - const struct thermal_trip *trip = &tz->trips[trip_index]; bool update; lockdep_assert_held(&tz->lock); diff --git a/drivers/thermal/gov_step_wise.c b/drivers/thermal/gov_step_wise.c index 8bc63a1d361e..5436aa58d41e 100644 --- a/drivers/thermal/gov_step_wise.c +++ b/drivers/thermal/gov_step_wise.c @@ -68,15 +68,16 @@ static unsigned long get_target_state(struct thermal_instance *instance, return next_target; } -static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id) +static void thermal_zone_trip_update(struct thermal_zone_device *tz, + const struct thermal_trip *trip) { - const struct thermal_trip *trip = &tz->trips[trip_id]; + int trip_id = thermal_zone_trip_id(tz, trip); enum thermal_trend trend; struct thermal_instance *instance; bool throttle = false; int old_target; - trend = get_tz_trend(tz, trip_id); + trend = get_tz_trend(tz, trip); if (tz->temperature >= trip->temperature) { throttle = true; @@ -120,7 +121,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id /** * step_wise_throttle - throttles devices associated with the given zone * @tz: thermal_zone_device - * @trip: trip point index + * @trip: trip point * * Throttling Logic: This uses the trend of the thermal zone to throttle. * If the thermal zone is 'heating up' this throttles all the cooling @@ -128,7 +129,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id * step. If the zone is 'cooling down' it brings back the performance of * the devices by one step. */ -static int step_wise_throttle(struct thermal_zone_device *tz, int trip) +static int step_wise_throttle(struct thermal_zone_device *tz, + const struct thermal_trip *trip) { struct thermal_instance *instance; diff --git a/drivers/thermal/gov_user_space.c b/drivers/thermal/gov_user_space.c index 8bc1c22aaf03..7a1790b7e8f5 100644 --- a/drivers/thermal/gov_user_space.c +++ b/drivers/thermal/gov_user_space.c @@ -25,11 +25,12 @@ static int user_space_bind(struct thermal_zone_device *tz) /** * notify_user_space - Notifies user space about thermal events * @tz: thermal_zone_device - * @trip: trip point index + * @trip: trip point * * This function notifies the user space through UEvents. */ -static int notify_user_space(struct thermal_zone_device *tz, int trip) +static int notify_user_space(struct thermal_zone_device *tz, + const struct thermal_trip *trip) { char *thermal_prop[5]; int i; @@ -38,7 +39,8 @@ static int notify_user_space(struct thermal_zone_device *tz, int trip) thermal_prop[0] = kasprintf(GFP_KERNEL, "NAME=%s", tz->type); thermal_prop[1] = kasprintf(GFP_KERNEL, "TEMP=%d", tz->temperature); - thermal_prop[2] = kasprintf(GFP_KERNEL, "TRIP=%d", trip); + thermal_prop[2] = kasprintf(GFP_KERNEL, "TRIP=%d", + thermal_zone_trip_id(tz, trip)); thermal_prop[3] = kasprintf(GFP_KERNEL, "EVENT=%d", tz->notify_event); thermal_prop[4] = NULL; kobject_uevent_env(&tz->device.kobj, KOBJ_CHANGE, thermal_prop); diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index ab43438dea35..bd3f4bb85a44 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -305,7 +305,8 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz) thermal_zone_device_set_polling(tz, tz->polling_delay_jiffies); } -static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip) +static void handle_non_critical_trips(struct thermal_zone_device *tz, + const struct thermal_trip *trip) { tz->governor ? tz->governor->throttle(tz, trip) : def_governor->throttle(tz, trip); @@ -327,44 +328,43 @@ void thermal_zone_device_critical(struct thermal_zone_device *tz) EXPORT_SYMBOL(thermal_zone_device_critical); static void handle_critical_trips(struct thermal_zone_device *tz, - int trip, int trip_temp, enum thermal_trip_type trip_type) + const struct thermal_trip *trip) { /* If we have not crossed the trip_temp, we do not care. */ - if (trip_temp <= 0 || tz->temperature < trip_temp) + if (trip->temperature <= 0 || tz->temperature < trip->temperature) return; - trace_thermal_zone_trip(tz, trip, trip_type); + trace_thermal_zone_trip(tz, thermal_zone_trip_id(tz, trip), trip->type); - if (trip_type == THERMAL_TRIP_HOT && tz->ops->hot) - tz->ops->hot(tz); - else if (trip_type == THERMAL_TRIP_CRITICAL) + if (trip->type == THERMAL_TRIP_CRITICAL) tz->ops->critical(tz); + else if (tz->ops->hot) + tz->ops->hot(tz); } -static void handle_thermal_trip(struct thermal_zone_device *tz, int trip_id) +static void handle_thermal_trip(struct thermal_zone_device *tz, + const struct thermal_trip *trip) { - struct thermal_trip trip; - - __thermal_zone_get_trip(tz, trip_id, &trip); - - if (trip.temperature == THERMAL_TEMP_INVALID) + if (trip->temperature == THERMAL_TEMP_INVALID) return; if (tz->last_temperature != THERMAL_TEMP_INVALID) { - if (tz->last_temperature < trip.temperature && - tz->temperature >= trip.temperature) - thermal_notify_tz_trip_up(tz->id, trip_id, + if (tz->last_temperature < trip->temperature && + tz->temperature >= trip->temperature) + thermal_notify_tz_trip_up(tz->id, + thermal_zone_trip_id(tz, trip), tz->temperature); - if (tz->last_temperature >= trip.temperature && - tz->temperature < (trip.temperature - trip.hysteresis)) - thermal_notify_tz_trip_down(tz->id, trip_id, + if (tz->last_temperature >= trip->temperature && + tz->temperature < trip->temperature - trip->hysteresis) + thermal_notify_tz_trip_down(tz->id, + thermal_zone_trip_id(tz, trip), tz->temperature); } - if (trip.type == THERMAL_TRIP_CRITICAL || trip.type == THERMAL_TRIP_HOT) - handle_critical_trips(tz, trip_id, trip.temperature, trip.type); + if (trip->type == THERMAL_TRIP_CRITICAL || trip->type == THERMAL_TRIP_HOT) + handle_critical_trips(tz, trip); else - handle_non_critical_trips(tz, trip_id); + handle_non_critical_trips(tz, trip); } static void update_temperature(struct thermal_zone_device *tz) @@ -401,7 +401,7 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz) void __thermal_zone_device_update(struct thermal_zone_device *tz, enum thermal_notify_event event) { - int count; + const struct thermal_trip *trip; if (tz->suspended) return; @@ -420,8 +420,8 @@ void __thermal_zone_device_update(struct thermal_zone_device *tz, tz->notify_event = event; - for (count = 0; count < tz->num_trips; count++) - handle_thermal_trip(tz, count); + for_each_trip(tz, trip) + handle_thermal_trip(tz, trip); monitor_thermal_zone(tz); } diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 4702d3a152f9..0a3b3ec5120b 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -70,7 +70,7 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) void thermal_cdev_update(struct thermal_cooling_device *); void __thermal_cdev_update(struct thermal_cooling_device *cdev); -int get_tz_trend(struct thermal_zone_device *tz, int trip_index); +int get_tz_trend(struct thermal_zone_device *tz, const struct thermal_trip *trip); struct thermal_instance * get_thermal_instance(struct thermal_zone_device *tz, diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c index c1d0af73c85d..69e8ea4aa908 100644 --- a/drivers/thermal/thermal_helpers.c +++ b/drivers/thermal/thermal_helpers.c @@ -22,9 +22,8 @@ #include "thermal_core.h" #include "thermal_trace.h" -int get_tz_trend(struct thermal_zone_device *tz, int trip_index) +int get_tz_trend(struct thermal_zone_device *tz, const struct thermal_trip *trip) { - struct thermal_trip *trip = tz->trips ? &tz->trips[trip_index] : NULL; enum thermal_trend trend; if (tz->emul_temperature || !tz->ops->get_trend || diff --git a/include/linux/thermal.h b/include/linux/thermal.h index fc9a9101e1b0..578e3d0d6f85 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -203,7 +203,8 @@ struct thermal_governor { char name[THERMAL_NAME_LENGTH]; int (*bind_to_tz)(struct thermal_zone_device *tz); void (*unbind_from_tz)(struct thermal_zone_device *tz); - int (*throttle)(struct thermal_zone_device *tz, int trip); + int (*throttle)(struct thermal_zone_device *tz, + const struct thermal_trip *trip); struct list_head governor_list; }; -- Gitee From a85a15dd8636056b58e1cee72034d61e327f50a0 Mon Sep 17 00:00:00 2001 From: James Morse Date: Fri, 20 Oct 2023 14:59:48 +0100 Subject: [PATCH 21/25] ACPI: scan: Use the acpi_device_is_present() helper in more places ANBZ: #32620 commit b5bdb60faaaff11bcfc9a90372158bc56e7ff544 upstream. acpi_device_is_present() checks the present or functional bits from the cached copy of _STA. A few places open-code this check. Use the helper instead to improve readability. Signed-off-by: James Morse Reviewed-by: Jonathan Cameron Reviewed-by: Gavin Shan Signed-off-by: Russell King (Oracle) Reviewed-by: Miguel Luis Signed-off-by: Rafael J. Wysocki Signed-off-by: Ruidong Tian --- drivers/acpi/scan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 515ce9476e0b..ab2695a861df 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -304,7 +304,7 @@ static int acpi_scan_device_check(struct acpi_device *adev) int error; acpi_bus_get_status(adev); - if (adev->status.present || adev->status.functional) { + if (acpi_device_is_present(adev)) { /* * This function is only called for device objects for which * matching scan handlers exist. The only situation in which @@ -334,7 +334,7 @@ static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used) int error; acpi_bus_get_status(adev); - if (!(adev->status.present || adev->status.functional)) { + if (!acpi_device_is_present(adev)) { acpi_scan_device_not_present(adev); return 0; } -- Gitee From 549dbbac04fd2e6d1589d78e57ae635efc4bdc39 Mon Sep 17 00:00:00 2001 From: James Morse Date: Fri, 20 Oct 2023 19:47:04 +0100 Subject: [PATCH 22/25] ACPI: scan: Rename acpi_scan_device_not_present() to be about enumeration ANBZ: #32620 commit 8c6fdbd635d4afbcd57243083319a55624d2e168 upstream. acpi_scan_device_not_present() is called when a device in the hierarchy is not available for enumeration. Historically enumeration was only based on whether the device was present. To add support for only enumerating devices that are both present and enabled, this helper should be renamed. It was only ever about enumeration, rename it acpi_scan_device_not_enumerated(). No change in behaviour is intended. Signed-off-by: James Morse Reviewed-by: Gavin Shan Signed-off-by: Russell King (Oracle) Reviewed-by: Miguel Luis Signed-off-by: Rafael J. Wysocki Signed-off-by: Ruidong Tian --- drivers/acpi/scan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ab2695a861df..8cc937ef4e4d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -289,10 +289,10 @@ static int acpi_scan_hot_remove(struct acpi_device *device) return 0; } -static int acpi_scan_device_not_present(struct acpi_device *adev) +static int acpi_scan_device_not_enumerated(struct acpi_device *adev) { if (!acpi_device_enumerated(adev)) { - dev_warn(&adev->dev, "Still not present\n"); + dev_warn(&adev->dev, "Still not enumerated\n"); return -EALREADY; } acpi_bus_trim(adev); @@ -323,7 +323,7 @@ static int acpi_scan_device_check(struct acpi_device *adev) return error; } } else { - error = acpi_scan_device_not_present(adev); + error = acpi_scan_device_not_enumerated(adev); } return error; } @@ -335,7 +335,7 @@ static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used) acpi_bus_get_status(adev); if (!acpi_device_is_present(adev)) { - acpi_scan_device_not_present(adev); + acpi_scan_device_not_enumerated(adev); return 0; } if (handler && handler->hotplug.scan_dependent) -- Gitee From 19e9b455d79095fa86b3debecd1d54dd05a88418 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 7 Dec 2023 19:28:10 +0100 Subject: [PATCH 23/25] ACPI: utils: Fix error path in acpi_evaluate_reference() ANBZ: #32620 commit 8f0b960a42badda7a2781e8a33564624200debc9 upstream. If a pointer to an uninitialized struct acpi_handle_list is passed to acpi_evaluate_reference() and it decides to bail out early, either because acpi_evaluate_object() fails, or because it produces invalid data, the handles pointer from the struct acpi_handle_list will be passed to kfree() and if it is not NULL, the kernel will crash on an attempt to free unallocated memory. Address this by moving the "end" label in acpi_evaluate_reference() to the end of the function, which is sufficient, because no cleanup is needed in that case. Fixes: 2e57d10a6591 ("ACPI: utils: Dynamically determine acpi_handle_list size") Signed-off-by: Rafael J. Wysocki Tested-by: Woody Suwalski Signed-off-by: Ruidong Tian --- drivers/acpi/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index b021a9aacabb..3edae8afc100 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -400,13 +400,13 @@ acpi_evaluate_reference(acpi_handle handle, acpi_handle_debug(list->handles[i], "Found in reference list\n"); } - end: if (ACPI_FAILURE(status)) { list->count = 0; kfree(list->handles); list->handles = NULL; } +end: kfree(buffer.pointer); return status; -- Gitee From 7800ad70cc626cd82eecb55e609ebbfa3c2e802d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 6 Jun 2024 20:27:30 +0200 Subject: [PATCH 24/25] thermal: ACPI: Invalidate trip points with temperature of 0 or below ANBZ: #32620 commit 7f18bd49cb6b6a3ab6d860fefccdc94f2a247db0 upstream. It is reported that commit 950210887670 ("thermal: core: Drop trips_disabled bitmask") causes the maximum frequency of CPUs to drop further down with every system sleep-wake cycle on Intel Core i7-4710HQ. This turns out to be due to a trip point whose temperature is equal to 0 degrees Celsius which is acted on every time the system wakes from sleep. Before commit 950210887670 this trip point would be disabled wia the trips_disabled bitmask, but now it is treated as a valid one. Since ACPI thermal control is generally about protection against overheating, trip points with temperature of 0 centigrade or below are not particularly useful there, so initialize them all as invalid which fixes the problem at hand. Fixes: 950210887670 ("thermal: core: Drop trips_disabled bitmask") Closes: https://lore.kernel.org/linux-pm/3f71747b-f852-4ee0-b384-cf46b2aefa3f@gmx.com Reported-by: Tibor Billes Tested-by: Tibor Billes Cc: 6.7+ # 6.7+ Signed-off-by: Rafael J. Wysocki Signed-off-by: Ruidong Tian --- drivers/acpi/thermal.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 0770034d8cfe..8db940f070e3 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -165,11 +165,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) { + int temp; + if (temp_deci_k == 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); + if (temp <= 0) + return THERMAL_TEMP_INVALID; + + return temp; } static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip) -- Gitee From a5edb8741faf54729a6a313942fe45587f5f9f7b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 8 Dec 2023 21:07:41 +0100 Subject: [PATCH 25/25] ACPI: utils: Fix white space in struct acpi_handle_list definition ANBZ: #32620 commit 4c660ffef34b7d645ae3144369bc50257f295212 upstream. Fix inadvertently introduced white space damage in the struct acpi_handle_list definition. No functional impact. Fixes: 2e57d10a6591 ("ACPI: utils: Dynamically determine acpi_handle_list size") Signed-off-by: Rafael J. Wysocki Signed-off-by: Ruidong Tian --- include/acpi/acpi_bus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 146c17ddbbe1..5968192e674c 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -19,7 +19,7 @@ struct acpi_handle_list { u32 count; - acpi_handle* handles; + acpi_handle *handles; }; /* acpi_utils.h */ -- Gitee