aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJohn Rose2006-02-24 11:34:23 -0600
committerPaul Mackerras2006-02-28 16:25:54 +1100
commit827c1a6c1a5dcb2902fecfb648f9af6a532934eb (patch)
tree7cc96f3b3df746dc8569bc1b0bffd47f11084214 /arch
parenta8b76b491510b7591c584838d0d7922f9ffe5c2c (diff)
[PATCH] powerpc: fix dynamic PCI probe regression
Some hotplug driver functions were migrated to the kernel for use by EEH in commit 2bf6a8fa21570f37fd1789610da30f70a05ac5e3. Previously, the PCI Hotplug module had been changed to use the new OFDT-based PCI probe when appropriate: 5fa80fcdca9d20d30c9ecec30d4dbff4ed93a5c6 When rpaphp_pci_config_slot() was moved from the rpaphp driver to the new kernel function pcibios_add_pci_devices(), the OFDT-based probe stuff was dropped. This patch restores it. Signed-off-by: John Rose <johnrose@austin.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c14
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c36
2 files changed, 34 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 83578313ee7e..2ab9dcdfb415 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -893,6 +893,20 @@ void eeh_add_device_tree_early(struct device_node *dn)
}
EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
+void eeh_add_device_tree_late(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ eeh_add_device_late(dev);
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ struct pci_bus *subbus = dev->subordinate;
+ if (subbus)
+ eeh_add_device_tree_late(subbus);
+ }
+ }
+}
+
/**
* eeh_add_device_late - perform EEH initialization for the indicated pci device
* @dev: pci device for which to set up EEH
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index bdaa8aabdaa6..f3bad900bbcf 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -106,6 +106,8 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
}
}
}
+
+ eeh_add_device_tree_late(bus);
}
EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
@@ -114,7 +116,6 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
{
u8 sec_busno;
struct pci_bus *child_bus;
- struct pci_dev *child_dev;
/* Get busno of downstream bus */
pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
@@ -129,10 +130,6 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
pci_scan_child_bus(child_bus);
- list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
- eeh_add_device_late(child_dev);
- }
-
/* Fixup new pci devices without touching bus struct */
pcibios_fixup_new_pci_devices(child_bus, 0);
@@ -160,18 +157,25 @@ pcibios_add_pci_devices(struct pci_bus * bus)
eeh_add_device_tree_early(dn);
- /* pci_scan_slot should find all children */
- slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
- num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
- if (num) {
- pcibios_fixup_new_pci_devices(bus, 1);
- pci_bus_add_devices(bus);
- }
+ if (_machine == PLATFORM_PSERIES_LPAR) {
+ /* use ofdt-based probe */
+ of_scan_bus(dn, bus);
+ if (!list_empty(&bus->devices)) {
+ pcibios_fixup_new_pci_devices(bus, 0);
+ pci_bus_add_devices(bus);
+ }
+ } else {
+ /* use legacy probe */
+ slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+ num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+ if (num) {
+ pcibios_fixup_new_pci_devices(bus, 1);
+ pci_bus_add_devices(bus);
+ }
- list_for_each_entry(dev, &bus->devices, bus_list) {
- eeh_add_device_late (dev);
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
- pcibios_pci_config_bridge(dev);
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+ pcibios_pci_config_bridge(dev);
}
}
EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);