public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ACPI: PCI: Rework acpi_get_pci_dev()
@ 2022-09-10 13:23 Rafael J. Wysocki
  2022-09-10 14:06 ` Greg Kroah-Hartman
  0 siblings, 1 reply; 2+ messages in thread
From: Rafael J. Wysocki @ 2022-09-10 13:23 UTC (permalink / raw)
  To: Linux PCI; +Cc: Greg Kroah-Hartman, Linux ACPI, Bjorn Helgaas

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The PCI device returned by acpi_get_pci_dev() needs to be registered,
so if it corresponds to an ACPI device object, the struct acpi_device
representing that object must be registered too and, moreover, it
should be the ACPI companion of the given PCI device.  Thus it should
be sufficient to look for it in the ACPI device object's list of
physical nodes associated with it.

Modify the code accordingly.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/pci_root.c |   81 ++++++++----------------------------------------
 1 file changed, 15 insertions(+), 66 deletions(-)

Index: linux-pm/drivers/acpi/pci_root.c
===================================================================
--- linux-pm.orig/drivers/acpi/pci_root.c
+++ linux-pm/drivers/acpi/pci_root.c
@@ -312,76 +312,25 @@ struct acpi_handle_node {
  */
 struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
 {
-	int dev, fn;
-	unsigned long long adr;
-	acpi_status status;
-	acpi_handle phandle;
-	struct pci_bus *pbus;
-	struct pci_dev *pdev = NULL;
-	struct acpi_handle_node *node, *tmp;
-	struct acpi_pci_root *root;
-	LIST_HEAD(device_list);
-
-	/*
-	 * Walk up the ACPI CA namespace until we reach a PCI root bridge.
-	 */
-	phandle = handle;
-	while (!acpi_is_root_bridge(phandle)) {
-		node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL);
-		if (!node)
-			goto out;
-
-		INIT_LIST_HEAD(&node->node);
-		node->handle = phandle;
-		list_add(&node->node, &device_list);
-
-		status = acpi_get_parent(phandle, &phandle);
-		if (ACPI_FAILURE(status))
-			goto out;
-	}
-
-	root = acpi_pci_find_root(phandle);
-	if (!root)
-		goto out;
-
-	pbus = root->bus;
-
-	/*
-	 * Now, walk back down the PCI device tree until we return to our
-	 * original handle. Assumes that everything between the PCI root
-	 * bridge and the device we're looking for must be a P2P bridge.
-	 */
-	list_for_each_entry(node, &device_list, node) {
-		acpi_handle hnd = node->handle;
-		status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr);
-		if (ACPI_FAILURE(status))
-			goto out;
-		dev = (adr >> 16) & 0xffff;
-		fn  = adr & 0xffff;
-
-		pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn));
-		if (!pdev || hnd == handle)
-			break;
-
-		pbus = pdev->subordinate;
-		pci_dev_put(pdev);
-
-		/*
-		 * This function may be called for a non-PCI device that has a
-		 * PCI parent (eg. a disk under a PCI SATA controller).  In that
-		 * case pdev->subordinate will be NULL for the parent.
-		 */
-		if (!pbus) {
-			dev_dbg(&pdev->dev, "Not a PCI-to-PCI bridge\n");
-			pdev = NULL;
+	struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
+	struct acpi_device_physical_node *pn;
+	struct pci_dev *pci_dev = NULL;
+
+	if (!adev)
+		return NULL;
+
+	mutex_lock(&adev->physical_node_lock);
+
+	list_for_each_entry(pn, &adev->physical_node_list, node) {
+		if (dev_is_pci(pn->dev)) {
+			pci_dev = to_pci_dev(pn->dev);
 			break;
 		}
 	}
-out:
-	list_for_each_entry_safe(node, tmp, &device_list, node)
-		kfree(node);
 
-	return pdev;
+	mutex_unlock(&adev->physical_node_lock);
+
+	return pci_dev;
 }
 EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
 




^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] ACPI: PCI: Rework acpi_get_pci_dev()
  2022-09-10 13:23 [PATCH] ACPI: PCI: Rework acpi_get_pci_dev() Rafael J. Wysocki
@ 2022-09-10 14:06 ` Greg Kroah-Hartman
  0 siblings, 0 replies; 2+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-10 14:06 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Linux PCI, Linux ACPI, Bjorn Helgaas

On Sat, Sep 10, 2022 at 03:23:46PM +0200, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> The PCI device returned by acpi_get_pci_dev() needs to be registered,
> so if it corresponds to an ACPI device object, the struct acpi_device
> representing that object must be registered too and, moreover, it
> should be the ACPI companion of the given PCI device.  Thus it should
> be sufficient to look for it in the ACPI device object's list of
> physical nodes associated with it.
> 
> Modify the code accordingly.
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/acpi/pci_root.c |   81 ++++++++----------------------------------------
>  1 file changed, 15 insertions(+), 66 deletions(-)

Nice, less code is always better :)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-09-10 14:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-10 13:23 [PATCH] ACPI: PCI: Rework acpi_get_pci_dev() Rafael J. Wysocki
2022-09-10 14:06 ` Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox