[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>
This commit is contained in:
parent
920573bd03
commit
92eb4602eb
4 changed files with 33 additions and 25 deletions
|
@ -589,7 +589,6 @@ void __devinit scan_phb(struct pci_controller *hose)
|
||||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||||
if (mode == PCI_PROBE_NORMAL)
|
if (mode == PCI_PROBE_NORMAL)
|
||||||
hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
|
hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
|
||||||
pci_bus_add_devices(bus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init pcibios_init(void)
|
static int __init pcibios_init(void)
|
||||||
|
@ -608,8 +607,10 @@ static int __init pcibios_init(void)
|
||||||
printk("PCI: Probing PCI hardware\n");
|
printk("PCI: Probing PCI hardware\n");
|
||||||
|
|
||||||
/* Scan all of the recorded PCI controllers. */
|
/* 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);
|
scan_phb(hose);
|
||||||
|
pci_bus_add_devices(hose->bus);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_PPC_ISERIES
|
#ifndef CONFIG_PPC_ISERIES
|
||||||
if (pci_probe_only)
|
if (pci_probe_only)
|
||||||
|
|
|
@ -280,8 +280,7 @@ static int phb_set_bus_ranges(struct device_node *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit setup_phb(struct device_node *dev,
|
int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb)
|
||||||
struct pci_controller *phb)
|
|
||||||
{
|
{
|
||||||
if (is_python(dev))
|
if (is_python(dev))
|
||||||
python_countermeasures(dev);
|
python_countermeasures(dev);
|
||||||
|
@ -359,27 +358,6 @@ unsigned long __init find_and_init_phbs(void)
|
||||||
return 0;
|
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 */
|
/* RPA-specific bits for removing PHBs */
|
||||||
int pcibios_remove_root_bus(struct pci_controller *phb)
|
int pcibios_remove_root_bus(struct pci_controller *phb)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <asm/pci-bridge.h>
|
#include <asm/pci-bridge.h>
|
||||||
|
#include <asm/ppc-pci.h>
|
||||||
|
|
||||||
static struct pci_bus *
|
static struct pci_bus *
|
||||||
find_bus_among_children(struct pci_bus *bus,
|
find_bus_among_children(struct pci_bus *bus,
|
||||||
|
@ -179,3 +180,30 @@ pcibios_add_pci_devices(struct pci_bus * bus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
|
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);
|
||||||
|
|
|
@ -38,6 +38,7 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
|
||||||
|
|
||||||
void pci_devs_phb_init(void);
|
void pci_devs_phb_init(void);
|
||||||
void pci_devs_phb_init_dynamic(struct pci_controller *phb);
|
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);
|
void __devinit scan_phb(struct pci_controller *hose);
|
||||||
|
|
||||||
/* From rtas_pci.h */
|
/* From rtas_pci.h */
|
||||||
|
|
Loading…
Reference in a new issue