From 4be32333d941a53dcfb48e342c808c63a3b25576 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 12 Sep 2023 20:35:40 +0200 Subject: ACPI: thermal: Simplify initialization of critical and hot trips Use the observation that the critical and hot trip points are never updated by the ACPI thermal driver, because the flags passed from acpi_thermal_notify() to acpi_thermal_trips_update() do not include ACPI_TRIPS_CRITICAL or ACPI_TRIPS_HOT, to move the initialization of those trip points directly into acpi_thermal_get_trip_points() and reduce the size of __acpi_thermal_trips_update(). Also make the critical and hot trip points initialization code more straightforward and drop the flags that are not needed any more. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 130 +++++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 312730f8272e..fe64347ff925 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -43,17 +43,13 @@ #define ACPI_THERMAL_MAX_ACTIVE 10 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 -#define ACPI_TRIPS_CRITICAL BIT(0) -#define ACPI_TRIPS_HOT BIT(1) -#define ACPI_TRIPS_PASSIVE BIT(2) -#define ACPI_TRIPS_ACTIVE BIT(3) -#define ACPI_TRIPS_DEVICES BIT(4) +#define ACPI_TRIPS_PASSIVE BIT(0) +#define ACPI_TRIPS_ACTIVE BIT(1) +#define ACPI_TRIPS_DEVICES BIT(2) #define ACPI_TRIPS_THRESHOLDS (ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE) -#define ACPI_TRIPS_INIT (ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT | \ - ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE | \ - ACPI_TRIPS_DEVICES) +#define ACPI_TRIPS_INIT (ACPI_TRIPS_THRESHOLDS | ACPI_TRIPS_DEVICES) /* * This exception is thrown out in two cases: @@ -196,62 +192,6 @@ static void __acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) bool valid = false; int i; - /* Critical Shutdown */ - if (flag & ACPI_TRIPS_CRITICAL) { - status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, &tmp); - tz->trips.critical.temperature = tmp; - /* - * Treat freezing temperatures as invalid as well; some - * BIOSes return really low values and cause reboots at startup. - * Below zero (Celsius) values clearly aren't right for sure.. - * ... so lets discard those as invalid. - */ - if (ACPI_FAILURE(status)) { - tz->trips.critical.valid = false; - acpi_handle_debug(tz->device->handle, - "No critical threshold\n"); - } else if (tmp <= 2732) { - pr_info(FW_BUG "Invalid critical threshold (%llu)\n", tmp); - tz->trips.critical.valid = false; - } else { - tz->trips.critical.valid = true; - acpi_handle_debug(tz->device->handle, - "Found critical threshold [%lu]\n", - tz->trips.critical.temperature); - } - if (tz->trips.critical.valid) { - if (crt == -1) { - tz->trips.critical.valid = false; - } else if (crt > 0) { - unsigned long crt_k = celsius_to_deci_kelvin(crt); - - /* - * Allow override critical threshold - */ - if (crt_k > tz->trips.critical.temperature) - pr_info("Critical threshold %d C\n", crt); - - tz->trips.critical.temperature = crt_k; - } - } - } - - /* Critical Sleep (optional) */ - if (flag & ACPI_TRIPS_HOT) { - 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"); - } else { - tz->trips.hot.temperature = tmp; - tz->trips.hot.valid = true; - acpi_handle_debug(tz->device->handle, - "Found hot threshold [%lu]\n", - tz->trips.hot.temperature); - } - } - /* Passive (optional) */ if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.trip.valid) || flag == ACPI_TRIPS_INIT) { @@ -451,11 +391,73 @@ static void acpi_thermal_trips_update(struct acpi_thermal *tz, u32 event) dev_name(&adev->dev), event, 0); } +static void acpi_thermal_get_critical_trip(struct acpi_thermal *tz) +{ + unsigned long long tmp; + acpi_status status; + + if (crt > 0) { + tmp = celsius_to_deci_kelvin(crt); + goto set; + } + if (crt == -1) { + acpi_handle_debug(tz->device->handle, "Critical threshold disabled\n"); + goto fail; + } + + 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; + } + if (tmp <= 2732) { + /* + * Below zero (Celsius) values clearly aren't right for sure, + * so discard them as invalid. + */ + pr_info(FW_BUG "Invalid critical threshold (%llu)\n", tmp); + goto fail; + } + +set: + tz->trips.critical.valid = true; + tz->trips.critical.temperature = tmp; + acpi_handle_debug(tz->device->handle, "Critical threshold [%lu]\n", + tz->trips.critical.temperature); + return; + +fail: + tz->trips.critical.valid = false; + tz->trips.critical.temperature = THERMAL_TEMP_INVALID; +} + +static void acpi_thermal_get_hot_trip(struct acpi_thermal *tz) +{ + unsigned long long tmp; + acpi_status status; + + status = acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, &tmp); + if (ACPI_FAILURE(status)) { + tz->trips.hot.valid = false; + tz->trips.hot.temperature = THERMAL_TEMP_INVALID; + acpi_handle_debug(tz->device->handle, "No hot threshold\n"); + return; + } + + tz->trips.hot.valid = true; + tz->trips.hot.temperature = tmp; + acpi_handle_debug(tz->device->handle, "Hot threshold [%lu]\n", + tz->trips.hot.temperature); +} + static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) { bool valid; int i; + acpi_thermal_get_critical_trip(tz); + acpi_thermal_get_hot_trip(tz); + /* Passive and active trip points (optional). */ __acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); valid = tz->trips.critical.valid | -- cgit From b09872a652d386207600fcd001077251c0eae15a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 12 Sep 2023 20:36:21 +0200 Subject: ACPI: thermal: Fold acpi_thermal_get_info() into its caller There is only one caller of acpi_thermal_get_info() and the code from it can be folded into its caller just fine, so do that. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 52 ++++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index fe64347ff925..b2705e67a6bd 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -846,38 +846,6 @@ static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) acpi_evaluate_integer(handle, "_TMP", NULL, &value); } -static int acpi_thermal_get_info(struct acpi_thermal *tz) -{ - int result; - - if (!tz) - return -EINVAL; - - acpi_thermal_aml_dependency_fix(tz); - - /* Get trip points [_CRT, _PSV, etc.] (required) */ - result = acpi_thermal_get_trip_points(tz); - if (result) - return result; - - /* Get temperature [_TMP] (required) */ - result = acpi_thermal_get_temperature(tz); - if (result) - return result; - - /* Set the cooling mode [_SCP] to active cooling (default) */ - acpi_execute_simple_method(tz->device->handle, "_SCP", - ACPI_THERMAL_MODE_ACTIVE); - - /* Get default polling frequency [_TZP] (optional) */ - if (tzp) - tz->polling_frequency = tzp; - else - acpi_thermal_get_polling_frequency(tz); - - return 0; -} - /* * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI * handles temperature values with a single decimal place. As a consequence, @@ -940,10 +908,28 @@ static int acpi_thermal_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); device->driver_data = tz; - result = acpi_thermal_get_info(tz); + acpi_thermal_aml_dependency_fix(tz); + + /* Get trip points [_CRT, _PSV, etc.] (required). */ + result = acpi_thermal_get_trip_points(tz); if (result) goto free_memory; + /* Get temperature [_TMP] (required). */ + result = acpi_thermal_get_temperature(tz); + if (result) + goto free_memory; + + /* Set the cooling mode [_SCP] to active cooling. */ + acpi_execute_simple_method(tz->device->handle, "_SCP", + ACPI_THERMAL_MODE_ACTIVE); + + /* Determine the default polling frequency [_TZP]. */ + if (tzp) + tz->polling_frequency = tzp; + else + acpi_thermal_get_polling_frequency(tz); + acpi_thermal_guess_offset(tz); result = acpi_thermal_register_thermal_zone(tz); -- cgit From f04256a8f7de2c13619b636cec1109e596804229 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 12 Sep 2023 20:37:59 +0200 Subject: ACPI: thermal: Determine the number of trip points earlier Compute the number of trip points in acpi_thermal_add() so as to allow the driver's data structures to be simplified going forward. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 56 ++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index b2705e67a6bd..79452315fdf3 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -452,7 +452,7 @@ static void acpi_thermal_get_hot_trip(struct acpi_thermal *tz) static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) { - bool valid; + unsigned int count = 0; int i; acpi_thermal_get_critical_trip(tz); @@ -460,18 +460,24 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) /* Passive and active trip points (optional). */ __acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); - valid = tz->trips.critical.valid | - tz->trips.hot.valid | - tz->trips.passive.trip.valid; + if (tz->trips.critical.valid) + count++; + + if (tz->trips.hot.valid) + count++; - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) - valid = valid || tz->trips.active[i].trip.valid; + if (tz->trips.passive.trip.valid) + count++; + + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { + if (tz->trips.active[i].trip.valid) + count++; + else + break; - if (!valid) { - pr_warn(FW_BUG "No valid trip found\n"); - return -ENODEV; } - return 0; + + return count; } /* sys I/F for generic thermal sysfs support */ @@ -681,29 +687,15 @@ static void acpi_thermal_zone_sysfs_remove(struct acpi_thermal *tz) sysfs_remove_link(&tzdev->kobj, "device"); } -static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) +static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz, + unsigned int trip_count) { struct acpi_thermal_trip *acpi_trip; struct thermal_trip *trip; int passive_delay = 0; - int trip_count = 0; int result; int i; - if (tz->trips.critical.valid) - trip_count++; - - if (tz->trips.hot.valid) - trip_count++; - - if (tz->trips.passive.trip.valid) { - trip_count++; - passive_delay = tz->trips.passive.tsp * 100; - } - - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].trip.valid; i++) - trip_count++; - trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); if (!trip) return -ENOMEM; @@ -724,6 +716,8 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) acpi_trip = &tz->trips.passive.trip; if (acpi_trip->valid) { + passive_delay = tz->trips.passive.tsp * 100; + trip->type = THERMAL_TRIP_PASSIVE; trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); trip->priv = acpi_trip; @@ -893,6 +887,7 @@ static void acpi_thermal_check_fn(struct work_struct *work) static int acpi_thermal_add(struct acpi_device *device) { struct acpi_thermal *tz; + unsigned int trip_count; int result; if (!device) @@ -911,9 +906,12 @@ static int acpi_thermal_add(struct acpi_device *device) acpi_thermal_aml_dependency_fix(tz); /* Get trip points [_CRT, _PSV, etc.] (required). */ - result = acpi_thermal_get_trip_points(tz); - if (result) + trip_count = acpi_thermal_get_trip_points(tz); + if (!trip_count) { + pr_warn(FW_BUG "No valid trip points!\n"); + result = -ENODEV; goto free_memory; + } /* Get temperature [_TMP] (required). */ result = acpi_thermal_get_temperature(tz); @@ -932,7 +930,7 @@ static int acpi_thermal_add(struct acpi_device *device) acpi_thermal_guess_offset(tz); - result = acpi_thermal_register_thermal_zone(tz); + result = acpi_thermal_register_thermal_zone(tz, trip_count); if (result) goto free_memory; -- cgit From 06a5f76ee104c17022425ade32b970c1d7793e01 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 12 Sep 2023 20:39:15 +0200 Subject: ACPI: thermal: Create and populate trip points table earlier Create and populate the driver's trip points table in acpi_thermal_add() so as to allow the its data structures to be simplified going forward. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 105 ++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 79452315fdf3..d10e8cec4dd8 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -688,53 +688,10 @@ static void acpi_thermal_zone_sysfs_remove(struct acpi_thermal *tz) } static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz, - unsigned int trip_count) + unsigned int trip_count, + int passive_delay) { - struct acpi_thermal_trip *acpi_trip; - struct thermal_trip *trip; - int passive_delay = 0; int result; - int i; - - trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); - if (!trip) - return -ENOMEM; - - tz->trip_table = trip; - - if (tz->trips.critical.valid) { - trip->type = THERMAL_TRIP_CRITICAL; - trip->temperature = acpi_thermal_temp(tz, tz->trips.critical.temperature); - trip++; - } - - if (tz->trips.hot.valid) { - trip->type = THERMAL_TRIP_HOT; - trip->temperature = acpi_thermal_temp(tz, tz->trips.hot.temperature); - trip++; - } - - acpi_trip = &tz->trips.passive.trip; - if (acpi_trip->valid) { - passive_delay = tz->trips.passive.tsp * 100; - - trip->type = THERMAL_TRIP_PASSIVE; - trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); - trip->priv = acpi_trip; - trip++; - } - - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - acpi_trip = &tz->trips.active[i].trip; - - if (!acpi_trip->valid) - break; - - trip->type = THERMAL_TRIP_ACTIVE; - trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); - trip->priv = acpi_trip; - trip++; - } tz->thermal_zone = thermal_zone_device_register_with_trips("acpitz", tz->trip_table, @@ -744,10 +701,8 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz, NULL, passive_delay, tz->polling_frequency * 100); - if (IS_ERR(tz->thermal_zone)) { - result = PTR_ERR(tz->thermal_zone); - goto free_trip_table; - } + if (IS_ERR(tz->thermal_zone)) + return PTR_ERR(tz->thermal_zone); result = acpi_thermal_zone_sysfs_add(tz); if (result) @@ -766,8 +721,6 @@ remove_links: acpi_thermal_zone_sysfs_remove(tz); unregister_tzd: thermal_zone_device_unregister(tz->thermal_zone); -free_trip_table: - kfree(tz->trip_table); return result; } @@ -886,9 +839,13 @@ static void acpi_thermal_check_fn(struct work_struct *work) static int acpi_thermal_add(struct acpi_device *device) { + struct acpi_thermal_trip *acpi_trip; + struct thermal_trip *trip; struct acpi_thermal *tz; unsigned int trip_count; + int passive_delay = 0; int result; + int i; if (!device) return -EINVAL; @@ -930,9 +887,49 @@ static int acpi_thermal_add(struct acpi_device *device) acpi_thermal_guess_offset(tz); - result = acpi_thermal_register_thermal_zone(tz, trip_count); + trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); + if (!trip) + return -ENOMEM; + + tz->trip_table = trip; + + if (tz->trips.critical.valid) { + trip->type = THERMAL_TRIP_CRITICAL; + trip->temperature = acpi_thermal_temp(tz, tz->trips.critical.temperature); + trip++; + } + + if (tz->trips.hot.valid) { + trip->type = THERMAL_TRIP_HOT; + trip->temperature = acpi_thermal_temp(tz, tz->trips.hot.temperature); + trip++; + } + + acpi_trip = &tz->trips.passive.trip; + if (acpi_trip->valid) { + passive_delay = tz->trips.passive.tsp * 100; + + trip->type = THERMAL_TRIP_PASSIVE; + trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); + trip->priv = acpi_trip; + trip++; + } + + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { + acpi_trip = &tz->trips.active[i].trip; + + if (!acpi_trip->valid) + break; + + trip->type = THERMAL_TRIP_ACTIVE; + trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); + trip->priv = acpi_trip; + trip++; + } + + result = acpi_thermal_register_thermal_zone(tz, trip_count, passive_delay); if (result) - goto free_memory; + goto free_trips; refcount_set(&tz->thermal_check_count, 3); mutex_init(&tz->thermal_check_lock); @@ -951,6 +948,8 @@ static int acpi_thermal_add(struct acpi_device *device) flush_wq: flush_workqueue(acpi_thermal_pm_queue); acpi_thermal_unregister_thermal_zone(tz); +free_trips: + kfree(tz->trip_table); free_memory: kfree(tz); -- cgit From 30f04c7535e464f1824edb02e736a50be018777b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 12 Sep 2023 20:41:06 +0200 Subject: ACPI: thermal: Simplify critical and hot trips representation Notice that the only piece of information regarding the critical and hot trips that needs to be stored in the driver's local data structures is whether or not these trips are valid, so drop all of the redundant information from there and adjust the code accordingly. Among other things, this requires acpi_thermal_add() to be rearranged so as to obtain the critical trip temperature before populating the trip points table and for symmetry, the hot trip temperature is obtained earlier too. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 69 ++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index d10e8cec4dd8..f60f3633f3ef 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -107,10 +107,10 @@ struct acpi_thermal_active { }; struct acpi_thermal_trips { - struct acpi_thermal_trip critical; - struct acpi_thermal_trip hot; struct acpi_thermal_passive passive; struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; + bool critical_valid; + bool hot_valid; }; struct acpi_thermal { @@ -391,7 +391,7 @@ static void acpi_thermal_trips_update(struct acpi_thermal *tz, u32 event) dev_name(&adev->dev), event, 0); } -static void acpi_thermal_get_critical_trip(struct acpi_thermal *tz) +static long acpi_thermal_get_critical_trip(struct acpi_thermal *tz) { unsigned long long tmp; acpi_status status; @@ -420,34 +420,30 @@ static void acpi_thermal_get_critical_trip(struct acpi_thermal *tz) } set: - tz->trips.critical.valid = true; - tz->trips.critical.temperature = tmp; - acpi_handle_debug(tz->device->handle, "Critical threshold [%lu]\n", - tz->trips.critical.temperature); - return; + tz->trips.critical_valid = true; + acpi_handle_debug(tz->device->handle, "Critical threshold [%llu]\n", tmp); + return tmp; fail: - tz->trips.critical.valid = false; - tz->trips.critical.temperature = THERMAL_TEMP_INVALID; + tz->trips.critical_valid = false; + return THERMAL_TEMP_INVALID; } -static void acpi_thermal_get_hot_trip(struct acpi_thermal *tz) +static long acpi_thermal_get_hot_trip(struct acpi_thermal *tz) { unsigned long long tmp; acpi_status status; status = acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, &tmp); if (ACPI_FAILURE(status)) { - tz->trips.hot.valid = false; - tz->trips.hot.temperature = THERMAL_TEMP_INVALID; + tz->trips.hot_valid = false; acpi_handle_debug(tz->device->handle, "No hot threshold\n"); - return; + return THERMAL_TEMP_INVALID; } - tz->trips.hot.valid = true; - tz->trips.hot.temperature = tmp; - acpi_handle_debug(tz->device->handle, "Hot threshold [%lu]\n", - tz->trips.hot.temperature); + tz->trips.hot_valid = true; + acpi_handle_debug(tz->device->handle, "Hot threshold [%llu]\n", tmp); + return tmp; } static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) @@ -455,17 +451,9 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) unsigned int count = 0; int i; - acpi_thermal_get_critical_trip(tz); - acpi_thermal_get_hot_trip(tz); /* Passive and active trip points (optional). */ __acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); - if (tz->trips.critical.valid) - count++; - - if (tz->trips.hot.valid) - count++; - if (tz->trips.passive.trip.valid) count++; @@ -578,10 +566,10 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, int trip = -1; int result = 0; - if (tz->trips.critical.valid) + if (tz->trips.critical_valid) trip++; - if (tz->trips.hot.valid) + if (tz->trips.hot_valid) trip++; if (tz->trips.passive.trip.valid) { @@ -803,10 +791,9 @@ static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) * The heuristic below should work for all ACPI thermal zones which have a * critical trip point with a value being a multiple of 0.5 degree Celsius. */ -static void acpi_thermal_guess_offset(struct acpi_thermal *tz) +static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp) { - if (tz->trips.critical.valid && - (tz->trips.critical.temperature % 5) == 1) + if (tz->trips.critical_valid && crit_temp % 5 == 1) tz->kelvin_offset = 273100; else tz->kelvin_offset = 273200; @@ -843,6 +830,7 @@ static int acpi_thermal_add(struct acpi_device *device) struct thermal_trip *trip; struct acpi_thermal *tz; unsigned int trip_count; + int crit_temp, hot_temp; int passive_delay = 0; int result; int i; @@ -864,6 +852,15 @@ static int acpi_thermal_add(struct acpi_device *device) /* Get trip points [_CRT, _PSV, etc.] (required). */ trip_count = acpi_thermal_get_trip_points(tz); + + crit_temp = acpi_thermal_get_critical_trip(tz); + if (tz->trips.critical_valid) + trip_count++; + + hot_temp = acpi_thermal_get_hot_trip(tz); + if (tz->trips.hot_valid) + trip_count++; + if (!trip_count) { pr_warn(FW_BUG "No valid trip points!\n"); result = -ENODEV; @@ -885,7 +882,7 @@ static int acpi_thermal_add(struct acpi_device *device) else acpi_thermal_get_polling_frequency(tz); - acpi_thermal_guess_offset(tz); + acpi_thermal_guess_offset(tz, crit_temp); trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); if (!trip) @@ -893,15 +890,15 @@ static int acpi_thermal_add(struct acpi_device *device) tz->trip_table = trip; - if (tz->trips.critical.valid) { + if (tz->trips.critical_valid) { trip->type = THERMAL_TRIP_CRITICAL; - trip->temperature = acpi_thermal_temp(tz, tz->trips.critical.temperature); + trip->temperature = acpi_thermal_temp(tz, crit_temp); trip++; } - if (tz->trips.hot.valid) { + if (tz->trips.hot_valid) { trip->type = THERMAL_TRIP_HOT; - trip->temperature = acpi_thermal_temp(tz, tz->trips.hot.temperature); + trip->temperature = acpi_thermal_temp(tz, hot_temp); trip++; } -- cgit From 64c512edf97735ecd882b532a5c5351edde39676 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 12 Sep 2023 20:43:52 +0200 Subject: ACPI: thermal: Untangle initialization and updates of the passive trip Separate the code needed to update the passive trip (in a response to a notification from the platform firmware) as well as to initialize it from the code that is only necessary for its initialization and cleanly divide it into functions that each carry out a specific action. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 198 +++++++++++++++++++++++++++++++------------------ 1 file changed, 125 insertions(+), 73 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index f60f3633f3ef..bd8d9bfd5df9 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -192,73 +192,6 @@ static void __acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) bool valid = false; int i; - /* Passive (optional) */ - if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.trip.valid) || - flag == ACPI_TRIPS_INIT) { - valid = tz->trips.passive.trip.valid; - if (psv == -1) { - status = AE_SUPPORT; - } else if (psv > 0) { - tmp = celsius_to_deci_kelvin(psv); - status = AE_OK; - } else { - status = acpi_evaluate_integer(tz->device->handle, - "_PSV", NULL, &tmp); - } - - if (ACPI_FAILURE(status)) { - tz->trips.passive.trip.valid = false; - } else { - tz->trips.passive.trip.temperature = tmp; - tz->trips.passive.trip.valid = true; - if (flag == ACPI_TRIPS_INIT) { - status = acpi_evaluate_integer(tz->device->handle, - "_TC1", NULL, &tmp); - if (ACPI_FAILURE(status)) - tz->trips.passive.trip.valid = false; - else - tz->trips.passive.tc1 = tmp; - - status = acpi_evaluate_integer(tz->device->handle, - "_TC2", NULL, &tmp); - if (ACPI_FAILURE(status)) - tz->trips.passive.trip.valid = false; - else - tz->trips.passive.tc2 = tmp; - - status = acpi_evaluate_integer(tz->device->handle, - "_TSP", NULL, &tmp); - if (ACPI_FAILURE(status)) - tz->trips.passive.trip.valid = false; - else - tz->trips.passive.tsp = tmp; - } - } - } - if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.trip.valid) { - memset(&devices, 0, sizeof(struct acpi_handle_list)); - status = acpi_evaluate_reference(tz->device->handle, "_PSL", - NULL, &devices); - if (ACPI_FAILURE(status)) { - acpi_handle_info(tz->device->handle, - "Invalid passive threshold\n"); - tz->trips.passive.trip.valid = false; - } else { - tz->trips.passive.trip.valid = true; - } - - if (memcmp(&tz->trips.passive.devices, &devices, - sizeof(struct acpi_handle_list))) { - memcpy(&tz->trips.passive.devices, &devices, - sizeof(struct acpi_handle_list)); - ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); - } - } - if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) { - if (valid != tz->trips.passive.trip.valid) - ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state"); - } - /* Active (optional) */ for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; @@ -339,6 +272,72 @@ static void __acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) } } +static void update_acpi_thermal_trip_temp(struct acpi_thermal_trip *acpi_trip, + int temp) +{ + acpi_trip->valid = temp != THERMAL_TEMP_INVALID; + acpi_trip->temperature = temp; +} + +static long get_passive_temp(struct acpi_thermal *tz) +{ + unsigned long long tmp; + acpi_status status; + + status = acpi_evaluate_integer(tz->device->handle, "_PSV", NULL, &tmp); + if (ACPI_FAILURE(status)) + return THERMAL_TEMP_INVALID; + + return tmp; +} + +static void acpi_thermal_update_passive_trip(struct acpi_thermal *tz) +{ + struct acpi_thermal_trip *acpi_trip = &tz->trips.passive.trip; + + if (!acpi_trip->valid || psv > 0) + return; + + update_acpi_thermal_trip_temp(acpi_trip, get_passive_temp(tz)); + if (!acpi_trip->valid) + ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_PASSIVE, tz, "state"); +} + +static bool update_passive_devices(struct acpi_thermal *tz, bool compare) +{ + struct acpi_handle_list devices; + acpi_status status; + + memset(&devices, 0, sizeof(devices)); + + status = acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, &devices); + if (ACPI_FAILURE(status)) { + acpi_handle_info(tz->device->handle, + "Missing device list for passive threshold\n"); + return false; + } + + if (compare && memcmp(&tz->trips.passive.devices, &devices, sizeof(devices))) + ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_PASSIVE, tz, "device"); + + memcpy(&tz->trips.passive.devices, &devices, sizeof(devices)); + return true; +} + +static void acpi_thermal_update_passive_devices(struct acpi_thermal *tz) +{ + struct acpi_thermal_trip *acpi_trip = &tz->trips.passive.trip; + + if (!acpi_trip->valid) + return; + + if (update_passive_devices(tz, true)) + return; + + update_acpi_thermal_trip_temp(acpi_trip, THERMAL_TEMP_INVALID); + ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_PASSIVE, tz, "state"); +} + static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) { struct acpi_thermal_trip *acpi_trip = trip->priv; @@ -359,8 +358,15 @@ 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 flag = data == ACPI_THERMAL_NOTIFY_THRESHOLDS ? - ACPI_TRIPS_THRESHOLDS : ACPI_TRIPS_DEVICES; + int flag; + + if (data == ACPI_THERMAL_NOTIFY_THRESHOLDS) { + acpi_thermal_update_passive_trip(tz); + flag = ACPI_TRIPS_THRESHOLDS; + } else { + acpi_thermal_update_passive_devices(tz); + flag = ACPI_TRIPS_DEVICES; + } __acpi_thermal_trips_update(tz, flag); @@ -446,17 +452,63 @@ static long acpi_thermal_get_hot_trip(struct acpi_thermal *tz) return tmp; } +static bool acpi_thermal_init_passive_trip(struct acpi_thermal *tz) +{ + unsigned long long tmp; + acpi_status status; + int temp; + + if (psv == -1) + goto fail; + + if (psv > 0) { + temp = celsius_to_deci_kelvin(psv); + } else { + temp = get_passive_temp(tz); + if (temp == THERMAL_TEMP_INVALID) + goto fail; + } + + status = acpi_evaluate_integer(tz->device->handle, "_TC1", NULL, &tmp); + if (ACPI_FAILURE(status)) + goto fail; + + tz->trips.passive.tc1 = tmp; + + status = acpi_evaluate_integer(tz->device->handle, "_TC2", NULL, &tmp); + if (ACPI_FAILURE(status)) + goto fail; + + tz->trips.passive.tc2 = tmp; + + status = acpi_evaluate_integer(tz->device->handle, "_TSP", NULL, &tmp); + if (ACPI_FAILURE(status)) + goto fail; + + tz->trips.passive.tsp = tmp; + + if (!update_passive_devices(tz, false)) + goto fail; + + update_acpi_thermal_trip_temp(&tz->trips.passive.trip, temp); + return true; + +fail: + update_acpi_thermal_trip_temp(&tz->trips.passive.trip, THERMAL_TEMP_INVALID); + return false; +} + static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) { unsigned int count = 0; int i; - /* Passive and active trip points (optional). */ - __acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); - - if (tz->trips.passive.trip.valid) + if (acpi_thermal_init_passive_trip(tz)) count++; + /* Active trip points (optional). */ + __acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { if (tz->trips.active[i].trip.valid) count++; -- cgit From cdfe09df04a0706f3926c0643ba2218fae04003b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 20 Sep 2023 14:35:46 +0200 Subject: ACPI: thermal: Untangle initialization and updates of active trips Separate the code needed to update active trips (in a response to a notification from the platform firmware) as well as to initialize them from the code that is only necessary for their initialization and cleanly divide it into functions that each carry out a specific action. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/acpi/thermal.c | 197 +++++++++++++++++++++++++------------------------ 1 file changed, 100 insertions(+), 97 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index bd8d9bfd5df9..a6599b19dba8 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -184,94 +184,6 @@ static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k) tz->kelvin_offset); } -static void __acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) -{ - acpi_status status; - unsigned long long tmp; - struct acpi_handle_list devices; - bool valid = false; - int i; - - /* Active (optional) */ - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; - valid = tz->trips.active[i].trip.valid; - - if (act == -1) - break; /* disable all active trip points */ - - if (flag == ACPI_TRIPS_INIT || ((flag & ACPI_TRIPS_ACTIVE) && - tz->trips.active[i].trip.valid)) { - status = acpi_evaluate_integer(tz->device->handle, - name, NULL, &tmp); - if (ACPI_FAILURE(status)) { - tz->trips.active[i].trip.valid = false; - if (i == 0) - break; - - if (act <= 0) - break; - - if (i == 1) - tz->trips.active[0].trip.temperature = - celsius_to_deci_kelvin(act); - else - /* - * Don't allow override higher than - * the next higher trip point - */ - tz->trips.active[i-1].trip.temperature = - min_t(unsigned long, - tz->trips.active[i-2].trip.temperature, - celsius_to_deci_kelvin(act)); - - break; - } else { - tz->trips.active[i].trip.temperature = tmp; - tz->trips.active[i].trip.valid = true; - } - } - - name[2] = 'L'; - if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].trip.valid) { - memset(&devices, 0, sizeof(struct acpi_handle_list)); - status = acpi_evaluate_reference(tz->device->handle, - name, NULL, &devices); - if (ACPI_FAILURE(status)) { - acpi_handle_info(tz->device->handle, - "Invalid active%d threshold\n", i); - tz->trips.active[i].trip.valid = false; - } else { - tz->trips.active[i].trip.valid = true; - } - - if (memcmp(&tz->trips.active[i].devices, &devices, - sizeof(struct acpi_handle_list))) { - memcpy(&tz->trips.active[i].devices, &devices, - sizeof(struct acpi_handle_list)); - ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); - } - } - if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES)) - if (valid != tz->trips.active[i].trip.valid) - ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state"); - - if (!tz->trips.active[i].trip.valid) - break; - } - - if (flag & ACPI_TRIPS_DEVICES) { - memset(&devices, 0, sizeof(devices)); - status = acpi_evaluate_reference(tz->device->handle, "_TZD", - NULL, &devices); - if (ACPI_SUCCESS(status) && - memcmp(&tz->devices, &devices, sizeof(devices))) { - tz->devices = devices; - ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); - } - } -} - static void update_acpi_thermal_trip_temp(struct acpi_thermal_trip *acpi_trip, int temp) { @@ -338,6 +250,78 @@ static void acpi_thermal_update_passive_devices(struct acpi_thermal *tz) ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_PASSIVE, 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; + + if (!acpi_trip->valid) + return; + + update_acpi_thermal_trip_temp(acpi_trip, get_active_temp(tz, index)); + if (!acpi_trip->valid) + ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_ACTIVE, tz, "state"); +} + +static bool update_active_devices(struct acpi_thermal *tz, int index, bool compare) +{ + char method[] = { '_', 'A', 'L', '0' + index, '\0' }; + struct acpi_handle_list devices; + acpi_status status; + + 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, + "Missing device list for active threshold %d\n", + index); + return false; + } + + if (compare && memcmp(&tz->trips.active[index].devices, &devices, sizeof(devices))) + ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_ACTIVE, tz, "device"); + + memcpy(&tz->trips.active[index].devices, &devices, sizeof(devices)); + return true; +} + +static void acpi_thermal_update_active_devices(struct acpi_thermal *tz, int index) +{ + struct acpi_thermal_trip *acpi_trip = &tz->trips.active[index].trip; + + if (!acpi_trip->valid) + return; + + if (update_active_devices(tz, index, true)) + return; + + update_acpi_thermal_trip_temp(acpi_trip, THERMAL_TEMP_INVALID); + ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_ACTIVE, tz, "state"); +} + static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) { struct acpi_thermal_trip *acpi_trip = trip->priv; @@ -358,18 +342,18 @@ 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 flag; + int i; if (data == ACPI_THERMAL_NOTIFY_THRESHOLDS) { acpi_thermal_update_passive_trip(tz); - flag = ACPI_TRIPS_THRESHOLDS; + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) + acpi_thermal_update_active_trip(tz, i); } else { acpi_thermal_update_passive_devices(tz); - flag = ACPI_TRIPS_DEVICES; + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) + acpi_thermal_update_active_devices(tz, i); } - __acpi_thermal_trips_update(tz, flag); - for_each_thermal_trip(tz->thermal_zone, acpi_thermal_adjust_trip, tz); } @@ -498,6 +482,28 @@ fail: return false; } +static bool acpi_thermal_init_active_trip(struct acpi_thermal *tz, int index) +{ + long temp; + + if (act == -1) + goto fail; + + temp = get_active_temp(tz, index); + if (temp == THERMAL_TEMP_INVALID) + goto fail; + + if (!update_active_devices(tz, index, false)) + goto fail; + + update_acpi_thermal_trip_temp(&tz->trips.active[index].trip, temp); + return true; + +fail: + update_acpi_thermal_trip_temp(&tz->trips.active[index].trip, THERMAL_TEMP_INVALID); + return false; +} + static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) { unsigned int count = 0; @@ -506,11 +512,8 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) if (acpi_thermal_init_passive_trip(tz)) count++; - /* Active trip points (optional). */ - __acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); - for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - if (tz->trips.active[i].trip.valid) + if (acpi_thermal_init_active_trip(tz, i)) count++; else break; -- cgit From 4175a24f01eb4bfde7d57a9a3ea254649f440034 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 12 Sep 2023 20:46:02 +0200 Subject: ACPI: thermal: Drop redundant trip point flags Trip point flags previously used by the driver need not be used any more after the preceding changes, so drop them and adjust the code accordingly. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index a6599b19dba8..c5ff542bcbf3 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -43,14 +43,6 @@ #define ACPI_THERMAL_MAX_ACTIVE 10 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 -#define ACPI_TRIPS_PASSIVE BIT(0) -#define ACPI_TRIPS_ACTIVE BIT(1) -#define ACPI_TRIPS_DEVICES BIT(2) - -#define ACPI_TRIPS_THRESHOLDS (ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE) - -#define ACPI_TRIPS_INIT (ACPI_TRIPS_THRESHOLDS | ACPI_TRIPS_DEVICES) - /* * This exception is thrown out in two cases: * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid @@ -58,12 +50,11 @@ * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change. * We need to re-bind the cooling devices of a thermal zone when this occurs. */ -#define ACPI_THERMAL_TRIPS_EXCEPTION(flags, tz, str) \ +#define ACPI_THERMAL_TRIPS_EXCEPTION(tz, str) \ do { \ - if (flags != ACPI_TRIPS_INIT) \ - acpi_handle_info(tz->device->handle, \ - "ACPI thermal trip point %s changed\n" \ - "Please report to linux-acpi@vger.kernel.org\n", str); \ + acpi_handle_info(tz->device->handle, \ + "ACPI thermal trip point %s changed\n" \ + "Please report to linux-acpi@vger.kernel.org\n", str); \ } while (0) static int act; @@ -212,7 +203,7 @@ static void acpi_thermal_update_passive_trip(struct acpi_thermal *tz) update_acpi_thermal_trip_temp(acpi_trip, get_passive_temp(tz)); if (!acpi_trip->valid) - ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_PASSIVE, tz, "state"); + ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } static bool update_passive_devices(struct acpi_thermal *tz, bool compare) @@ -230,7 +221,7 @@ static bool update_passive_devices(struct acpi_thermal *tz, bool compare) } if (compare && memcmp(&tz->trips.passive.devices, &devices, sizeof(devices))) - ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_PASSIVE, tz, "device"); + ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); memcpy(&tz->trips.passive.devices, &devices, sizeof(devices)); return true; @@ -247,7 +238,7 @@ static void acpi_thermal_update_passive_devices(struct acpi_thermal *tz) return; update_acpi_thermal_trip_temp(acpi_trip, THERMAL_TEMP_INVALID); - ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_PASSIVE, tz, "state"); + ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } static long get_active_temp(struct acpi_thermal *tz, int index) @@ -282,7 +273,7 @@ static void acpi_thermal_update_active_trip(struct acpi_thermal *tz, int index) update_acpi_thermal_trip_temp(acpi_trip, get_active_temp(tz, index)); if (!acpi_trip->valid) - ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_ACTIVE, tz, "state"); + ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } static bool update_active_devices(struct acpi_thermal *tz, int index, bool compare) @@ -302,7 +293,7 @@ static bool update_active_devices(struct acpi_thermal *tz, int index, bool compa } if (compare && memcmp(&tz->trips.active[index].devices, &devices, sizeof(devices))) - ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_ACTIVE, tz, "device"); + ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); memcpy(&tz->trips.active[index].devices, &devices, sizeof(devices)); return true; @@ -319,7 +310,7 @@ static void acpi_thermal_update_active_devices(struct acpi_thermal *tz, int inde return; update_acpi_thermal_trip_temp(acpi_trip, THERMAL_TEMP_INVALID); - ACPI_THERMAL_TRIPS_EXCEPTION(ACPI_TRIPS_ACTIVE, tz, "state"); + ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) -- cgit From 058f5e407deb8d21b0a04e50e8efbd25b1fcbd1b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 20 Sep 2023 15:03:46 +0200 Subject: ACPI: thermal: Drop valid flag from struct acpi_thermal_trip Notice that the valid flag in struct acpi_thermal_trip is in fact redundant, because the temperature field of invalid trips is always equal to THERMAL_TEMP_INVALID, so drop it from there and adjust the code accordingly. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index c5ff542bcbf3..10720a038846 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -81,7 +81,6 @@ static struct workqueue_struct *acpi_thermal_pm_queue; struct acpi_thermal_trip { unsigned long temperature; - bool valid; }; struct acpi_thermal_passive { @@ -175,11 +174,9 @@ static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k) tz->kelvin_offset); } -static void update_acpi_thermal_trip_temp(struct acpi_thermal_trip *acpi_trip, - int temp) +static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip) { - acpi_trip->valid = temp != THERMAL_TEMP_INVALID; - acpi_trip->temperature = temp; + return acpi_trip->temperature != THERMAL_TEMP_INVALID; } static long get_passive_temp(struct acpi_thermal *tz) @@ -198,11 +195,11 @@ static void acpi_thermal_update_passive_trip(struct acpi_thermal *tz) { struct acpi_thermal_trip *acpi_trip = &tz->trips.passive.trip; - if (!acpi_trip->valid || psv > 0) + if (!acpi_thermal_trip_valid(acpi_trip) || psv > 0) return; - update_acpi_thermal_trip_temp(acpi_trip, get_passive_temp(tz)); - if (!acpi_trip->valid) + acpi_trip->temperature = get_passive_temp(tz); + if (!acpi_thermal_trip_valid(acpi_trip)) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } @@ -231,13 +228,13 @@ static void acpi_thermal_update_passive_devices(struct acpi_thermal *tz) { struct acpi_thermal_trip *acpi_trip = &tz->trips.passive.trip; - if (!acpi_trip->valid) + if (!acpi_thermal_trip_valid(acpi_trip)) return; if (update_passive_devices(tz, true)) return; - update_acpi_thermal_trip_temp(acpi_trip, THERMAL_TEMP_INVALID); + acpi_trip->temperature = THERMAL_TEMP_INVALID; ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } @@ -268,11 +265,11 @@ 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_trip->valid) + if (!acpi_thermal_trip_valid(acpi_trip)) return; - update_acpi_thermal_trip_temp(acpi_trip, get_active_temp(tz, index)); - if (!acpi_trip->valid) + acpi_trip->temperature = get_active_temp(tz, index); + if (!acpi_thermal_trip_valid(acpi_trip)) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } @@ -303,13 +300,13 @@ static void acpi_thermal_update_active_devices(struct acpi_thermal *tz, int inde { struct acpi_thermal_trip *acpi_trip = &tz->trips.active[index].trip; - if (!acpi_trip->valid) + if (!acpi_thermal_trip_valid(acpi_trip)) return; if (update_active_devices(tz, index, true)) return; - update_acpi_thermal_trip_temp(acpi_trip, THERMAL_TEMP_INVALID); + acpi_trip->temperature = THERMAL_TEMP_INVALID; ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } @@ -321,7 +318,7 @@ static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) if (!acpi_trip) return 0; - if (acpi_trip->valid) + if (acpi_thermal_trip_valid(acpi_trip)) trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); else trip->temperature = THERMAL_TEMP_INVALID; @@ -465,11 +462,11 @@ static bool acpi_thermal_init_passive_trip(struct acpi_thermal *tz) if (!update_passive_devices(tz, false)) goto fail; - update_acpi_thermal_trip_temp(&tz->trips.passive.trip, temp); + tz->trips.passive.trip.temperature = temp; return true; fail: - update_acpi_thermal_trip_temp(&tz->trips.passive.trip, THERMAL_TEMP_INVALID); + tz->trips.passive.trip.temperature = THERMAL_TEMP_INVALID; return false; } @@ -487,11 +484,11 @@ static bool acpi_thermal_init_active_trip(struct acpi_thermal *tz, int index) if (!update_active_devices(tz, index, false)) goto fail; - update_acpi_thermal_trip_temp(&tz->trips.active[index].trip, temp); + tz->trips.active[index].trip.temperature = temp; return true; fail: - update_acpi_thermal_trip_temp(&tz->trips.active[index].trip, THERMAL_TEMP_INVALID); + tz->trips.active[index].trip.temperature = THERMAL_TEMP_INVALID; return false; } @@ -545,7 +542,7 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, return -EINVAL; acpi_trip = trip->priv; - if (!acpi_trip || !acpi_trip->valid) + if (!acpi_trip || !acpi_thermal_trip_valid(acpi_trip)) return -EINVAL; switch (trip->type) { @@ -618,7 +615,7 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, if (tz->trips.hot_valid) trip++; - if (tz->trips.passive.trip.valid) { + if (acpi_thermal_trip_valid(&tz->trips.passive.trip)) { trip++; for (i = 0; i < tz->trips.passive.devices.count; i++) { handle = tz->trips.passive.devices.handles[i]; @@ -643,7 +640,7 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, } for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - if (!tz->trips.active[i].trip.valid) + if (!acpi_thermal_trip_valid(&tz->trips.active[i].trip)) break; trip++; @@ -949,7 +946,7 @@ static int acpi_thermal_add(struct acpi_device *device) } acpi_trip = &tz->trips.passive.trip; - if (acpi_trip->valid) { + if (acpi_thermal_trip_valid(acpi_trip)) { passive_delay = tz->trips.passive.tsp * 100; trip->type = THERMAL_TRIP_PASSIVE; @@ -961,7 +958,7 @@ static int acpi_thermal_add(struct acpi_device *device) for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { acpi_trip = &tz->trips.active[i].trip; - if (!acpi_trip->valid) + if (!acpi_thermal_trip_valid(acpi_trip)) break; trip->type = THERMAL_TRIP_ACTIVE; @@ -1038,7 +1035,7 @@ static int acpi_thermal_resume(struct device *dev) return -EINVAL; for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - if (!tz->trips.active[i].trip.valid) + if (!acpi_thermal_trip_valid(&tz->trips.active[i].trip)) break; for (j = 0; j < tz->trips.active[i].devices.count; j++) { -- cgit From 0d9741abd1c583e7bedb178358a9abd0981f49ba Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 27 Sep 2023 15:37:26 +0300 Subject: ACPI: thermal: Fix a small leak in acpi_thermal_add() Free "tz" if the "trip" allocation fails. Fixes: 5fc2189f9335 ("ACPI: thermal: Create and populate trip points table earlier") Signed-off-by: Dan Carpenter Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 10720a038846..f8a95939c88d 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -928,8 +928,10 @@ static int acpi_thermal_add(struct acpi_device *device) acpi_thermal_guess_offset(tz, crit_temp); trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); - if (!trip) - return -ENOMEM; + if (!trip) { + result = -ENOMEM; + goto free_memory; + } tz->trip_table = trip; -- cgit From 0fa1bf34980eba19a5f07f97297bbd60b796e6d1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 19:48:33 +0200 Subject: ACPI: thermal: Add device list to struct acpi_thermal_trip The device lists present in struct acpi_thermal_passive and struct acpi_thermal_active can be located in struct acpi_thermal_trip which then will allow the same code to be used for handling both the passive and active trip points, so make that change. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index f8a95939c88d..4248669eb228 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -81,11 +81,11 @@ static struct workqueue_struct *acpi_thermal_pm_queue; struct acpi_thermal_trip { unsigned long temperature; + struct acpi_handle_list devices; }; struct acpi_thermal_passive { struct acpi_thermal_trip trip; - struct acpi_handle_list devices; unsigned long tc1; unsigned long tc2; unsigned long tsp; @@ -93,7 +93,6 @@ struct acpi_thermal_passive { struct acpi_thermal_active { struct acpi_thermal_trip trip; - struct acpi_handle_list devices; }; struct acpi_thermal_trips { @@ -205,6 +204,7 @@ static void acpi_thermal_update_passive_trip(struct acpi_thermal *tz) static bool update_passive_devices(struct acpi_thermal *tz, bool compare) { + struct acpi_thermal_trip *acpi_trip = &tz->trips.passive.trip; struct acpi_handle_list devices; acpi_status status; @@ -217,10 +217,10 @@ static bool update_passive_devices(struct acpi_thermal *tz, bool compare) return false; } - if (compare && memcmp(&tz->trips.passive.devices, &devices, sizeof(devices))) + if (compare && memcmp(&acpi_trip->devices, &devices, sizeof(devices))) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); - memcpy(&tz->trips.passive.devices, &devices, sizeof(devices)); + memcpy(&acpi_trip->devices, &devices, sizeof(devices)); return true; } @@ -276,6 +276,7 @@ static void acpi_thermal_update_active_trip(struct acpi_thermal *tz, int index) static bool update_active_devices(struct acpi_thermal *tz, int index, bool compare) { char method[] = { '_', 'A', 'L', '0' + index, '\0' }; + struct acpi_thermal_trip *acpi_trip = &tz->trips.active[index].trip; struct acpi_handle_list devices; acpi_status status; @@ -289,10 +290,10 @@ static bool update_active_devices(struct acpi_thermal *tz, int index, bool compa return false; } - if (compare && memcmp(&tz->trips.active[index].devices, &devices, sizeof(devices))) + if (compare && memcmp(&acpi_trip->devices, &devices, sizeof(devices))) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); - memcpy(&tz->trips.active[index].devices, &devices, sizeof(devices)); + memcpy(&acpi_trip->devices, &devices, sizeof(devices)); return true; } @@ -602,6 +603,7 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, { 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; int i; @@ -615,10 +617,11 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, if (tz->trips.hot_valid) trip++; - if (acpi_thermal_trip_valid(&tz->trips.passive.trip)) { + acpi_trip = &tz->trips.passive.trip; + if (acpi_thermal_trip_valid(acpi_trip)) { trip++; - for (i = 0; i < tz->trips.passive.devices.count; i++) { - handle = tz->trips.passive.devices.handles[i]; + 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; @@ -640,12 +643,13 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, } for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - if (!acpi_thermal_trip_valid(&tz->trips.active[i].trip)) + acpi_trip = &tz->trips.active[i].trip; + if (!acpi_thermal_trip_valid(acpi_trip)) break; trip++; - for (j = 0; j < tz->trips.active[i].devices.count; j++) { - handle = tz->trips.active[i].devices.handles[j]; + 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; @@ -1037,11 +1041,13 @@ static int acpi_thermal_resume(struct device *dev) return -EINVAL; for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - if (!acpi_thermal_trip_valid(&tz->trips.active[i].trip)) + struct acpi_thermal_trip *acpi_trip = &tz->trips.active[i].trip; + + if (!acpi_thermal_trip_valid(acpi_trip)) break; - for (j = 0; j < tz->trips.active[i].devices.count; j++) { - acpi_bus_update_power(tz->trips.active[i].devices.handles[j], + for (j = 0; j < acpi_trip->devices.count; j++) { + acpi_bus_update_power(acpi_trip->devices.handles[j], &power_state); } } -- cgit From 317508c65f1f966367553ef84f5d8eba16720f32 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 19:49:24 +0200 Subject: ACPI: thermal: Collapse trip devices update functions In order to reduce code duplication, merge update_passive_devices() and update_active_devices() into one function called update_trip_devices() that will be used for updating both the passive and active trip points. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 53 +++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 4248669eb228..93d2ab552686 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -43,6 +43,8 @@ #define ACPI_THERMAL_MAX_ACTIVE 10 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 +#define ACPI_THERMAL_TRIP_PASSIVE (-1) + /* * This exception is thrown out in two cases: * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid @@ -202,18 +204,25 @@ static void acpi_thermal_update_passive_trip(struct acpi_thermal *tz) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } -static bool update_passive_devices(struct acpi_thermal *tz, bool compare) +static bool update_trip_devices(struct acpi_thermal *tz, + struct acpi_thermal_trip *acpi_trip, + int index, bool compare) { - struct acpi_thermal_trip *acpi_trip = &tz->trips.passive.trip; struct acpi_handle_list devices; + char method[] = "_PSL"; acpi_status status; + if (index != ACPI_THERMAL_TRIP_PASSIVE) { + method[1] = 'A'; + method[2] = 'L'; + method[3] = '0' + index; + } + memset(&devices, 0, sizeof(devices)); - status = acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, &devices); + status = acpi_evaluate_reference(tz->device->handle, method, NULL, &devices); if (ACPI_FAILURE(status)) { - acpi_handle_info(tz->device->handle, - "Missing device list for passive threshold\n"); + acpi_handle_info(tz->device->handle, "%s evaluation failure\n", method); return false; } @@ -231,8 +240,9 @@ static void acpi_thermal_update_passive_devices(struct acpi_thermal *tz) if (!acpi_thermal_trip_valid(acpi_trip)) return; - if (update_passive_devices(tz, true)) + if (update_trip_devices(tz, acpi_trip, ACPI_THERMAL_TRIP_PASSIVE, true)) { return; + } acpi_trip->temperature = THERMAL_TEMP_INVALID; ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); @@ -273,30 +283,6 @@ static void acpi_thermal_update_active_trip(struct acpi_thermal *tz, int index) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } -static bool update_active_devices(struct acpi_thermal *tz, int index, bool compare) -{ - char method[] = { '_', 'A', 'L', '0' + index, '\0' }; - struct acpi_thermal_trip *acpi_trip = &tz->trips.active[index].trip; - struct acpi_handle_list devices; - acpi_status status; - - 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, - "Missing device list for active threshold %d\n", - index); - return false; - } - - if (compare && memcmp(&acpi_trip->devices, &devices, sizeof(devices))) - ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); - - memcpy(&acpi_trip->devices, &devices, sizeof(devices)); - return true; -} - static void acpi_thermal_update_active_devices(struct acpi_thermal *tz, int index) { struct acpi_thermal_trip *acpi_trip = &tz->trips.active[index].trip; @@ -304,7 +290,7 @@ static void acpi_thermal_update_active_devices(struct acpi_thermal *tz, int inde if (!acpi_thermal_trip_valid(acpi_trip)) return; - if (update_active_devices(tz, index, true)) + if (update_trip_devices(tz, acpi_trip, index, true)) return; acpi_trip->temperature = THERMAL_TEMP_INVALID; @@ -460,7 +446,8 @@ static bool acpi_thermal_init_passive_trip(struct acpi_thermal *tz) tz->trips.passive.tsp = tmp; - if (!update_passive_devices(tz, false)) + if (!update_trip_devices(tz, &tz->trips.passive.trip, + ACPI_THERMAL_TRIP_PASSIVE, false)) goto fail; tz->trips.passive.trip.temperature = temp; @@ -482,7 +469,7 @@ static bool acpi_thermal_init_active_trip(struct acpi_thermal *tz, int index) if (temp == THERMAL_TEMP_INVALID) goto fail; - if (!update_active_devices(tz, index, false)) + if (!update_trip_devices(tz, &tz->trips.active[index].trip, index, false)) goto fail; tz->trips.active[index].trip.temperature = temp; -- cgit From 54fc61a106c9b7fb55a3c6a595349826c0548468 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 19:50:08 +0200 Subject: ACPI: thermal: Collapse trip devices update function wrappers In order to reduce code duplicationeve further, merge acpi_thermal_update_passive/active_devices() into one function called acpi_thermal_update_trip_devices() that will be used for updating both the passive and active trip points. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 93d2ab552686..ebe11288d7e0 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -233,14 +233,16 @@ static bool update_trip_devices(struct acpi_thermal *tz, return true; } -static void acpi_thermal_update_passive_devices(struct acpi_thermal *tz) +static void acpi_thermal_update_trip_devices(struct acpi_thermal *tz, int index) { - struct acpi_thermal_trip *acpi_trip = &tz->trips.passive.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; - if (update_trip_devices(tz, acpi_trip, ACPI_THERMAL_TRIP_PASSIVE, true)) { + if (update_trip_devices(tz, acpi_trip, index, true)) { return; } @@ -283,20 +285,6 @@ static void acpi_thermal_update_active_trip(struct acpi_thermal *tz, int index) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); } -static void acpi_thermal_update_active_devices(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; - - if (update_trip_devices(tz, acpi_trip, index, true)) - return; - - acpi_trip->temperature = THERMAL_TEMP_INVALID; - 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; @@ -324,9 +312,9 @@ static void acpi_thermal_adjust_thermal_zone(struct thermal_zone_device *thermal for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) acpi_thermal_update_active_trip(tz, i); } else { - acpi_thermal_update_passive_devices(tz); + acpi_thermal_update_trip_devices(tz, ACPI_THERMAL_TRIP_PASSIVE); for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) - acpi_thermal_update_active_devices(tz, i); + acpi_thermal_update_trip_devices(tz, i); } for_each_thermal_trip(tz->thermal_zone, acpi_thermal_adjust_trip, tz); -- cgit From 3e7d6f396d74a3e40c390bb53947938957426097 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 19:51:19 +0200 Subject: ACPI: thermal: Merge trip initialization functions In order to reduce code duplicationeve further, merge acpi_thermal_init_passive/active_trip() into one function called acpi_thermal_init_trip() that will be used for initializing both the passive and active trip points. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Daniel Lezcano --- drivers/acpi/thermal.c | 64 +++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index ebe11288d7e0..c303688ead71 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -399,72 +399,68 @@ static long acpi_thermal_get_hot_trip(struct acpi_thermal *tz) return tmp; } -static bool acpi_thermal_init_passive_trip(struct acpi_thermal *tz) +static bool passive_trip_params_init(struct acpi_thermal *tz) { unsigned long long tmp; acpi_status status; - int temp; - - if (psv == -1) - goto fail; - - if (psv > 0) { - temp = celsius_to_deci_kelvin(psv); - } else { - temp = get_passive_temp(tz); - if (temp == THERMAL_TEMP_INVALID) - goto fail; - } status = acpi_evaluate_integer(tz->device->handle, "_TC1", NULL, &tmp); if (ACPI_FAILURE(status)) - goto fail; + return false; tz->trips.passive.tc1 = tmp; status = acpi_evaluate_integer(tz->device->handle, "_TC2", NULL, &tmp); if (ACPI_FAILURE(status)) - goto fail; + return false; tz->trips.passive.tc2 = tmp; status = acpi_evaluate_integer(tz->device->handle, "_TSP", NULL, &tmp); if (ACPI_FAILURE(status)) - goto fail; + return false; tz->trips.passive.tsp = tmp; - if (!update_trip_devices(tz, &tz->trips.passive.trip, - ACPI_THERMAL_TRIP_PASSIVE, false)) - goto fail; - - tz->trips.passive.trip.temperature = temp; return true; - -fail: - tz->trips.passive.trip.temperature = THERMAL_TEMP_INVALID; - return false; } -static bool acpi_thermal_init_active_trip(struct acpi_thermal *tz, int index) +static bool acpi_thermal_init_trip(struct acpi_thermal *tz, int index) { + struct acpi_thermal_trip *acpi_trip; long temp; - if (act == -1) - goto fail; + if (index == ACPI_THERMAL_TRIP_PASSIVE) { + acpi_trip = &tz->trips.passive.trip; + + if (psv == -1) + goto fail; + + if (!passive_trip_params_init(tz)) + goto fail; + + temp = psv > 0 ? celsius_to_deci_kelvin(psv) : + get_passive_temp(tz); + } else { + acpi_trip = &tz->trips.active[index].trip; + + if (act == -1) + goto fail; + + temp = get_active_temp(tz, index); + } - temp = get_active_temp(tz, index); if (temp == THERMAL_TEMP_INVALID) goto fail; - if (!update_trip_devices(tz, &tz->trips.active[index].trip, index, false)) + if (!update_trip_devices(tz, acpi_trip, index, false)) goto fail; - tz->trips.active[index].trip.temperature = temp; + acpi_trip->temperature = temp; return true; fail: - tz->trips.active[index].trip.temperature = THERMAL_TEMP_INVALID; + acpi_trip->temperature = THERMAL_TEMP_INVALID; return false; } @@ -473,11 +469,11 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) unsigned int count = 0; int i; - if (acpi_thermal_init_passive_trip(tz)) + if (acpi_thermal_init_trip(tz, ACPI_THERMAL_TRIP_PASSIVE)) count++; for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - if (acpi_thermal_init_active_trip(tz, i)) + if (acpi_thermal_init_trip(tz, i)) count++; else break; -- cgit From 2713b83cb3b0ca78dc16a6968d58bee1342c4bc7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 28 Sep 2023 17:45:59 +0200 Subject: ACPI: thermal: Mark uninitialized active trips as invalid After removing the valid flag from struct acpi_thermal_trip, the trip temperature value is used in validity checks, so it must be THERMAL_TEMP_INVALID for the active trip entries in struct acpi_thermal_trips that are not going to be used (because the corresponding objects are not present in the ACPI tables, for example). Accordingly, modify acpi_thermal_get_trip_points() to set the temperature value to THERMAL_TEMP_INVALID for trip point entries skipped by it after acpi_thermal_init_trip() has returned 'false' for an active trip. Fixes: 058f5e407deb ("ACPI: thermal: Drop valid flag from struct acpi_thermal_trip") Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index c303688ead71..0c3160c04d65 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -480,6 +480,9 @@ 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; + return count; } -- cgit From d5ea889246b112e228433a5f27f57af90ca0c1fb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 20:02:59 +0200 Subject: ACPI: thermal: Do not use trip indices for cooling device binding 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 --- 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 0c3160c04d65..03cc42064467 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -571,94 +571,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 = { -- cgit From c8f46f43a1db7a9a46cd9313aa434380238e874f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 20:04:49 +0200 Subject: ACPI: thermal: Drop critical_valid and hot_valid trip flags 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 --- 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 03cc42064467..95464e578ac9 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; } @@ -792,7 +783,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; @@ -853,11 +844,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) { @@ -891,13 +882,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++; -- cgit From 03a6d5986c9dea51f05c66a5f2fee6a15e498160 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Sep 2023 20:06:58 +0200 Subject: ACPI: thermal: Rename structure fields holding temperature in deci-Kelvin 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 --- 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 95464e578ac9..d3d6429b98c5 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; @@ -447,11 +447,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; } @@ -472,7 +472,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; } @@ -491,7 +491,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; } @@ -513,10 +513,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) @@ -527,7 +527,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; @@ -899,7 +899,7 @@ static int acpi_thermal_add(struct acpi_device *device) passive_delay = tz->trips.passive.tsp * 100; 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++; } @@ -911,7 +911,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++; } @@ -925,7 +925,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); -- cgit From c6767334185e50121b66eae9f882d2832d2d2ad1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 28 Sep 2023 20:47:31 +0200 Subject: ACPI: thermal: Drop list of device ACPI handles from struct acpi_thermal 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 --- drivers/acpi/thermal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index d3d6429b98c5..17bcf4185fef 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; -- cgit From 1dd72ce0c125110033e65051c9f8b2676e425cfd Mon Sep 17 00:00:00 2001 From: Jonathan Bergh Date: Fri, 29 Sep 2023 00:13:44 +0200 Subject: ACPI: thermal: Fix up function header formatting in two places Fix up the following formatting issues: * braces following function declarations should be on a new line * empty line should be present between function declarations Signed-off-by: Jonathan Bergh [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 17bcf4185fef..c01ba4ad8009 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -1021,7 +1021,8 @@ static struct acpi_driver acpi_thermal_driver = { .drv.pm = &acpi_thermal_pm, }; -static int thermal_act(const struct dmi_system_id *d) { +static int thermal_act(const struct dmi_system_id *d) +{ if (act == 0) { pr_notice("%s detected: disabling all active thermal trip points\n", d->ident); @@ -1029,13 +1030,17 @@ static int thermal_act(const struct dmi_system_id *d) { } return 0; } -static int thermal_nocrt(const struct dmi_system_id *d) { + +static int thermal_nocrt(const struct dmi_system_id *d) +{ pr_notice("%s detected: disabling all critical thermal trip point actions.\n", d->ident); crt = -1; return 0; } -static int thermal_tzp(const struct dmi_system_id *d) { + +static int thermal_tzp(const struct dmi_system_id *d) +{ if (tzp == 0) { pr_notice("%s detected: enabling thermal zone polling\n", d->ident); @@ -1043,7 +1048,9 @@ static int thermal_tzp(const struct dmi_system_id *d) { } return 0; } -static int thermal_psv(const struct dmi_system_id *d) { + +static int thermal_psv(const struct dmi_system_id *d) +{ if (psv == 0) { pr_notice("%s detected: disabling all passive thermal trip points\n", d->ident); -- cgit From 44babd829a7e0c13b57040fc8234f64fabab1efd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:18:31 +0200 Subject: ACPI: thermal: Move get_active_temp() 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 --- 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 c01ba4ad8009..71a1ca18c97c 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; @@ -247,29 +270,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; -- cgit From 4f9cf91e4102fe77ef3393febab72612b594172f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:21:30 +0200 Subject: ACPI: thermal: Combine passive and active trip update functions 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 --- 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 71a1ca18c97c..d527db0f1144 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"); } @@ -270,18 +281,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; @@ -305,9 +304,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++) -- cgit From b251ab28caeb5a4a63d832dcd53d29ad2dd5318f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:24:12 +0200 Subject: ACPI: thermal: Use thermal_zone_for_each_trip() for updating trips 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 --- 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 d527db0f1144..fb9da37a79d8 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); } @@ -264,31 +270,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 @@ -297,25 +311,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)) @@ -324,17 +319,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); -- cgit From 4963e34ce7b95237021575d208fa576f88697839 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Oct 2023 15:25:33 +0200 Subject: thermal: core: Drop thermal_zone_device_exec() 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 --- 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 45d0aa0b69b7..8ee22eb804d3 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -495,25 +495,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 2bab72149bbf..c8600e313909 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -339,10 +339,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 *); -- cgit From b44444027ce7714f309e96b804b7fb088a40d708 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 7 Oct 2023 13:29:22 +0200 Subject: thermal: trip: Remove lockdep assertion from for_each_thermal_trip() 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 --- 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 8c649a899537..9f10e2ff9248 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) -- cgit From 108ffd12be24ba1d74b3314df8db32a0a6d55ba5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 11 Oct 2023 17:45:42 +0200 Subject: thermal: trip: Drop lockdep assertion from thermal_zone_trip_id() The lockdep assertion in thermal_zone_trip_id() triggers when the trip point sysfs attribute of a thermal instance is read, because there is no thermal zone locking in that code path. This is not verly useful, though, because there is no mechanism by which the location of the trips[] table in a thermal zone or its size can change after binding cooling devices to the trips in that thermal zone and before those cooling devices are unbound from them. Thus it is not in fact necessary to hold the thermal zone lock when thermal_zone_trip_id() is called from trip_point_show() and so the lockdep asserion in the former is invalid. Accordingly, drop that lockdep assertion. Fixes: 2c7b4bfadef0 ("thermal: core: Store trip pointer in struct thermal_instance") Signed-off-by: Rafael J. Wysocki --- 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 9f10e2ff9248..80f3cdb2f30e 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -175,8 +175,6 @@ int thermal_zone_trip_id(struct thermal_zone_device *tz, { int i; - lockdep_assert_held(&tz->lock); - for (i = 0; i < tz->num_trips; i++) { if (&tz->trips[i] == trip) return i; -- cgit