Commit 395ee2a2 authored by Oliver O'Halloran's avatar Oliver O'Halloran Committed by Michael Ellerman

powerpc/eeh: Move EEH initialisation to an arch initcall

The initialisation of EEH mostly happens in a core_initcall_sync initcall,
followed by registering a bus notifier later on in an arch_initcall.
Anything involving initcall dependecies is mostly incomprehensible unless
you've spent a while staring at code so here's the full sequence:

ppc_md.setup_arch       <-- pci_controllers are created here

...time passes...

core_initcall           <-- pci_dns are created from DT nodes
core_initcall_sync      <-- platforms call eeh_init()
postcore_initcall       <-- PCI bus type is registered
postcore_initcall_sync
arch_initcall           <-- EEH pci_bus notifier registered
subsys_initcall         <-- PHBs are scanned here

There's no real requirement to do the EEH setup at the core_initcall_sync
level. It just needs to be done after pci_dn's are created and before we
start scanning PHBs. Simplify the flow a bit by moving the platform EEH
inititalisation to an arch_initcall so we can fold the bus notifier
registration into eeh_init().
Signed-off-by: default avatarOliver O'Halloran <oohall@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200918093050.37344-5-oohall@gmail.com
parent 5d69e46a
......@@ -940,6 +940,30 @@ static struct notifier_block eeh_reboot_nb = {
.notifier_call = eeh_reboot_notifier,
};
static int eeh_device_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
struct device *dev = data;
switch (action) {
/*
* Note: It's not possible to perform EEH device addition (i.e.
* {pseries,pnv}_pcibios_bus_add_device()) here because it depends on
* the device's resources, which have not yet been set up.
*/
case BUS_NOTIFY_DEL_DEVICE:
eeh_remove_device(to_pci_dev(dev));
break;
default:
break;
}
return NOTIFY_DONE;
}
static struct notifier_block eeh_device_nb = {
.notifier_call = eeh_device_notifier,
};
/**
* eeh_init - System wide EEH initialization
*
......@@ -960,7 +984,14 @@ int eeh_init(struct eeh_ops *ops)
/* Register reboot notifier */
ret = register_reboot_notifier(&eeh_reboot_nb);
if (ret) {
pr_warn("%s: Failed to register notifier (%d)\n",
pr_warn("%s: Failed to register reboot notifier (%d)\n",
__func__, ret);
return ret;
}
ret = bus_register_notifier(&pci_bus_type, &eeh_device_nb);
if (ret) {
pr_warn("%s: Failed to register bus notifier (%d)\n",
__func__, ret);
return ret;
}
......@@ -975,37 +1006,6 @@ int eeh_init(struct eeh_ops *ops)
return eeh_event_init();
}
static int eeh_device_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
struct device *dev = data;
switch (action) {
/*
* Note: It's not possible to perform EEH device addition (i.e.
* {pseries,pnv}_pcibios_bus_add_device()) here because it depends on
* the device's resources, which have not yet been set up.
*/
case BUS_NOTIFY_DEL_DEVICE:
eeh_remove_device(to_pci_dev(dev));
break;
default:
break;
}
return NOTIFY_DONE;
}
static struct notifier_block eeh_device_nb = {
.notifier_call = eeh_device_notifier,
};
static __init int eeh_set_bus_notifier(void)
{
bus_register_notifier(&pci_bus_type, &eeh_device_nb);
return 0;
}
arch_initcall(eeh_set_bus_notifier);
/**
* eeh_probe_device() - Perform EEH initialization for the indicated pci device
* @dev: pci device for which to set up EEH
......
......@@ -1721,4 +1721,4 @@ static int __init eeh_powernv_init(void)
return ret;
}
machine_core_initcall_sync(powernv, eeh_powernv_init);
machine_arch_initcall(powernv, eeh_powernv_init);
......@@ -985,4 +985,4 @@ static int __init eeh_pseries_init(void)
ret);
return ret;
}
machine_core_initcall_sync(pseries, eeh_pseries_init);
machine_arch_initcall(pseries, eeh_pseries_init);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment