diff options
author | Vicki Pfau <vi@endrift.com> | 2023-02-21 19:38:03 -0800 |
---|---|---|
committer | Cristian Ciocaltea <cristian.ciocaltea@collabora.com> | 2023-09-11 23:46:39 +0300 |
commit | 79c8690d0153a6ef2eea461a92c903efd22b6786 (patch) | |
tree | 452b968f9aa1f17d000eea921e04c2a24267709a | |
parent | 87e2a7e2c8b2f120b56ec46a263d7cd6ca6a252e (diff) | |
download | linux-79c8690d0153a6ef2eea461a92c903efd22b6786.tar.gz |
ACPI: utils: Make acpi_handle_list dynamically allocated
This fixes a long-standing "TBD" comment in the ACPI headers regarding making the acpi_handle_list struct's size dynamic. The number 10, which along with the comment dates back to 2.4.23, seems like it may have been arbitrarily chosen, and isn't sufficient in all cases. This patch finally makes the size dynamic and updates its users to handle the modified API. Signed-off-by: Vicki Pfau <vi@endrift.com> (cherry picked from commit e4efc98ccb538204b344c64a419a601e3f50e79e) Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-rw-r--r-- | drivers/acpi/acpi_lpss.c | 5 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 1 | ||||
-rw-r--r-- | drivers/acpi/thermal.c | 23 | ||||
-rw-r--r-- | drivers/acpi/utils.c | 5 | ||||
-rw-r--r-- | drivers/platform/surface/surface_acpi_notify.c | 5 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 4 |
6 files changed, 30 insertions, 13 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index f08ffa75f4a7..d36dbb6564e2 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -576,10 +576,13 @@ static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle) } for (i = 0; i < dep_devices.count; i++) { - if (dep_devices.handles[i] == handle) + if (dep_devices.handles[i] == handle) { + kfree(dep_devices.handles); return true; + } } + kfree(dep_devices.handles); return false; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index b47e93a24a9a..d35e9c104c1f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2023,6 +2023,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep) mutex_unlock(&acpi_dep_list_lock); } + kfree(dep_devices.handles); return count; } diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 40b07057983e..601535384f89 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -379,8 +379,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) tz->trips.passive.flags.valid = 1; } - if (memcmp(&tz->trips.passive.devices, &devices, - sizeof(struct acpi_handle_list))) { + if (tz->trips.passive.devices.count != devices.count || + memcmp(tz->trips.passive.devices.handles, + devices.handles, sizeof(acpi_handle) * devices.count)) { + kfree(tz->trips.passive.devices.handles); memcpy(&tz->trips.passive.devices, &devices, sizeof(struct acpi_handle_list)); ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); @@ -444,8 +446,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) tz->trips.active[i].flags.valid = 1; } - if (memcmp(&tz->trips.active[i].devices, &devices, - sizeof(struct acpi_handle_list))) { + if (tz->trips.active[i].devices.count != devices.count || + memcmp(tz->trips.active[i].devices.handles, + devices.handles, sizeof(acpi_handle) * devices.count)) { + kfree(tz->trips.active[i].devices.handles); memcpy(&tz->trips.active[i].devices, &devices, sizeof(struct acpi_handle_list)); ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); @@ -463,8 +467,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) 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))) { + if (ACPI_SUCCESS(status) && (tz->devices.count != devices.count || + memcmp(tz->devices.handles, devices.handles, + sizeof(acpi_handle) * devices.count))) { + kfree(tz->devices.handles); tz->devices = devices; ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); } @@ -1062,6 +1068,7 @@ end: static int acpi_thermal_remove(struct acpi_device *device) { struct acpi_thermal *tz; + int i; if (!device || !acpi_driver_data(device)) return -EINVAL; @@ -1070,6 +1077,10 @@ static int acpi_thermal_remove(struct acpi_device *device) tz = acpi_driver_data(device); acpi_thermal_unregister_thermal_zone(tz); + kfree(tz->trips.passive.devices.handles); + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) + kfree(tz->trips.active[i].devices.handles); + kfree(tz->devices.handles); kfree(tz); return 0; } diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 2ea14648a661..96f821c41756 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -370,7 +370,8 @@ acpi_evaluate_reference(acpi_handle handle, goto end; } - if (package->package.count > ACPI_MAX_HANDLES) { + list->handles = kcalloc(package->package.count, sizeof(*list->handles), GFP_KERNEL); + if (!list->handles) { kfree(package); return AE_NO_MEMORY; } @@ -402,7 +403,7 @@ acpi_evaluate_reference(acpi_handle handle, end: if (ACPI_FAILURE(status)) { list->count = 0; - //kfree(list->handles); + kfree(list->handles); } kfree(buffer.pointer); diff --git a/drivers/platform/surface/surface_acpi_notify.c b/drivers/platform/surface/surface_acpi_notify.c index 50500e562963..e3c7fe93100a 100644 --- a/drivers/platform/surface/surface_acpi_notify.c +++ b/drivers/platform/surface/surface_acpi_notify.c @@ -753,10 +753,13 @@ static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle) } for (i = 0; i < dep_devices.count; i++) { - if (dep_devices.handles[i] == supplier) + if (dep_devices.handles[i] == supplier) { + kfree(dep_devices.handles); return true; + } } + kfree(dep_devices.handles); return false; } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c09d72986968..647f41abc324 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -12,11 +12,9 @@ #include <linux/device.h> #include <linux/property.h> -/* TBD: Make dynamic */ -#define ACPI_MAX_HANDLES 10 struct acpi_handle_list { u32 count; - acpi_handle handles[ACPI_MAX_HANDLES]; + acpi_handle* handles; }; /* acpi_utils.h */ |