diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 6a9a1116f1eb..09b4a35e21a8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -458,6 +458,30 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev, EXPORT_SYMBOL(pci_find_parent_resource); /** + * pci_find_pcie_root_port - return PCIe Root Port + * @dev: PCI device to query + * + * Traverse up the parent chain and return the PCIe Root Port PCI Device + * for a given PCI Device. + */ +struct pci_dev *pci_find_pcie_root_port(struct pci_dev *dev) +{ + struct pci_dev *bridge, *highest_pcie_bridge = NULL; + + bridge = pci_upstream_bridge(dev); + while (bridge && pci_is_pcie(bridge)) { + highest_pcie_bridge = bridge; + bridge = pci_upstream_bridge(bridge); + } + + if (pci_pcie_type(highest_pcie_bridge) != PCI_EXP_TYPE_ROOT_PORT) + return NULL; + + return highest_pcie_bridge; +} +EXPORT_SYMBOL(pci_find_pcie_root_port); + +/** * pci_wait_for_pending - wait for @mask bit(s) to clear in status word @pos * @dev: the PCI device to operate on * @pos: config space offset of status word |