PCI: portdrv: Deduplicate PM callback iterator
authorLukas Wunner <lukas@wunner.de>
Thu, 19 Jul 2018 22:27:52 +0000 (17:27 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 31 Jul 2018 16:07:59 +0000 (11:07 -0500)
Replace suspend_iter() and resume_iter() with a single function pm_iter()
to allow addition of port service callbacks for further power management
phases without having to add another iterator each time.

No functional change intended.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/pcie/portdrv_core.c

index e0261ad4bcdd582d9be6e25ddc80b5c490c421ba..13a248575a14bef4e7f7ea8e1112e4fc63b22058 100644 (file)
@@ -353,14 +353,19 @@ error_disable:
 }
 
 #ifdef CONFIG_PM
-static int suspend_iter(struct device *dev, void *data)
+typedef int (*pcie_pm_callback_t)(struct pcie_device *);
+
+static int pm_iter(struct device *dev, void *data)
 {
        struct pcie_port_service_driver *service_driver;
+       size_t offset = *(size_t *)data;
+       pcie_pm_callback_t cb;
 
        if ((dev->bus == &pcie_port_bus_type) && dev->driver) {
                service_driver = to_service_driver(dev->driver);
-               if (service_driver->suspend)
-                       service_driver->suspend(to_pcie_device(dev));
+               cb = *(pcie_pm_callback_t *)((void *)service_driver + offset);
+               if (cb)
+                       return cb(to_pcie_device(dev));
        }
        return 0;
 }
@@ -371,20 +376,8 @@ static int suspend_iter(struct device *dev, void *data)
  */
 int pcie_port_device_suspend(struct device *dev)
 {
-       return device_for_each_child(dev, NULL, suspend_iter);
-}
-
-static int resume_iter(struct device *dev, void *data)
-{
-       struct pcie_port_service_driver *service_driver;
-
-       if ((dev->bus == &pcie_port_bus_type) &&
-           (dev->driver)) {
-               service_driver = to_service_driver(dev->driver);
-               if (service_driver->resume)
-                       service_driver->resume(to_pcie_device(dev));
-       }
-       return 0;
+       size_t off = offsetof(struct pcie_port_service_driver, suspend);
+       return device_for_each_child(dev, &off, pm_iter);
 }
 
 /**
@@ -393,7 +386,8 @@ static int resume_iter(struct device *dev, void *data)
  */
 int pcie_port_device_resume(struct device *dev)
 {
-       return device_for_each_child(dev, NULL, resume_iter);
+       size_t off = offsetof(struct pcie_port_service_driver, resume);
+       return device_for_each_child(dev, &off, pm_iter);
 }
 #endif /* PM */