ACPI: glue: Introduce acpi_find_child_by_adr()
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 13 Jun 2022 18:10:03 +0000 (20:10 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 20 Jun 2022 18:28:48 +0000 (20:28 +0200)
Rearrange the ACPI device lookup code used internally by
acpi_find_child_device() so it can avoid extra checks after finding
one object with a matching _ADR and use it for defining
acpi_find_child_by_adr() that will allow the callers to find a given
ACPI device's child matching a given bus address without doing any
other checks in check_one_child().

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
drivers/acpi/glue.c
include/acpi/acpi_bus.h

index 5203a7c..204fe94 100644 (file)
@@ -119,6 +119,7 @@ struct find_child_walk_data {
        struct acpi_device *adev;
        u64 address;
        int score;
+       bool check_sta;
        bool check_children;
 };
 
@@ -131,9 +132,13 @@ static int check_one_child(struct acpi_device *adev, void *data)
                return 0;
 
        if (!wd->adev) {
-               /* This is the first matching object.  Save it and continue. */
+               /*
+                * This is the first matching object, so save it.  If it is not
+                * necessary to look for any other matching objects, stop the
+                * search.
+                */
                wd->adev = adev;
-               return 0;
+               return !(wd->check_sta || wd->check_children);
        }
 
        /*
@@ -169,12 +174,14 @@ static int check_one_child(struct acpi_device *adev, void *data)
        return 0;
 }
 
-struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
-                                          u64 address, bool check_children)
+static struct acpi_device *acpi_find_child(struct acpi_device *parent,
+                                          u64 address, bool check_children,
+                                          bool check_sta)
 {
        struct find_child_walk_data wd = {
                .address = address,
                .check_children = check_children,
+               .check_sta = check_sta,
                .adev = NULL,
                .score = 0,
        };
@@ -184,8 +191,21 @@ struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
 
        return wd.adev;
 }
+
+struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
+                                          u64 address, bool check_children)
+{
+       return acpi_find_child(parent, address, check_children, true);
+}
 EXPORT_SYMBOL_GPL(acpi_find_child_device);
 
+struct acpi_device *acpi_find_child_by_adr(struct acpi_device *adev,
+                                          acpi_bus_address adr)
+{
+       return acpi_find_child(adev, adr, false, false);
+}
+EXPORT_SYMBOL_GPL(acpi_find_child_by_adr);
+
 static void acpi_physnode_link_name(char *buf, unsigned int node_id)
 {
        if (node_id > 0)
index 0dc1ea0..5979619 100644 (file)
@@ -622,6 +622,8 @@ static inline int acpi_dma_configure(struct device *dev,
 }
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
                                           u64 address, bool check_children);
+struct acpi_device *acpi_find_child_by_adr(struct acpi_device *adev,
+                                          acpi_bus_address adr);
 int acpi_is_root_bridge(acpi_handle);
 struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);