PCI: portdrv: Initialize service drivers directly
authorKeith Busch <keith.busch@intel.com>
Thu, 20 Sep 2018 16:27:06 +0000 (10:27 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 20 Sep 2018 17:05:54 +0000 (12:05 -0500)
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>
drivers/pci/hotplug/pciehp_core.c
drivers/pci/pcie/aer.c
drivers/pci/pcie/dpc.c
drivers/pci/pcie/pme.c
drivers/pci/pcie/portdrv.h
drivers/pci/pcie/portdrv_pci.c

index 68b20e667764a3cc11458eff5f69822140011cc1..944047976569e68c6713d8ef5e10d65cc19e1870 100644 (file)
@@ -287,7 +287,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;
 
@@ -298,4 +298,3 @@ static int __init pcied_init(void)
 
        return retval;
 }
-device_initcall(pcied_init);
index 83180edd6ed470d5fa57f08833e8178d91a18d92..637d638f73da5edf1f327e1bc81892df29ec3147 100644 (file)
@@ -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);
index f03279fc87cd5978650b0085ad49019047f8bafd..a1fd16bf1cab2db66129de96591f81cae13b55d9 100644 (file)
@@ -282,8 +282,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);
index 3ed67676ea2a16d14f41c9710d7b3a8edfd3b157..1a8b85051b1b5b3ff5cf1362e4a7fc77e0ab6f53 100644 (file)
@@ -446,8 +446,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);
index d59afa42fc14ba3702b26acb704dc9726442360d..2498b2d340095e53cf2191bdf992ab866139614a 100644 (file)
 
 #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)
 
index eef22dc29140cd104318de4f332ab1dbb3e88034..23a5a0c2c3fe9021252475e97eef03789d7d0d5d 100644 (file)
@@ -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);