Skip to content

Commit 63f534b

Browse files
committed
ACPI: PCI: Rework acpi_get_pci_dev()
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> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 521a547 commit 63f534b

File tree

1 file changed

+12
-63
lines changed

1 file changed

+12
-63
lines changed

drivers/acpi/pci_root.c

Lines changed: 12 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -312,76 +312,25 @@ struct acpi_handle_node {
312312
*/
313313
struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
314314
{
315-
int dev, fn;
316-
unsigned long long adr;
317-
acpi_status status;
318-
acpi_handle phandle;
319-
struct pci_bus *pbus;
320-
struct pci_dev *pdev = NULL;
321-
struct acpi_handle_node *node, *tmp;
322-
struct acpi_pci_root *root;
323-
LIST_HEAD(device_list);
324-
325-
/*
326-
* Walk up the ACPI CA namespace until we reach a PCI root bridge.
327-
*/
328-
phandle = handle;
329-
while (!acpi_is_root_bridge(phandle)) {
330-
node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL);
331-
if (!node)
332-
goto out;
333-
334-
INIT_LIST_HEAD(&node->node);
335-
node->handle = phandle;
336-
list_add(&node->node, &device_list);
337-
338-
status = acpi_get_parent(phandle, &phandle);
339-
if (ACPI_FAILURE(status))
340-
goto out;
341-
}
342-
343-
root = acpi_pci_find_root(phandle);
344-
if (!root)
345-
goto out;
315+
struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
316+
struct acpi_device_physical_node *pn;
317+
struct pci_dev *pci_dev = NULL;
346318

347-
pbus = root->bus;
348-
349-
/*
350-
* Now, walk back down the PCI device tree until we return to our
351-
* original handle. Assumes that everything between the PCI root
352-
* bridge and the device we're looking for must be a P2P bridge.
353-
*/
354-
list_for_each_entry(node, &device_list, node) {
355-
acpi_handle hnd = node->handle;
356-
status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr);
357-
if (ACPI_FAILURE(status))
358-
goto out;
359-
dev = (adr >> 16) & 0xffff;
360-
fn = adr & 0xffff;
361-
362-
pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn));
363-
if (!pdev || hnd == handle)
364-
break;
319+
if (!adev)
320+
return NULL;
365321

366-
pbus = pdev->subordinate;
367-
pci_dev_put(pdev);
322+
mutex_lock(&adev->physical_node_lock);
368323

369-
/*
370-
* This function may be called for a non-PCI device that has a
371-
* PCI parent (eg. a disk under a PCI SATA controller). In that
372-
* case pdev->subordinate will be NULL for the parent.
373-
*/
374-
if (!pbus) {
375-
dev_dbg(&pdev->dev, "Not a PCI-to-PCI bridge\n");
376-
pdev = NULL;
324+
list_for_each_entry(pn, &adev->physical_node_list, node) {
325+
if (dev_is_pci(pn->dev)) {
326+
pci_dev = to_pci_dev(pn->dev);
377327
break;
378328
}
379329
}
380-
out:
381-
list_for_each_entry_safe(node, tmp, &device_list, node)
382-
kfree(node);
383330

384-
return pdev;
331+
mutex_unlock(&adev->physical_node_lock);
332+
333+
return pci_dev;
385334
}
386335
EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
387336

0 commit comments

Comments
 (0)