diff options
author | John Rose <johnrose@austin.ibm.com> | 2006-03-14 18:46:45 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-03-16 00:55:07 -0500 |
commit | 92eb4602eb5c37db86cd9d2b1f4c8ca304fbc49f (patch) | |
tree | d6f53b85f0071e914cd1fa5d363259d584f1d3b2 /arch/powerpc | |
parent | 920573bd03bf690135967b5022362d34ede589c3 (diff) |
[PATCH] powerpc: properly configure DDR/P5IOC children devs
The dynamic add path for PCI Host Bridges can fail to configure children
adapters under P5IOC controllers. It fails to properly fixup bus/device
resources, and it fails to properly enable EEH. Both of these steps
need to occur before any children devices are enabled in
pci_bus_add_devices().
Signed-off-by: John Rose <johnrose@austin.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas_pci.c | 24 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pci_dlpar.c | 28 |
3 files changed, 32 insertions, 25 deletions
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index c367520bc1c3..ba92bab7cc2c 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -589,7 +589,6 @@ void __devinit scan_phb(struct pci_controller *hose) | |||
589 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 589 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
590 | if (mode == PCI_PROBE_NORMAL) | 590 | if (mode == PCI_PROBE_NORMAL) |
591 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); | 591 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); |
592 | pci_bus_add_devices(bus); | ||
593 | } | 592 | } |
594 | 593 | ||
595 | static int __init pcibios_init(void) | 594 | static int __init pcibios_init(void) |
@@ -608,8 +607,10 @@ static int __init pcibios_init(void) | |||
608 | printk("PCI: Probing PCI hardware\n"); | 607 | printk("PCI: Probing PCI hardware\n"); |
609 | 608 | ||
610 | /* Scan all of the recorded PCI controllers. */ | 609 | /* Scan all of the recorded PCI controllers. */ |
611 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | 610 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
612 | scan_phb(hose); | 611 | scan_phb(hose); |
612 | pci_bus_add_devices(hose->bus); | ||
613 | } | ||
613 | 614 | ||
614 | #ifndef CONFIG_PPC_ISERIES | 615 | #ifndef CONFIG_PPC_ISERIES |
615 | if (pci_probe_only) | 616 | if (pci_probe_only) |
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 5579f6559912..7442775ef2a1 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -280,8 +280,7 @@ static int phb_set_bus_ranges(struct device_node *dev, | |||
280 | return 0; | 280 | return 0; |
281 | } | 281 | } |
282 | 282 | ||
283 | static int __devinit setup_phb(struct device_node *dev, | 283 | int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb) |
284 | struct pci_controller *phb) | ||
285 | { | 284 | { |
286 | if (is_python(dev)) | 285 | if (is_python(dev)) |
287 | python_countermeasures(dev); | 286 | python_countermeasures(dev); |
@@ -359,27 +358,6 @@ unsigned long __init find_and_init_phbs(void) | |||
359 | return 0; | 358 | return 0; |
360 | } | 359 | } |
361 | 360 | ||
362 | struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) | ||
363 | { | ||
364 | struct pci_controller *phb; | ||
365 | int primary; | ||
366 | |||
367 | primary = list_empty(&hose_list); | ||
368 | phb = pcibios_alloc_controller(dn); | ||
369 | if (!phb) | ||
370 | return NULL; | ||
371 | setup_phb(dn, phb); | ||
372 | pci_process_bridge_OF_ranges(phb, dn, primary); | ||
373 | |||
374 | pci_setup_phb_io_dynamic(phb, primary); | ||
375 | |||
376 | pci_devs_phb_init_dynamic(phb); | ||
377 | scan_phb(phb); | ||
378 | |||
379 | return phb; | ||
380 | } | ||
381 | EXPORT_SYMBOL(init_phb_dynamic); | ||
382 | |||
383 | /* RPA-specific bits for removing PHBs */ | 361 | /* RPA-specific bits for removing PHBs */ |
384 | int pcibios_remove_root_bus(struct pci_controller *phb) | 362 | int pcibios_remove_root_bus(struct pci_controller *phb) |
385 | { | 363 | { |
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index f3bad900bbcf..44abdeb9ca03 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <asm/pci-bridge.h> | 29 | #include <asm/pci-bridge.h> |
30 | #include <asm/ppc-pci.h> | ||
30 | 31 | ||
31 | static struct pci_bus * | 32 | static struct pci_bus * |
32 | find_bus_among_children(struct pci_bus *bus, | 33 | find_bus_among_children(struct pci_bus *bus, |
@@ -179,3 +180,30 @@ pcibios_add_pci_devices(struct pci_bus * bus) | |||
179 | } | 180 | } |
180 | } | 181 | } |
181 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); | 182 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); |
183 | |||
184 | struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) | ||
185 | { | ||
186 | struct pci_controller *phb; | ||
187 | int primary; | ||
188 | |||
189 | primary = list_empty(&hose_list); | ||
190 | phb = pcibios_alloc_controller(dn); | ||
191 | if (!phb) | ||
192 | return NULL; | ||
193 | setup_phb(dn, phb); | ||
194 | pci_process_bridge_OF_ranges(phb, dn, 0); | ||
195 | |||
196 | pci_setup_phb_io_dynamic(phb, primary); | ||
197 | |||
198 | pci_devs_phb_init_dynamic(phb); | ||
199 | |||
200 | if (dn->child) | ||
201 | eeh_add_device_tree_early(dn); | ||
202 | |||
203 | scan_phb(phb); | ||
204 | pcibios_fixup_new_pci_devices(phb->bus, 0); | ||
205 | pci_bus_add_devices(phb->bus); | ||
206 | |||
207 | return phb; | ||
208 | } | ||
209 | EXPORT_SYMBOL_GPL(init_phb_dynamic); | ||