diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2016-05-20 08:41:40 +0200 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-06-21 07:30:58 +0200 |
commit | 7e19bf32c8ac977e7702a67d7392a3e0a9644bc8 (patch) | |
tree | 13f003cef438104190d28896c8eee2a0619578fe | |
parent | powerpc/powernv: Use PCI slot reset infrastructure (diff) | |
download | linux-7e19bf32c8ac977e7702a67d7392a3e0a9644bc8.tar.xz linux-7e19bf32c8ac977e7702a67d7392a3e0a9644bc8.zip |
powerpc/powernv: Introduce pnv_pci_get_slot_id()
This introduces pnv_pci_get_slot_id() to get the hotpluggable PCI
slot ID from the corresponding device node. It will be used by
hotplug driver.
Requested-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/include/asm/pnv-pci.h | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 38 |
2 files changed, 40 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h index c607902c5477..810cc9a8169f 100644 --- a/arch/powerpc/include/asm/pnv-pci.h +++ b/arch/powerpc/include/asm/pnv-pci.h @@ -17,6 +17,8 @@ #define PCI_SLOT_ID(phb_id, bdfn) \ (PCI_SLOT_ID_PREFIX | ((uint64_t)(bdfn) << 16) | (phb_id)) +extern int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id); + int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode); int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq, unsigned int virq); diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 0f1b8bf953e1..2607d2923b80 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -26,6 +26,7 @@ #include <asm/machdep.h> #include <asm/msi_bitmap.h> #include <asm/ppc-pci.h> +#include <asm/pnv-pci.h> #include <asm/opal.h> #include <asm/iommu.h> #include <asm/tce.h> @@ -36,6 +37,43 @@ #include "powernv.h" #include "pci.h" +int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id) +{ + struct device_node *parent = np; + u32 bdfn; + u64 phbid; + int ret; + + ret = of_property_read_u32(np, "reg", &bdfn); + if (ret) + return -ENXIO; + + bdfn = ((bdfn & 0x00ffff00) >> 8); + while ((parent = of_get_parent(parent))) { + if (!PCI_DN(parent)) { + of_node_put(parent); + break; + } + + if (!of_device_is_compatible(parent, "ibm,ioda2-phb")) { + of_node_put(parent); + continue; + } + + ret = of_property_read_u64(parent, "ibm,opal-phbid", &phbid); + if (ret) { + of_node_put(parent); + return -ENXIO; + } + + *id = PCI_SLOT_ID(phbid, bdfn); + return 0; + } + + return -ENODEV; +} +EXPORT_SYMBOL_GPL(pnv_pci_get_slot_id); + #ifdef CONFIG_PCI_MSI int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { |