Merge tag 'nfsd-4.7' of git://linux-nfs.org/~bfields/linux
[cascardo/linux.git] / arch / powerpc / kernel / pci-hotplug.c
index 59c4361..2d71269 100644 (file)
 #include <asm/firmware.h>
 #include <asm/eeh.h>
 
+static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
+                                              struct device_node *dn)
+{
+       struct pci_bus *child = NULL;
+       struct pci_bus *tmp;
+
+       if (pci_bus_to_OF_node(bus) == dn)
+               return bus;
+
+       list_for_each_entry(tmp, &bus->children, node) {
+               child = find_bus_among_children(tmp, dn);
+               if (child)
+                       break;
+       }
+
+       return child;
+}
+
+struct pci_bus *pci_find_bus_by_node(struct device_node *dn)
+{
+       struct pci_dn *pdn = PCI_DN(dn);
+
+       if (!pdn  || !pdn->phb || !pdn->phb->bus)
+               return NULL;
+
+       return find_bus_among_children(pdn->phb->bus, dn);
+}
+EXPORT_SYMBOL_GPL(pci_find_bus_by_node);
+
 /**
  * pcibios_release_device - release PCI device
  * @dev: PCI device
@@ -38,20 +67,20 @@ void pcibios_release_device(struct pci_dev *dev)
 }
 
 /**
- * pcibios_remove_pci_devices - remove all devices under this bus
+ * pci_hp_remove_devices - remove all devices under this bus
  * @bus: the indicated PCI bus
  *
  * Remove all of the PCI devices under this bus both from the
  * linux pci device tree, and from the powerpc EEH address cache.
  */
-void pcibios_remove_pci_devices(struct pci_bus *bus)
+void pci_hp_remove_devices(struct pci_bus *bus)
 {
        struct pci_dev *dev, *tmp;
        struct pci_bus *child_bus;
 
        /* First go down child busses */
        list_for_each_entry(child_bus, &bus->children, node)
-               pcibios_remove_pci_devices(child_bus);
+               pci_hp_remove_devices(child_bus);
 
        pr_debug("PCI: Removing devices on bus %04x:%02x\n",
                 pci_domain_nr(bus),  bus->number);
@@ -60,11 +89,10 @@ void pcibios_remove_pci_devices(struct pci_bus *bus)
                pci_stop_and_remove_bus_device(dev);
        }
 }
-
-EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
+EXPORT_SYMBOL_GPL(pci_hp_remove_devices);
 
 /**
- * pcibios_add_pci_devices - adds new pci devices to bus
+ * pci_hp_add_devices - adds new pci devices to bus
  * @bus: the indicated PCI bus
  *
  * This routine will find and fixup new pci devices under
@@ -74,7 +102,7 @@ EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
  * is how this routine differs from other, similar pcibios
  * routines.)
  */
-void pcibios_add_pci_devices(struct pci_bus * bus)
+void pci_hp_add_devices(struct pci_bus *bus)
 {
        int slotno, mode, pass, max;
        struct pci_dev *dev;
@@ -92,7 +120,8 @@ void pcibios_add_pci_devices(struct pci_bus * bus)
        if (mode == PCI_PROBE_DEVTREE) {
                /* use ofdt-based probe */
                of_rescan_bus(dn, bus);
-       } else if (mode == PCI_PROBE_NORMAL) {
+       } else if (mode == PCI_PROBE_NORMAL &&
+                  dn->child && PCI_DN(dn->child)) {
                /*
                 * Use legacy probe. In the partial hotplug case, we
                 * probably have grandchildren devices unplugged. So
@@ -114,4 +143,4 @@ void pcibios_add_pci_devices(struct pci_bus * bus)
        }
        pcibios_finish_adding_to_bus(bus);
 }
-EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
+EXPORT_SYMBOL_GPL(pci_hp_add_devices);