summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2026-08-26 19:22:52 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2026-08-26 19:22:52 +0200
commitbbc981bd541e62760c4c0dbf326427a4751e3586 (patch)
treedc53fa025e0b7f2c5b031d486058b3991a17a56b
parent4c2cebc89db9852a0815d4c3cbdea4e102230e8c (diff)
parent87ee7d704f69f303c86b2dcf617e33764371fe7b (diff)
Merge branch 'acpi-bus'
Merge changes related to primary "physical" device lookup for a given ACPI device object that include the introduction of a new lookup helper function and core ACPI device enumeration code updates putting that new function to use (Rafael Wysocki) * acpi-bus: ACPI: scan: Use acpi_bus_get_primary_device() ACPI: platform: Use acpi_bus_get_primary_device() ACPI: bus: Introduce acpi_bus_get_primary_device()
-rw-r--r--drivers/acpi/acpi_platform.c16
-rw-r--r--drivers/acpi/bus.c54
-rw-r--r--drivers/acpi/scan.c20
-rw-r--r--include/acpi/acpi_bus.h6
4 files changed, 60 insertions, 36 deletions
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index e3c77a65f61c..80ea7121744d 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -108,18 +108,15 @@ static unsigned int acpi_platform_adjust_resources(struct acpi_device *adev,
return count;
}
-static void acpi_platform_fill_resource(struct acpi_device *adev,
- const struct resource *src, struct resource *dest)
+static void acpi_platform_fill_resource(struct device *parent,
+ const struct resource *src,
+ struct resource *dest)
{
- struct device *parent;
-
*dest = *src;
-
/*
* If the device has parent we need to take its resources into
* account as well because this device might consume part of those.
*/
- parent = acpi_get_first_physical_node(acpi_dev_parent(adev));
if (parent && dev_is_pci(parent))
dest->parent = pci_find_resource(to_pci_dev(parent), dest);
}
@@ -147,7 +144,8 @@ static unsigned int acpi_platform_resource_count(struct acpi_resource *ares, voi
struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
const struct property_entry *properties)
{
- struct acpi_device *parent = acpi_dev_parent(adev);
+ struct acpi_device *p = acpi_dev_parent(adev);
+ struct device *parent __free(put_device) = acpi_bus_get_primary_device(p);
struct platform_device *pdev = NULL;
struct platform_device_info pdevinfo;
const struct acpi_device_id *match;
@@ -193,7 +191,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
rentry->res,
resources,
count);
- acpi_platform_fill_resource(adev, rentry->res,
+ acpi_platform_fill_resource(parent, rentry->res,
&resources[count++]);
}
acpi_dev_free_resource_list(&resource_list);
@@ -206,7 +204,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
* attached to it, that physical device should be the parent of the
* platform device we are about to create.
*/
- pdevinfo.parent = parent ? acpi_get_first_physical_node(parent) : NULL;
+ pdevinfo.parent = parent;
pdevinfo.name = dev_name(&adev->dev);
pdevinfo.id = PLATFORM_DEVID_NONE;
pdevinfo.res = resources;
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index c1876f145ae4..ce50ce7a50da 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -774,30 +774,52 @@ static int __init acpi_setup_sb_notify_handler(void)
Device Matching
-------------------------------------------------------------------------- */
+
+static struct device *primary_physical_device(struct acpi_device *adev)
+{
+ struct acpi_device_physical_node *pn;
+
+ pn = list_first_entry_or_null(&adev->physical_node_list,
+ struct acpi_device_physical_node, node);
+ if (pn)
+ return pn->dev;
+
+ return NULL;
+}
+
+/**
+ * acpi_bus_get_primary_device - Get first physical device for a given ACPI one
+ * @adev: ACPI device to get the first physical device for.
+ *
+ * Find the first physical device for which @adev is the ACPI companion and
+ * reference count it if present.
+ *
+ * Return: Pointer to the first physical counterpart of @adev or NULL if there
+ * are none. Callers are responsible for invoking put_device() on the returned
+ * device.
+ */
+struct device *acpi_bus_get_primary_device(struct acpi_device *adev)
+{
+ if (!adev)
+ return NULL;
+
+ guard(mutex)(&adev->physical_node_lock);
+
+ return get_device(primary_physical_device(adev));
+}
+EXPORT_SYMBOL_GPL(acpi_bus_get_primary_device);
+
/**
- * acpi_get_first_physical_node - Get first physical node of an ACPI device
+ * acpi_get_first_physical_node - Find first physical node of an ACPI device
* @adev: ACPI device in question
*
* Return: First physical node of ACPI device @adev
*/
struct device *acpi_get_first_physical_node(struct acpi_device *adev)
{
- struct mutex *physical_node_lock = &adev->physical_node_lock;
- struct device *phys_dev;
-
- mutex_lock(physical_node_lock);
- if (list_empty(&adev->physical_node_list)) {
- phys_dev = NULL;
- } else {
- const struct acpi_device_physical_node *node;
+ guard(mutex)(&adev->physical_node_lock);
- node = list_first_entry(&adev->physical_node_list,
- struct acpi_device_physical_node, node);
-
- phys_dev = node->dev;
- }
- mutex_unlock(physical_node_lock);
- return phys_dev;
+ return primary_physical_device(adev);
}
EXPORT_SYMBOL_GPL(acpi_get_first_physical_node);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b8a2f21dffd5..5f9b918fb6c5 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2208,29 +2208,27 @@ static void acpi_create_video_bus_device(struct acpi_device *adev,
struct auxiliary_device *aux_dev;
static unsigned int aux_dev_id;
+ struct device *phys_parent __free(put_device) = acpi_bus_get_primary_device(parent);
+ if (!phys_parent)
+ return;
+
aux_dev = kzalloc_obj(*aux_dev);
if (!aux_dev)
return;
aux_dev->id = aux_dev_id++;
aux_dev->name = "video_bus";
- aux_dev->dev.parent = acpi_get_first_physical_node(parent);
- if (!aux_dev->dev.parent)
- goto err;
-
+ aux_dev->dev.parent = phys_parent;
aux_dev->dev.release = acpi_video_bus_device_release;
- if (auxiliary_device_init(aux_dev))
- goto err;
+ if (auxiliary_device_init(aux_dev)) {
+ kfree(aux_dev);
+ return;
+ }
ACPI_COMPANION_SET(&aux_dev->dev, adev);
if (__auxiliary_device_add(aux_dev, "acpi"))
auxiliary_device_uninit(aux_dev);
-
- return;
-
-err:
- kfree(aux_dev);
}
struct acpi_scan_system_dev {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 32cac3a6f362..eaf13f6ac2d3 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -650,6 +650,7 @@ int acpi_scan_add_handler(struct acpi_scan_handler *handler);
int acpi_bus_scan(acpi_handle handle);
void acpi_bus_trim(struct acpi_device *start);
acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
+struct device *acpi_bus_get_primary_device(struct acpi_device *adev);
int acpi_match_device_ids(struct acpi_device *device,
const struct acpi_device_id *ids);
void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
@@ -952,6 +953,11 @@ int acpi_scan_add_dep(acpi_handle handle, struct acpi_handle_list *dep_devices);
u32 arch_acpi_add_auto_dep(acpi_handle handle);
#else /* CONFIG_ACPI */
+static inline struct device *acpi_bus_get_primary_device(struct acpi_device *adev)
+{
+ return NULL;
+}
+
static inline bool acpi_of_match_device(const struct acpi_device *adev,
const struct of_device_id *of_match_table,
const struct of_device_id **of_id)