[PATCH] powerpc: properly configure DDR/P5IOC children devs
John Rose
johnrose at austin.ibm.com
Wed Mar 15 10:46:45 EST 2006
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 at austin.ibm.com>
---
This is a single concise respin of the 3 patches sent on March 6th:
http://ozlabs.org/pipermail/linuxppc64-dev/2006-March/008275.html
The first patch has been set aside as not essential, and the other two
have been combined. This is a bug fix that will hopefully make 2.6.16.
This has been tested for P5IOC and non-P5IOC slots.
Thanks-
John
diff -puN arch/powerpc/kernel/rtas_pci.c~move_init_phb_dyn arch/powerpc/kernel/rtas_pci.c
--- 2_6_p5_2/arch/powerpc/kernel/rtas_pci.c~move_init_phb_dyn 2006-03-14 17:28:18.000000000 -0600
+++ 2_6_p5_2-johnrose/arch/powerpc/kernel/rtas_pci.c 2006-03-14 17:29:25.000000000 -0600
@@ -280,8 +280,7 @@ static int phb_set_bus_ranges(struct dev
return 0;
}
-static int __devinit setup_phb(struct device_node *dev,
- struct pci_controller *phb)
+int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb)
{
if (is_python(dev))
python_countermeasures(dev);
@@ -359,27 +358,6 @@ unsigned long __init find_and_init_phbs(
return 0;
}
-struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
-{
- struct pci_controller *phb;
- int primary;
-
- primary = list_empty(&hose_list);
- phb = pcibios_alloc_controller(dn);
- if (!phb)
- return NULL;
- setup_phb(dn, phb);
- pci_process_bridge_OF_ranges(phb, dn, primary);
-
- pci_setup_phb_io_dynamic(phb, primary);
-
- pci_devs_phb_init_dynamic(phb);
- scan_phb(phb);
-
- return phb;
-}
-EXPORT_SYMBOL(init_phb_dynamic);
-
/* RPA-specific bits for removing PHBs */
int pcibios_remove_root_bus(struct pci_controller *phb)
{
diff -puN arch/powerpc/platforms/pseries/pci_dlpar.c~move_init_phb_dyn arch/powerpc/platforms/pseries/pci_dlpar.c
--- 2_6_p5_2/arch/powerpc/platforms/pseries/pci_dlpar.c~move_init_phb_dyn 2006-03-14 17:28:18.000000000 -0600
+++ 2_6_p5_2-johnrose/arch/powerpc/platforms/pseries/pci_dlpar.c 2006-03-14 17:37:09.000000000 -0600
@@ -27,6 +27,7 @@
#include <linux/pci.h>
#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
static struct pci_bus *
find_bus_among_children(struct pci_bus *bus,
@@ -179,3 +180,30 @@ pcibios_add_pci_devices(struct pci_bus *
}
}
EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
+
+struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
+{
+ struct pci_controller *phb;
+ int primary;
+
+ primary = list_empty(&hose_list);
+ phb = pcibios_alloc_controller(dn);
+ if (!phb)
+ return NULL;
+ setup_phb(dn, phb);
+ pci_process_bridge_OF_ranges(phb, dn, 0);
+
+ pci_setup_phb_io_dynamic(phb, primary);
+
+ pci_devs_phb_init_dynamic(phb);
+
+ if (dn->child)
+ eeh_add_device_tree_early(dn);
+
+ scan_phb(phb);
+ pcibios_fixup_new_pci_devices(phb->bus, 0);
+ pci_bus_add_devices(phb->bus);
+
+ return phb;
+}
+EXPORT_SYMBOL_GPL(init_phb_dynamic);
diff -puN include/asm-powerpc/ppc-pci.h~move_init_phb_dyn include/asm-powerpc/ppc-pci.h
--- 2_6_p5_2/include/asm-powerpc/ppc-pci.h~move_init_phb_dyn 2006-03-14 17:28:18.000000000 -0600
+++ 2_6_p5_2-johnrose/include/asm-powerpc/ppc-pci.h 2006-03-14 17:28:18.000000000 -0600
@@ -38,6 +38,7 @@ void *traverse_pci_devices(struct device
void pci_devs_phb_init(void);
void pci_devs_phb_init_dynamic(struct pci_controller *phb);
+int setup_phb(struct device_node *dev, struct pci_controller *phb);
void __devinit scan_phb(struct pci_controller *hose);
/* From rtas_pci.h */
diff -puN arch/powerpc/kernel/pci_64.c~move_init_phb_dyn arch/powerpc/kernel/pci_64.c
--- 2_6_p5_2/arch/powerpc/kernel/pci_64.c~move_init_phb_dyn 2006-03-14 17:37:01.000000000 -0600
+++ 2_6_p5_2-johnrose/arch/powerpc/kernel/pci_64.c 2006-03-14 17:37:09.000000000 -0600
@@ -589,7 +589,6 @@ void __devinit scan_phb(struct pci_contr
#endif /* CONFIG_PPC_MULTIPLATFORM */
if (mode == PCI_PROBE_NORMAL)
hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
- pci_bus_add_devices(bus);
}
static int __init pcibios_init(void)
@@ -608,8 +607,10 @@ static int __init pcibios_init(void)
printk("PCI: Probing PCI hardware\n");
/* Scan all of the recorded PCI controllers. */
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
scan_phb(hose);
+ pci_bus_add_devices(hose->bus);
+ }
#ifndef CONFIG_PPC_ISERIES
if (pci_probe_only)
_
More information about the Linuxppc64-dev
mailing list