[PATCH] platform: unify the platform_pm_* suspend/resume dispatch

KrisPoint <[email protected]>
Newsgroups dev.linux.lists.driver-core,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The six platform_pm_suspend()/platform_pm_resume()/platform_pm_freeze()/
platform_pm_thaw()/platform_pm_poweroff()/platform_pm_restore() callbacks
all follow the same pattern: return early when the device has no driver,
call the matching dev_pm_ops callback when one is present, and otherwise
fall back to the legacy platform suspend/resume callbacks. This skeleton
is currently open-coded in each of the six functions, leaving about 110
lines of near-identical logic that must be kept in sync by hand.

Add a common platform_pm_dispatch() helper that implements the shared
logic, driven by the dev_pm_ops callback, the legacy callback and the
pm message to pass, and turn the six callbacks into thin wrappers around
it. A platform_legacy_resume_state() adapter is added so the legacy
callbacks share a single signature.

No functional change intended.

Signed-off-by: KrisPoint <[email protected]>
---
 drivers/base/platform.c | 109 ++++++++++++++--------------------------
 1 file changed, 38 insertions(+), 71 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 66f9ec73d..f02b44937 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1248,44 +1248,47 @@ static int platform_legacy_resume(struct device *dev)
 	return ret;
 }
 
-#endif /* CONFIG_PM_SLEEP */
-
-#ifdef CONFIG_SUSPEND
+static int platform_legacy_resume_state(struct device *dev, pm_message_t state)
+{
+	return platform_legacy_resume(dev);
+}
 
-int platform_pm_suspend(struct device *dev)
+static int platform_pm_dispatch(struct device *dev,
+				int (*pm_op)(struct device *),
+				int (*legacy_op)(struct device *, pm_message_t),
+				pm_message_t legacy_state)
 {
 	const struct device_driver *drv = dev->driver;
-	int ret = 0;
 
 	if (!drv)
 		return 0;
 
-	if (drv->pm) {
-		if (drv->pm->suspend)
-			ret = drv->pm->suspend(dev);
-	} else {
-		ret = platform_legacy_suspend(dev, PMSG_SUSPEND);
-	}
+	if (drv->pm)
+		return pm_op ? pm_op(dev) : 0;
 
-	return ret;
+	return legacy_op(dev, legacy_state);
 }
 
-int platform_pm_resume(struct device *dev)
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_SUSPEND
+
+int platform_pm_suspend(struct device *dev)
 {
 	const struct device_driver *drv = dev->driver;
-	int ret = 0;
 
-	if (!drv)
-		return 0;
+	return platform_pm_dispatch(dev,
+				    drv && drv->pm ? drv->pm->suspend : NULL,
+				    platform_legacy_suspend, PMSG_SUSPEND);
+}
 
-	if (drv->pm) {
-		if (drv->pm->resume)
-			ret = drv->pm->resume(dev);
-	} else {
-		ret = platform_legacy_resume(dev);
-	}
+int platform_pm_resume(struct device *dev)
+{
+	const struct device_driver *drv = dev->driver;
 
-	return ret;
+	return platform_pm_dispatch(dev,
+				    drv && drv->pm ? drv->pm->resume : NULL,
+				    platform_legacy_resume_state, PMSG_RESUME);
 }
 
 #endif /* CONFIG_SUSPEND */
@@ -1295,73 +1298,37 @@ int platform_pm_resume(struct device *dev)
 int platform_pm_freeze(struct device *dev)
 {
 	const struct device_driver *drv = dev->driver;
-	int ret = 0;
-
-	if (!drv)
-		return 0;
-
-	if (drv->pm) {
-		if (drv->pm->freeze)
-			ret = drv->pm->freeze(dev);
-	} else {
-		ret = platform_legacy_suspend(dev, PMSG_FREEZE);
-	}
 
-	return ret;
+	return platform_pm_dispatch(dev,
+				    drv && drv->pm ? drv->pm->freeze : NULL,
+				    platform_legacy_suspend, PMSG_FREEZE);
 }
 
 int platform_pm_thaw(struct device *dev)
 {
 	const struct device_driver *drv = dev->driver;
-	int ret = 0;
 
-	if (!drv)
-		return 0;
-
-	if (drv->pm) {
-		if (drv->pm->thaw)
-			ret = drv->pm->thaw(dev);
-	} else {
-		ret = platform_legacy_resume(dev);
-	}
-
-	return ret;
+	return platform_pm_dispatch(dev,
+				    drv && drv->pm ? drv->pm->thaw : NULL,
+				    platform_legacy_resume_state, PMSG_RESUME);
 }
 
 int platform_pm_poweroff(struct device *dev)
 {
 	const struct device_driver *drv = dev->driver;
-	int ret = 0;
 
-	if (!drv)
-		return 0;
-
-	if (drv->pm) {
-		if (drv->pm->poweroff)
-			ret = drv->pm->poweroff(dev);
-	} else {
-		ret = platform_legacy_suspend(dev, PMSG_HIBERNATE);
-	}
-
-	return ret;
+	return platform_pm_dispatch(dev,
+				    drv && drv->pm ? drv->pm->poweroff : NULL,
+				    platform_legacy_suspend, PMSG_HIBERNATE);
 }
 
 int platform_pm_restore(struct device *dev)
 {
 	const struct device_driver *drv = dev->driver;
-	int ret = 0;
 
-	if (!drv)
-		return 0;
-
-	if (drv->pm) {
-		if (drv->pm->restore)
-			ret = drv->pm->restore(dev);
-	} else {
-		ret = platform_legacy_resume(dev);
-	}
-
-	return ret;
+	return platform_pm_dispatch(dev,
+				    drv && drv->pm ? drv->pm->restore : NULL,
+				    platform_legacy_resume_state, PMSG_RESUME);
 }
 
 #endif /* CONFIG_HIBERNATE_CALLBACKS */
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.