| From 73c93c2ef97576f83880cb93d6fb87e3663064fb Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 20 Sep 2018 10:27:06 -0600 |
| Subject: PCI: portdrv: Initialize service drivers directly |
| |
| From: Keith Busch <keith.busch@intel.com> |
| |
| [ Upstream commit c29de84149aba5f74e87b6491c13ac7203c12f55 ] |
| |
| The PCI port driver saves the PCI state after initializing the device with |
| the applicable service devices. This was, however, before the service |
| drivers were even registered because PCI probe happens before the |
| device_initcall initialized those service drivers. The config space state |
| that the services set up were not being saved. The end result would cause |
| PCI devices to not react to events that the drivers think they did if the |
| PCI state ever needed to be restored. |
| |
| Fix this by changing the service drivers from using the init calls to |
| having the portdrv driver calling the services directly. This will get the |
| state saved as desired, while making the relationship between the port |
| driver and the services under it more explicit in the code. |
| |
| Signed-off-by: Keith Busch <keith.busch@intel.com> |
| Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> |
| Reviewed-by: Sinan Kaya <okaya@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/pci/hotplug/pciehp_core.c | 3 +-- |
| drivers/pci/pcie/aer.c | 3 +-- |
| drivers/pci/pcie/dpc.c | 3 +-- |
| drivers/pci/pcie/pme.c | 3 +-- |
| drivers/pci/pcie/portdrv.h | 24 ++++++++++++++++++++++++ |
| drivers/pci/pcie/portdrv_pci.c | 9 +++++++++ |
| 6 files changed, 37 insertions(+), 8 deletions(-) |
| |
| diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c |
| index ec48c9433ae50..518c46f8e63b7 100644 |
| --- a/drivers/pci/hotplug/pciehp_core.c |
| +++ b/drivers/pci/hotplug/pciehp_core.c |
| @@ -348,7 +348,7 @@ static struct pcie_port_service_driver hpdriver_portdrv = { |
| #endif /* PM */ |
| }; |
| |
| -static int __init pcied_init(void) |
| +int __init pcie_hp_init(void) |
| { |
| int retval = 0; |
| |
| @@ -359,4 +359,3 @@ static int __init pcied_init(void) |
| |
| return retval; |
| } |
| -device_initcall(pcied_init); |
| diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c |
| index 83180edd6ed47..637d638f73da5 100644 |
| --- a/drivers/pci/pcie/aer.c |
| +++ b/drivers/pci/pcie/aer.c |
| @@ -1569,10 +1569,9 @@ static struct pcie_port_service_driver aerdriver = { |
| * |
| * Invoked when AER root service driver is loaded. |
| */ |
| -static int __init aer_service_init(void) |
| +int __init pcie_aer_init(void) |
| { |
| if (!pci_aer_available() || aer_acpi_firmware_first()) |
| return -ENXIO; |
| return pcie_port_service_register(&aerdriver); |
| } |
| -device_initcall(aer_service_init); |
| diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c |
| index 1908dd2978d3c..118b5bcae42ea 100644 |
| --- a/drivers/pci/pcie/dpc.c |
| +++ b/drivers/pci/pcie/dpc.c |
| @@ -307,8 +307,7 @@ static struct pcie_port_service_driver dpcdriver = { |
| .reset_link = dpc_reset_link, |
| }; |
| |
| -static int __init dpc_service_init(void) |
| +int __init pcie_dpc_init(void) |
| { |
| return pcie_port_service_register(&dpcdriver); |
| } |
| -device_initcall(dpc_service_init); |
| diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c |
| index 6ac17f0c40775..54d593d10396f 100644 |
| --- a/drivers/pci/pcie/pme.c |
| +++ b/drivers/pci/pcie/pme.c |
| @@ -455,8 +455,7 @@ static struct pcie_port_service_driver pcie_pme_driver = { |
| /** |
| * pcie_pme_service_init - Register the PCIe PME service driver. |
| */ |
| -static int __init pcie_pme_service_init(void) |
| +int __init pcie_pme_init(void) |
| { |
| return pcie_port_service_register(&pcie_pme_driver); |
| } |
| -device_initcall(pcie_pme_service_init); |
| diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h |
| index d59afa42fc14b..2498b2d340095 100644 |
| --- a/drivers/pci/pcie/portdrv.h |
| +++ b/drivers/pci/pcie/portdrv.h |
| @@ -23,6 +23,30 @@ |
| |
| #define PCIE_PORT_DEVICE_MAXSERVICES 4 |
| |
| +#ifdef CONFIG_PCIEAER |
| +int pcie_aer_init(void); |
| +#else |
| +static inline int pcie_aer_init(void) { return 0; } |
| +#endif |
| + |
| +#ifdef CONFIG_HOTPLUG_PCI_PCIE |
| +int pcie_hp_init(void); |
| +#else |
| +static inline int pcie_hp_init(void) { return 0; } |
| +#endif |
| + |
| +#ifdef CONFIG_PCIE_PME |
| +int pcie_pme_init(void); |
| +#else |
| +static inline int pcie_pme_init(void) { return 0; } |
| +#endif |
| + |
| +#ifdef CONFIG_PCIE_DPC |
| +int pcie_dpc_init(void); |
| +#else |
| +static inline int pcie_dpc_init(void) { return 0; } |
| +#endif |
| + |
| /* Port Type */ |
| #define PCIE_ANY_PORT (~0) |
| |
| diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c |
| index eef22dc29140c..23a5a0c2c3fe9 100644 |
| --- a/drivers/pci/pcie/portdrv_pci.c |
| +++ b/drivers/pci/pcie/portdrv_pci.c |
| @@ -226,11 +226,20 @@ static const struct dmi_system_id pcie_portdrv_dmi_table[] __initconst = { |
| {} |
| }; |
| |
| +static void __init pcie_init_services(void) |
| +{ |
| + pcie_aer_init(); |
| + pcie_pme_init(); |
| + pcie_dpc_init(); |
| + pcie_hp_init(); |
| +} |
| + |
| static int __init pcie_portdrv_init(void) |
| { |
| if (pcie_ports_disabled) |
| return -EACCES; |
| |
| + pcie_init_services(); |
| dmi_check_system(pcie_portdrv_dmi_table); |
| |
| return pci_register_driver(&pcie_portdriver); |
| -- |
| 2.20.1 |
| |