powerpc/powernv: Introduce pnv_pci_get_slot_id()
authorGavin Shan <gwshan@linux.vnet.ibm.com>
Fri, 20 May 2016 06:41:40 +0000 (16:41 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 21 Jun 2016 05:30:58 +0000 (15:30 +1000)
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>
arch/powerpc/include/asm/pnv-pci.h
arch/powerpc/platforms/powernv/pci.c

index c607902c5477583c3f2783e332876575ef2c1470..810cc9a8169f3dc8c9688180bae1f73b0f0331e6 100644 (file)
@@ -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);
index 0f1b8bf953e16a05612a7fe91dce06d554a5ee4a..2607d2923b8064e96f23458c42a2757c7cb29cb9 100644 (file)
@@ -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>
 #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)
 {