aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/pci_64.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-27 15:48:37 -0400
committerPaul Mackerras <paulus@samba.org>2008-11-05 17:22:37 -0500
commit8b8da35804bb89eee23f9bcd5638e1f754bd4c91 (patch)
tree8ec1ba6ef03c88da5c37eec4825fff6524358b37 /arch/powerpc/kernel/pci_64.c
parentab56ced9c57b66862c687f3158045d15133f02d6 (diff)
powerpc/pci: Split pcibios_fixup_bus() into bus setup and device setup
Currently, our PCI code uses the pcibios_fixup_bus() callback, which is called by the generic code when probing PCI buses, for two different things. One is to set up things related to the bus itself, such as reading bridge resources for P2P bridges, fixing them up, or setting up the iommu's associated with bridges on some platforms. The other is some setup for each individual device under that bridge, mostly setting up DMA mappings and interrupts. The problem is that this approach doesn't work well with PCI hotplug when an existing bus is re-probed for new children. We fix this problem by splitting pcibios_fixup_bus into two routines: pcibios_setup_bus_self() is now called to setup the bus itself pcibios_setup_bus_devices() is now called to setup devices pcibios_fixup_bus() is then modified to call these two after reading the bridge bases, and the OF based PCI probe is modified to avoid calling into the first one when rescanning an existing bridge. [paulus@samba.org - fixed eeh.h for 32-bit compile now that pci-common.c is including it unconditionally.] Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/pci_64.c')
-rw-r--r--arch/powerpc/kernel/pci_64.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index e6e8813c364a..39fadc6e1492 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -189,8 +189,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
189} 189}
190EXPORT_SYMBOL(of_create_pci_dev); 190EXPORT_SYMBOL(of_create_pci_dev);
191 191
192void __devinit of_scan_bus(struct device_node *node, 192static void __devinit __of_scan_bus(struct device_node *node,
193 struct pci_bus *bus) 193 struct pci_bus *bus, int rescan_existing)
194{ 194{
195 struct device_node *child; 195 struct device_node *child;
196 const u32 *reg; 196 const u32 *reg;
@@ -215,8 +215,12 @@ void __devinit of_scan_bus(struct device_node *node,
215 pr_debug(" dev header type: %x\n", dev->hdr_type); 215 pr_debug(" dev header type: %x\n", dev->hdr_type);
216 } 216 }
217 217
218 /* Ally all fixups */ 218 /* Apply all fixups necessary. We don't fixup the bus "self"
219 pcibios_fixup_of_probed_bus(bus); 219 * for an existing bridge that is being rescanned
220 */
221 if (!rescan_existing)
222 pcibios_setup_bus_self(bus);
223 pcibios_setup_bus_devices(bus);
220 224
221 /* Now scan child busses */ 225 /* Now scan child busses */
222 list_for_each_entry(dev, &bus->devices, bus_list) { 226 list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -228,7 +232,20 @@ void __devinit of_scan_bus(struct device_node *node,
228 } 232 }
229 } 233 }
230} 234}
231EXPORT_SYMBOL(of_scan_bus); 235
236void __devinit of_scan_bus(struct device_node *node,
237 struct pci_bus *bus)
238{
239 __of_scan_bus(node, bus, 0);
240}
241EXPORT_SYMBOL_GPL(of_scan_bus);
242
243void __devinit of_rescan_bus(struct device_node *node,
244 struct pci_bus *bus)
245{
246 __of_scan_bus(node, bus, 1);
247}
248EXPORT_SYMBOL_GPL(of_rescan_bus);
232 249
233void __devinit of_scan_pci_bridge(struct device_node *node, 250void __devinit of_scan_pci_bridge(struct device_node *node,
234 struct pci_dev *dev) 251 struct pci_dev *dev)