mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 06:04:23 +08:00
powerpc/pci: Move PHB discovery for PCI_DN using platforms
Make powernv, pseries, powermac and maple use ppc_mc.discover_phbs. These platforms need to be done together because they all depend on pci_dn's being created from the DT. The pci_dn contains a pointer to the relevant pci_controller so they need to be created after the pci_controller structures are available, but before PCI devices are scanned. Currently this ordering is provided by initcalls and the sequence is: 1. PHBs are discovered (setup_arch) (early boot, pre-initcalls) 2. pci_dn are created from the unflattended DT (core initcall) 3. PHBs are scanned pcibios_init() (subsys initcall) The new ppc_md.discover_phbs() function is also a core_initcall so we can't guarantee ordering between the creation of pci_controllers and the creation of pci_dn's which require a pci_controller. We could use the postcore, or core_sync initcall levels, but it's cleaner to just move the pci_dn setup into the per-PHB inits which occur inside of .discover_phb() for these platforms. This brings the boot-time path in line with the PHB hotplug path that is used for pseries DLPAR operations too. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> [mpe: Squash powermac & maple in to avoid breakage those platforms, convert memblock allocs to use kmalloc to avoid warnings] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20201103043523.916109-2-oohall@gmail.com
This commit is contained in:
parent
5537fcb319
commit
fbbefb3202
@ -481,28 +481,6 @@ void pci_devs_phb_init_dynamic(struct pci_controller *phb)
|
|||||||
pci_traverse_device_nodes(dn, add_pdn, phb);
|
pci_traverse_device_nodes(dn, add_pdn, phb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* pci_devs_phb_init - Initialize phbs and pci devs under them.
|
|
||||||
*
|
|
||||||
* This routine walks over all phb's (pci-host bridges) on the
|
|
||||||
* system, and sets up assorted pci-related structures
|
|
||||||
* (including pci info in the device node structs) for each
|
|
||||||
* pci device found underneath. This routine runs once,
|
|
||||||
* early in the boot sequence.
|
|
||||||
*/
|
|
||||||
static int __init pci_devs_phb_init(void)
|
|
||||||
{
|
|
||||||
struct pci_controller *phb, *tmp;
|
|
||||||
|
|
||||||
/* This must be done first so the device nodes have valid pci info! */
|
|
||||||
list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
|
|
||||||
pci_devs_phb_init_dynamic(phb);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
core_initcall(pci_devs_phb_init);
|
|
||||||
|
|
||||||
static void pci_dev_pdn_setup(struct pci_dev *pdev)
|
static void pci_dev_pdn_setup(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct pci_dn *pdn;
|
struct pci_dn *pdn;
|
||||||
|
@ -536,6 +536,9 @@ static int __init maple_add_bridge(struct device_node *dev)
|
|||||||
/* Check for legacy IOs */
|
/* Check for legacy IOs */
|
||||||
isa_bridge_find_early(hose);
|
isa_bridge_find_early(hose);
|
||||||
|
|
||||||
|
/* create pci_dn's for DT nodes under this PHB */
|
||||||
|
pci_devs_phb_init_dynamic(hose);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,9 +179,6 @@ static void __init maple_setup_arch(void)
|
|||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
smp_ops = &maple_smp_ops;
|
smp_ops = &maple_smp_ops;
|
||||||
#endif
|
#endif
|
||||||
/* Lookup PCI hosts */
|
|
||||||
maple_pci_init();
|
|
||||||
|
|
||||||
maple_use_rtas_reboot_and_halt_if_present();
|
maple_use_rtas_reboot_and_halt_if_present();
|
||||||
|
|
||||||
printk(KERN_DEBUG "Using native/NAP idle loop\n");
|
printk(KERN_DEBUG "Using native/NAP idle loop\n");
|
||||||
@ -351,6 +348,7 @@ define_machine(maple) {
|
|||||||
.name = "Maple",
|
.name = "Maple",
|
||||||
.probe = maple_probe,
|
.probe = maple_probe,
|
||||||
.setup_arch = maple_setup_arch,
|
.setup_arch = maple_setup_arch,
|
||||||
|
.discover_phbs = maple_pci_init,
|
||||||
.init_IRQ = maple_init_IRQ,
|
.init_IRQ = maple_init_IRQ,
|
||||||
.pci_irq_fixup = maple_pci_irq_fixup,
|
.pci_irq_fixup = maple_pci_irq_fixup,
|
||||||
.pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
|
.pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
|
||||||
|
@ -850,6 +850,10 @@ static int __init pmac_add_bridge(struct device_node *dev)
|
|||||||
/* Fixup "bus-range" OF property */
|
/* Fixup "bus-range" OF property */
|
||||||
fixup_bus_range(dev);
|
fixup_bus_range(dev);
|
||||||
|
|
||||||
|
/* create pci_dn's for DT nodes under this PHB */
|
||||||
|
if (IS_ENABLED(CONFIG_PPC64))
|
||||||
|
pci_devs_phb_init_dynamic(hose);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,9 +298,6 @@ static void __init pmac_setup_arch(void)
|
|||||||
of_node_put(ic);
|
of_node_put(ic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup PCI hosts */
|
|
||||||
pmac_pci_init();
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC32
|
#ifdef CONFIG_PPC32
|
||||||
ohare_init();
|
ohare_init();
|
||||||
l2cr_init();
|
l2cr_init();
|
||||||
@ -600,6 +597,7 @@ define_machine(powermac) {
|
|||||||
.name = "PowerMac",
|
.name = "PowerMac",
|
||||||
.probe = pmac_probe,
|
.probe = pmac_probe,
|
||||||
.setup_arch = pmac_setup_arch,
|
.setup_arch = pmac_setup_arch,
|
||||||
|
.discover_phbs = pmac_pci_init,
|
||||||
.show_cpuinfo = pmac_show_cpuinfo,
|
.show_cpuinfo = pmac_show_cpuinfo,
|
||||||
.init_IRQ = pmac_pic_init,
|
.init_IRQ = pmac_pic_init,
|
||||||
.get_irq = NULL, /* changed later */
|
.get_irq = NULL, /* changed later */
|
||||||
|
@ -2921,7 +2921,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
|||||||
phb_id = be64_to_cpup(prop64);
|
phb_id = be64_to_cpup(prop64);
|
||||||
pr_debug(" PHB-ID : 0x%016llx\n", phb_id);
|
pr_debug(" PHB-ID : 0x%016llx\n", phb_id);
|
||||||
|
|
||||||
phb = memblock_alloc(sizeof(*phb), SMP_CACHE_BYTES);
|
phb = kmalloc(sizeof(*phb), GFP_KERNEL);
|
||||||
if (!phb)
|
if (!phb)
|
||||||
panic("%s: Failed to allocate %zu bytes\n", __func__,
|
panic("%s: Failed to allocate %zu bytes\n", __func__,
|
||||||
sizeof(*phb));
|
sizeof(*phb));
|
||||||
@ -2970,7 +2970,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
|||||||
else
|
else
|
||||||
phb->diag_data_size = PNV_PCI_DIAG_BUF_SIZE;
|
phb->diag_data_size = PNV_PCI_DIAG_BUF_SIZE;
|
||||||
|
|
||||||
phb->diag_data = memblock_alloc(phb->diag_data_size, SMP_CACHE_BYTES);
|
phb->diag_data = kmalloc(phb->diag_data_size, GFP_KERNEL);
|
||||||
if (!phb->diag_data)
|
if (!phb->diag_data)
|
||||||
panic("%s: Failed to allocate %u bytes\n", __func__,
|
panic("%s: Failed to allocate %u bytes\n", __func__,
|
||||||
phb->diag_data_size);
|
phb->diag_data_size);
|
||||||
@ -3032,9 +3032,10 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
|||||||
}
|
}
|
||||||
pemap_off = size;
|
pemap_off = size;
|
||||||
size += phb->ioda.total_pe_num * sizeof(struct pnv_ioda_pe);
|
size += phb->ioda.total_pe_num * sizeof(struct pnv_ioda_pe);
|
||||||
aux = memblock_alloc(size, SMP_CACHE_BYTES);
|
aux = kmalloc(size, GFP_KERNEL);
|
||||||
if (!aux)
|
if (!aux)
|
||||||
panic("%s: Failed to allocate %lu bytes\n", __func__, size);
|
panic("%s: Failed to allocate %lu bytes\n", __func__, size);
|
||||||
|
|
||||||
phb->ioda.pe_alloc = aux;
|
phb->ioda.pe_alloc = aux;
|
||||||
phb->ioda.m64_segmap = aux + m64map_off;
|
phb->ioda.m64_segmap = aux + m64map_off;
|
||||||
phb->ioda.m32_segmap = aux + m32map_off;
|
phb->ioda.m32_segmap = aux + m32map_off;
|
||||||
@ -3161,6 +3162,9 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
|
|||||||
/* Remove M64 resource if we can't configure it successfully */
|
/* Remove M64 resource if we can't configure it successfully */
|
||||||
if (!phb->init_m64 || phb->init_m64(phb))
|
if (!phb->init_m64 || phb->init_m64(phb))
|
||||||
hose->mem_resources[1].flags = 0;
|
hose->mem_resources[1].flags = 0;
|
||||||
|
|
||||||
|
/* create pci_dn's for DT nodes under this PHB */
|
||||||
|
pci_devs_phb_init_dynamic(hose);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init pnv_pci_init_ioda2_phb(struct device_node *np)
|
void __init pnv_pci_init_ioda2_phb(struct device_node *np)
|
||||||
|
@ -180,9 +180,6 @@ static void __init pnv_setup_arch(void)
|
|||||||
/* Initialize SMP */
|
/* Initialize SMP */
|
||||||
pnv_smp_init();
|
pnv_smp_init();
|
||||||
|
|
||||||
/* Setup PCI */
|
|
||||||
pnv_pci_init();
|
|
||||||
|
|
||||||
/* Setup RTC and NVRAM callbacks */
|
/* Setup RTC and NVRAM callbacks */
|
||||||
if (firmware_has_feature(FW_FEATURE_OPAL))
|
if (firmware_has_feature(FW_FEATURE_OPAL))
|
||||||
opal_nvram_init();
|
opal_nvram_init();
|
||||||
@ -547,6 +544,7 @@ define_machine(powernv) {
|
|||||||
.init_IRQ = pnv_init_IRQ,
|
.init_IRQ = pnv_init_IRQ,
|
||||||
.show_cpuinfo = pnv_show_cpuinfo,
|
.show_cpuinfo = pnv_show_cpuinfo,
|
||||||
.get_proc_freq = pnv_get_proc_freq,
|
.get_proc_freq = pnv_get_proc_freq,
|
||||||
|
.discover_phbs = pnv_pci_init,
|
||||||
.progress = pnv_progress,
|
.progress = pnv_progress,
|
||||||
.machine_shutdown = pnv_shutdown,
|
.machine_shutdown = pnv_shutdown,
|
||||||
.power_save = NULL,
|
.power_save = NULL,
|
||||||
|
@ -463,7 +463,7 @@ void pseries_little_endian_exceptions(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __init find_and_init_phbs(void)
|
static void __init pSeries_discover_phbs(void)
|
||||||
{
|
{
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
struct pci_controller *phb;
|
struct pci_controller *phb;
|
||||||
@ -481,6 +481,9 @@ static void __init find_and_init_phbs(void)
|
|||||||
pci_process_bridge_OF_ranges(phb, node, 0);
|
pci_process_bridge_OF_ranges(phb, node, 0);
|
||||||
isa_bridge_find_early(phb);
|
isa_bridge_find_early(phb);
|
||||||
phb->controller_ops = pseries_pci_controller_ops;
|
phb->controller_ops = pseries_pci_controller_ops;
|
||||||
|
|
||||||
|
/* create pci_dn's for DT nodes under this PHB */
|
||||||
|
pci_devs_phb_init_dynamic(phb);
|
||||||
}
|
}
|
||||||
|
|
||||||
of_node_put(root);
|
of_node_put(root);
|
||||||
@ -786,7 +789,6 @@ static void __init pSeries_setup_arch(void)
|
|||||||
|
|
||||||
/* Find and initialize PCI host bridges */
|
/* Find and initialize PCI host bridges */
|
||||||
init_pci_config_tokens();
|
init_pci_config_tokens();
|
||||||
find_and_init_phbs();
|
|
||||||
of_reconfig_notifier_register(&pci_dn_reconfig_nb);
|
of_reconfig_notifier_register(&pci_dn_reconfig_nb);
|
||||||
|
|
||||||
pSeries_nvram_init();
|
pSeries_nvram_init();
|
||||||
@ -1050,6 +1052,7 @@ define_machine(pseries) {
|
|||||||
.init_IRQ = pseries_init_irq,
|
.init_IRQ = pseries_init_irq,
|
||||||
.show_cpuinfo = pSeries_show_cpuinfo,
|
.show_cpuinfo = pSeries_show_cpuinfo,
|
||||||
.log_error = pSeries_log_error,
|
.log_error = pSeries_log_error,
|
||||||
|
.discover_phbs = pSeries_discover_phbs,
|
||||||
.pcibios_fixup = pSeries_final_fixup,
|
.pcibios_fixup = pSeries_final_fixup,
|
||||||
.restart = rtas_restart,
|
.restart = rtas_restart,
|
||||||
.halt = rtas_halt,
|
.halt = rtas_halt,
|
||||||
|
Loading…
Reference in New Issue
Block a user