]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
PCI/portdrv: Add runtime PM hooks for port service drivers
authorMika Westerberg <mika.westerberg@linux.intel.com>
Thu, 27 Sep 2018 21:41:48 +0000 (16:41 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 2 Oct 2018 21:04:40 +0000 (16:04 -0500)
When PCIe port is runtime suspended/resumed some extra steps might be
needed to be executed from the port service driver side. For instance we
may need to disable PCIe hotplug interrupt to prevent it from triggering
immediately when PCIe link to the downstream component goes down.

To make the above possible add optional ->runtime_suspend() and
->runtime_resume() callbacks to struct pcie_port_service_driver and call
them for each port service in runtime suspend/resume callbacks of portdrv.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
[bhelgaas: adjust "slot->state" for 5790a9c78e78 ("PCI: pciehp: Unify
controller and slot structs")]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/pci/pcie/portdrv.h
drivers/pci/pcie/portdrv_core.c
drivers/pci/pcie/portdrv_pci.c

index 2498b2d340095e53cf2191bdf992ab866139614a..abfdc2ae797910775a9daead3f69dff469563031 100644 (file)
@@ -76,6 +76,8 @@ struct pcie_port_service_driver {
        int (*suspend) (struct pcie_device *dev);
        int (*resume_noirq) (struct pcie_device *dev);
        int (*resume) (struct pcie_device *dev);
+       int (*runtime_suspend) (struct pcie_device *dev);
+       int (*runtime_resume) (struct pcie_device *dev);
 
        /* Device driver may resume normal operations */
        void (*error_resume)(struct pci_dev *dev);
@@ -109,6 +111,8 @@ int pcie_port_device_register(struct pci_dev *dev);
 int pcie_port_device_suspend(struct device *dev);
 int pcie_port_device_resume_noirq(struct device *dev);
 int pcie_port_device_resume(struct device *dev);
+int pcie_port_device_runtime_suspend(struct device *dev);
+int pcie_port_device_runtime_resume(struct device *dev);
 #endif
 void pcie_port_device_remove(struct pci_dev *dev);
 int __must_check pcie_port_bus_register(void);
index 7c37d815229e9ee20e7732695dda58344fc77a20..6542c48c7f593567c511d9783631c1d85b65e8d9 100644 (file)
@@ -395,6 +395,26 @@ int pcie_port_device_resume(struct device *dev)
        size_t off = offsetof(struct pcie_port_service_driver, resume);
        return device_for_each_child(dev, &off, pm_iter);
 }
+
+/**
+ * pcie_port_device_runtime_suspend - runtime suspend port services
+ * @dev: PCI Express port to handle
+ */
+int pcie_port_device_runtime_suspend(struct device *dev)
+{
+       size_t off = offsetof(struct pcie_port_service_driver, runtime_suspend);
+       return device_for_each_child(dev, &off, pm_iter);
+}
+
+/**
+ * pcie_port_device_runtime_resume - runtime resume port services
+ * @dev: PCI Express port to handle
+ */
+int pcie_port_device_runtime_resume(struct device *dev)
+{
+       size_t off = offsetof(struct pcie_port_service_driver, runtime_resume);
+       return device_for_each_child(dev, &off, pm_iter);
+}
 #endif /* PM */
 
 static int remove_iter(struct device *dev, void *data)
index a1379151c565d6204de5ed1a59805c44bd76e6f4..0acca3596807afbbcd392fc1537a9dd2048704dc 100644 (file)
@@ -45,12 +45,10 @@ __setup("pcie_ports=", pcie_port_setup);
 #ifdef CONFIG_PM
 static int pcie_port_runtime_suspend(struct device *dev)
 {
-       return to_pci_dev(dev)->bridge_d3 ? 0 : -EBUSY;
-}
+       if (!to_pci_dev(dev)->bridge_d3)
+               return -EBUSY;
 
-static int pcie_port_runtime_resume(struct device *dev)
-{
-       return 0;
+       return pcie_port_device_runtime_suspend(dev);
 }
 
 static int pcie_port_runtime_idle(struct device *dev)
@@ -73,7 +71,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
        .restore_noirq  = pcie_port_device_resume_noirq,
        .restore        = pcie_port_device_resume,
        .runtime_suspend = pcie_port_runtime_suspend,
-       .runtime_resume = pcie_port_runtime_resume,
+       .runtime_resume = pcie_port_device_runtime_resume,
        .runtime_idle   = pcie_port_runtime_idle,
 };