* [PATCH] platform: unify the platform_pm_* suspend/resume dispatch
@ 2026-08-20 8:07 KrisPoint
2026-08-20 8:22 ` Greg KH
0 siblings, 1 reply; 2+ messages in thread
From: KrisPoint @ 2026-08-20 8:07 UTC (permalink / raw)
To: gregkh, rafael, dakr; +Cc: driver-core, linux-kernel, KrisPoint
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 <KrisPointCSGO@gmail.com>
---
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
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] platform: unify the platform_pm_* suspend/resume dispatch
2026-08-20 8:07 [PATCH] platform: unify the platform_pm_* suspend/resume dispatch KrisPoint
@ 2026-08-20 8:22 ` Greg KH
0 siblings, 0 replies; 2+ messages in thread
From: Greg KH @ 2026-08-20 8:22 UTC (permalink / raw)
To: KrisPoint; +Cc: rafael, dakr, driver-core, linux-kernel
On Thu, Aug 20, 2026 at 04:07:35PM +0800, KrisPoint wrote:
> 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 <KrisPointCSGO@gmail.com>
Real name please.
While I appreciate the goal of making code smaller, you have to admit,
these lines:
> + return platform_pm_dispatch(dev,
> + drv && drv->pm ? drv->pm->suspend : NULL,
> + platform_legacy_suspend, PMSG_SUSPEND);
Are pretty unreadable.
Now we need to go look up the platform_pm_dispatch parameters each time
and try to figure out the suspend vs. NULL mess.
We write code for people first, compilers second. And this feels to me,
like making it harder for people to understand.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-20 8:24 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-20 8:07 [PATCH] platform: unify the platform_pm_* suspend/resume dispatch KrisPoint
2026-08-20 8:22 ` Greg KH
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.