summary refs log tree commit diff
diff options
context:
space:
mode:
authorVicki Pfau <vi@endrift.com>2023-02-21 19:38:03 -0800
committerCristian Ciocaltea <cristian.ciocaltea@collabora.com>2023-09-11 23:46:39 +0300
commit79c8690d0153a6ef2eea461a92c903efd22b6786 (patch)
tree452b968f9aa1f17d000eea921e04c2a24267709a
parent87e2a7e2c8b2f120b56ec46a263d7cd6ca6a252e (diff)
downloadlinux-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.c5
-rw-r--r--drivers/acpi/scan.c1
-rw-r--r--drivers/acpi/thermal.c23
-rw-r--r--drivers/acpi/utils.c5
-rw-r--r--drivers/platform/surface/surface_acpi_notify.c5
-rw-r--r--include/acpi/acpi_bus.h4
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 */