ACPI: scan: Add acpi_dev_get_next_consumer_dev()
authorDaniel Scally <djrscally@gmail.com>
Wed, 21 Sep 2022 23:04:35 +0000 (00:04 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 24 Sep 2022 17:12:32 +0000 (19:12 +0200)
In commit b83e2b306736 ("ACPI: scan: Add function to fetch dependent
of ACPI device") we added a means of fetching the first device to
declare itself dependent on another ACPI device in the _DEP method.
One assumption in that patch was that there would only be a single
consuming device, but this has not held.

Replace that function with a new function that fetches the next consumer
of a supplier device. Where no "previous" consumer is passed in, it
behaves identically to the original function.

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Daniel Scally <djrscally@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/scan.c
drivers/platform/x86/intel/int3472/common.c
include/acpi/acpi_bus.h

index f6b9ea937de1bea402d7c5bfbf093d2ee08c3645..d0277427e7ee1785baaed69d46deb3b4f20341af 100644 (file)
@@ -2235,9 +2235,22 @@ ok:
        return 0;
 }
 
-static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
+static int acpi_dev_get_next_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
 {
-       struct acpi_device *adev;
+       struct acpi_device **adev_p = data;
+       struct acpi_device *adev = *adev_p;
+
+       /*
+        * If we're passed a 'previous' consumer device then we need to skip
+        * any consumers until we meet the previous one, and then NULL @data
+        * so the next one can be returned.
+        */
+       if (adev) {
+               if (dep->consumer == adev->handle)
+                       *adev_p = NULL;
+
+               return 0;
+       }
 
        adev = acpi_get_acpi_dev(dep->consumer);
        if (adev) {
@@ -2368,25 +2381,32 @@ bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
 EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
 
 /**
- * acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
+ * acpi_dev_get_next_consumer_dev - Return the next adev dependent on @supplier
  * @supplier: Pointer to the dependee device
+ * @start: Pointer to the current dependent device
  *
- * Returns the first &struct acpi_device which declares itself dependent on
+ * Returns the next &struct acpi_device which declares itself dependent on
  * @supplier via the _DEP buffer, parsed from the acpi_dep_list.
  *
- * The caller is responsible for putting the reference to adev when it is no
- * longer needed.
+ * If the returned adev is not passed as @start to this function, the caller is
+ * responsible for putting the reference to adev when it is no longer needed.
  */
-struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier)
+struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier,
+                                                  struct acpi_device *start)
 {
-       struct acpi_device *adev = NULL;
+       struct acpi_device *adev = start;
 
        acpi_walk_dep_device_list(supplier->handle,
-                                 acpi_dev_get_first_consumer_dev_cb, &adev);
+                                 acpi_dev_get_next_consumer_dev_cb, &adev);
+
+       acpi_dev_put(start);
+
+       if (adev == start)
+               return NULL;
 
        return adev;
 }
-EXPORT_SYMBOL_GPL(acpi_dev_get_first_consumer_dev);
+EXPORT_SYMBOL_GPL(acpi_dev_get_next_consumer_dev);
 
 /**
  * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
index 77cf058e4168f6894cf7e690203967cf9d426e8f..9db2bb0bbba4bd90c1d8d46348ad47e1b2626184 100644 (file)
@@ -62,7 +62,7 @@ int skl_int3472_get_sensor_adev_and_name(struct device *dev,
        struct acpi_device *sensor;
        int ret = 0;
 
-       sensor = acpi_dev_get_first_consumer_dev(adev);
+       sensor = acpi_dev_get_next_consumer_dev(adev, NULL);
        if (!sensor) {
                dev_err(dev, "INT3472 seems to have no dependents.\n");
                return -ENODEV;
index 42f76f2c2d49f04ac630690d2b6a9c677a77a06b..c66d17c3298b86fd2604421793bb10c50993644e 100644 (file)
@@ -742,7 +742,9 @@ bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const ch
 
 void acpi_dev_clear_dependencies(struct acpi_device *supplier);
 bool acpi_dev_ready_for_enumeration(const struct acpi_device *device);
-struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
+struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier,
+                                                  struct acpi_device *start);
+
 struct acpi_device *
 acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
 struct acpi_device *