Make powernv and pseries use ppc_mc.discover_phbs. These two platforms need
to be done together because they both depends 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  and 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 creations 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 <ooh...@gmail.com>
---
 arch/powerpc/kernel/pci_dn.c              | 22 ----------------------
 arch/powerpc/platforms/powernv/pci-ioda.c |  3 +++
 arch/powerpc/platforms/powernv/setup.c    |  4 +---
 arch/powerpc/platforms/pseries/setup.c    |  7 +++++--
 4 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 54e240597fd9..61571ae23953 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -481,28 +481,6 @@ void pci_devs_phb_init_dynamic(struct pci_controller *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)
 {
        struct pci_dn *pdn;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 023a4f987bb2..987654a08e2e 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -3184,6 +3184,9 @@ static void __init pnv_pci_init_ioda_phb(struct 
device_node *np,
        /* Remove M64 resource if we can't configure it successfully */
        if (!phb->init_m64 || phb->init_m64(phb))
                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)
diff --git a/arch/powerpc/platforms/powernv/setup.c 
b/arch/powerpc/platforms/powernv/setup.c
index 7fcb88623081..a4d6d41b1155 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -140,9 +140,6 @@ static void __init pnv_setup_arch(void)
        /* Initialize SMP */
        pnv_smp_init();
 
-       /* Setup PCI */
-       pnv_pci_init();
-
        /* Setup RTC and NVRAM callbacks */
        if (firmware_has_feature(FW_FEATURE_OPAL))
                opal_nvram_init();
@@ -500,6 +497,7 @@ define_machine(powernv) {
        .init_IRQ               = pnv_init_IRQ,
        .show_cpuinfo           = pnv_show_cpuinfo,
        .get_proc_freq          = pnv_get_proc_freq,
+       .discover_phbs          = pnv_pci_init,
        .progress               = pnv_progress,
        .machine_shutdown       = pnv_shutdown,
        .power_save             = NULL,
diff --git a/arch/powerpc/platforms/pseries/setup.c 
b/arch/powerpc/platforms/pseries/setup.c
index 2f4ee0a90284..d0bf487fadf5 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -463,7 +463,7 @@ void pseries_little_endian_exceptions(void)
 }
 #endif
 
-static void __init find_and_init_phbs(void)
+static void __init pSeries_discover_phbs(void)
 {
        struct device_node *node;
        struct pci_controller *phb;
@@ -481,6 +481,9 @@ static void __init find_and_init_phbs(void)
                pci_process_bridge_OF_ranges(phb, node, 0);
                isa_bridge_find_early(phb);
                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);
@@ -771,7 +774,6 @@ static void __init pSeries_setup_arch(void)
 
        /* Find and initialize PCI host bridges */
        init_pci_config_tokens();
-       find_and_init_phbs();
        of_reconfig_notifier_register(&pci_dn_reconfig_nb);
 
        pSeries_nvram_init();
@@ -1035,6 +1037,7 @@ define_machine(pseries) {
        .init_IRQ               = pseries_init_irq,
        .show_cpuinfo           = pSeries_show_cpuinfo,
        .log_error              = pSeries_log_error,
+       .discover_phbs          = pSeries_discover_phbs,
        .pcibios_fixup          = pSeries_final_fixup,
        .restart                = rtas_restart,
        .halt                   = rtas_halt,
-- 
2.26.2

Reply via email to