* [PATCH] PM: Introduce CALL_PM_OP macro to reduce code duplication
@ 2025-09-19 12:44 Kaushlendra Kumar
2025-10-13 18:56 ` Rafael J. Wysocki
2025-10-20 17:56 ` Rafael J. Wysocki
0 siblings, 2 replies; 5+ messages in thread
From: Kaushlendra Kumar @ 2025-09-19 12:44 UTC (permalink / raw)
To: rafael, pavel, gregkh, dakr; +Cc: linux-pm, Kaushlendra Kumar
Add CALL_PM_OP macro to eliminate repetitive code patterns in power
management generic operations. Replace identical driver PM callback
invocation logic across all pm_generic_* functions with a single
macro that handles the NULL pointer checks and function calls.
This reduces code duplication significantly while maintaining the
same functionality and improving code maintainability.
Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
---
drivers/base/power/generic_ops.c | 85 ++++++++++----------------------
1 file changed, 25 insertions(+), 60 deletions(-)
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
index 6502720bb564..c4fc802b8c65 100644
--- a/drivers/base/power/generic_ops.c
+++ b/drivers/base/power/generic_ops.c
@@ -8,6 +8,13 @@
#include <linux/pm_runtime.h>
#include <linux/export.h>
+#define CALL_PM_OP(dev, op) \
+({ \
+struct device *_dev = (dev); \
+const struct dev_pm_ops *pm = _dev->driver ? _dev->driver->pm : NULL; \
+pm && pm->op ? pm->op(_dev) : 0; \
+})
+
#ifdef CONFIG_PM
/**
* pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
@@ -19,12 +26,7 @@
*/
int pm_generic_runtime_suspend(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int ret;
-
- ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : 0;
-
- return ret;
+ return CALL_PM_OP(dev, runtime_suspend);
}
EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
@@ -38,12 +40,7 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
*/
int pm_generic_runtime_resume(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int ret;
-
- ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;
-
- return ret;
+ return CALL_PM_OP(dev, runtime_resume);
}
EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);
#endif /* CONFIG_PM */
@@ -72,9 +69,7 @@ int pm_generic_prepare(struct device *dev)
*/
int pm_generic_suspend_noirq(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0;
+ return CALL_PM_OP(dev, suspend_noirq);
}
EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
@@ -84,9 +79,7 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
*/
int pm_generic_suspend_late(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->suspend_late ? pm->suspend_late(dev) : 0;
+ return CALL_PM_OP(dev, suspend_late);
}
EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
@@ -96,9 +89,7 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
*/
int pm_generic_suspend(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->suspend ? pm->suspend(dev) : 0;
+ return CALL_PM_OP(dev, suspend);
}
EXPORT_SYMBOL_GPL(pm_generic_suspend);
@@ -108,9 +99,7 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend);
*/
int pm_generic_freeze_noirq(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0;
+ return CALL_PM_OP(dev, freeze_noirq);
}
EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
@@ -120,9 +109,7 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
*/
int pm_generic_freeze(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->freeze ? pm->freeze(dev) : 0;
+ return CALL_PM_OP(dev, freeze);
}
EXPORT_SYMBOL_GPL(pm_generic_freeze);
@@ -132,9 +119,7 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze);
*/
int pm_generic_poweroff_noirq(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0;
+ return CALL_PM_OP(dev, poweroff_noirq);
}
EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
@@ -144,9 +129,7 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
*/
int pm_generic_poweroff_late(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0;
+ return CALL_PM_OP(dev, poweroff_late);
}
EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
@@ -156,9 +139,7 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
*/
int pm_generic_poweroff(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->poweroff ? pm->poweroff(dev) : 0;
+ return CALL_PM_OP(dev, poweroff);
}
EXPORT_SYMBOL_GPL(pm_generic_poweroff);
@@ -168,9 +149,7 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff);
*/
int pm_generic_thaw_noirq(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0;
+ return CALL_PM_OP(dev, thaw_noirq);
}
EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
@@ -180,9 +159,7 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
*/
int pm_generic_thaw(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->thaw ? pm->thaw(dev) : 0;
+ return CALL_PM_OP(dev, thaw);
}
EXPORT_SYMBOL_GPL(pm_generic_thaw);
@@ -192,9 +169,7 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw);
*/
int pm_generic_resume_noirq(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0;
+ return CALL_PM_OP(dev, resume_noirq);
}
EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
@@ -204,9 +179,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
*/
int pm_generic_resume_early(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->resume_early ? pm->resume_early(dev) : 0;
+ return CALL_PM_OP(dev, resume_early);
}
EXPORT_SYMBOL_GPL(pm_generic_resume_early);
@@ -216,9 +189,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume_early);
*/
int pm_generic_resume(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->resume ? pm->resume(dev) : 0;
+ return CALL_PM_OP(dev, resume);
}
EXPORT_SYMBOL_GPL(pm_generic_resume);
@@ -228,9 +199,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume);
*/
int pm_generic_restore_noirq(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0;
+ return CALL_PM_OP(dev, restore_noirq);
}
EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
@@ -240,9 +209,7 @@ EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
*/
int pm_generic_restore_early(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->restore_early ? pm->restore_early(dev) : 0;
+ return CALL_PM_OP(dev, restore_early);
}
EXPORT_SYMBOL_GPL(pm_generic_restore_early);
@@ -252,9 +219,7 @@ EXPORT_SYMBOL_GPL(pm_generic_restore_early);
*/
int pm_generic_restore(struct device *dev)
{
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
- return pm && pm->restore ? pm->restore(dev) : 0;
+ return CALL_PM_OP(dev, restore);
}
EXPORT_SYMBOL_GPL(pm_generic_restore);
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] PM: Introduce CALL_PM_OP macro to reduce code duplication
2025-09-19 12:44 [PATCH] PM: Introduce CALL_PM_OP macro to reduce code duplication Kaushlendra Kumar
@ 2025-10-13 18:56 ` Rafael J. Wysocki
2025-10-14 8:32 ` Kumar, Kaushlendra
2025-10-15 5:46 ` Dhruva Gole
2025-10-20 17:56 ` Rafael J. Wysocki
1 sibling, 2 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2025-10-13 18:56 UTC (permalink / raw)
To: Kaushlendra Kumar; +Cc: rafael, pavel, gregkh, dakr, linux-pm
On Fri, Sep 19, 2025 at 2:46 PM Kaushlendra Kumar
<kaushlendra.kumar@intel.com> wrote:
>
> Add CALL_PM_OP macro to eliminate repetitive code patterns in power
> management generic operations. Replace identical driver PM callback
> invocation logic across all pm_generic_* functions with a single
> macro that handles the NULL pointer checks and function calls.
>
> This reduces code duplication significantly while maintaining the
> same functionality and improving code maintainability.
>
> Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
> ---
> drivers/base/power/generic_ops.c | 85 ++++++++++----------------------
> 1 file changed, 25 insertions(+), 60 deletions(-)
>
> diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
> index 6502720bb564..c4fc802b8c65 100644
> --- a/drivers/base/power/generic_ops.c
> +++ b/drivers/base/power/generic_ops.c
> @@ -8,6 +8,13 @@
> #include <linux/pm_runtime.h>
> #include <linux/export.h>
>
> +#define CALL_PM_OP(dev, op) \
> +({ \
> +struct device *_dev = (dev); \
> +const struct dev_pm_ops *pm = _dev->driver ? _dev->driver->pm : NULL; \
> +pm && pm->op ? pm->op(_dev) : 0; \
> +})
Why don't you include the function signature and symbol export into the macro?
> +
> #ifdef CONFIG_PM
> /**
> * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
> @@ -19,12 +26,7 @@
> */
> int pm_generic_runtime_suspend(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> - int ret;
> -
> - ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : 0;
> -
> - return ret;
> + return CALL_PM_OP(dev, runtime_suspend);
> }
> EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
>
> @@ -38,12 +40,7 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
> */
> int pm_generic_runtime_resume(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> - int ret;
> -
> - ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;
> -
> - return ret;
> + return CALL_PM_OP(dev, runtime_resume);
> }
> EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);
> #endif /* CONFIG_PM */
> @@ -72,9 +69,7 @@ int pm_generic_prepare(struct device *dev)
> */
> int pm_generic_suspend_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0;
> + return CALL_PM_OP(dev, suspend_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
>
> @@ -84,9 +79,7 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
> */
> int pm_generic_suspend_late(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->suspend_late ? pm->suspend_late(dev) : 0;
> + return CALL_PM_OP(dev, suspend_late);
> }
> EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
>
> @@ -96,9 +89,7 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
> */
> int pm_generic_suspend(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->suspend ? pm->suspend(dev) : 0;
> + return CALL_PM_OP(dev, suspend);
> }
> EXPORT_SYMBOL_GPL(pm_generic_suspend);
>
> @@ -108,9 +99,7 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend);
> */
> int pm_generic_freeze_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0;
> + return CALL_PM_OP(dev, freeze_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
>
> @@ -120,9 +109,7 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
> */
> int pm_generic_freeze(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->freeze ? pm->freeze(dev) : 0;
> + return CALL_PM_OP(dev, freeze);
> }
> EXPORT_SYMBOL_GPL(pm_generic_freeze);
>
> @@ -132,9 +119,7 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze);
> */
> int pm_generic_poweroff_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0;
> + return CALL_PM_OP(dev, poweroff_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
>
> @@ -144,9 +129,7 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
> */
> int pm_generic_poweroff_late(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0;
> + return CALL_PM_OP(dev, poweroff_late);
> }
> EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
>
> @@ -156,9 +139,7 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
> */
> int pm_generic_poweroff(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->poweroff ? pm->poweroff(dev) : 0;
> + return CALL_PM_OP(dev, poweroff);
> }
> EXPORT_SYMBOL_GPL(pm_generic_poweroff);
>
> @@ -168,9 +149,7 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff);
> */
> int pm_generic_thaw_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0;
> + return CALL_PM_OP(dev, thaw_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
>
> @@ -180,9 +159,7 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
> */
> int pm_generic_thaw(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->thaw ? pm->thaw(dev) : 0;
> + return CALL_PM_OP(dev, thaw);
> }
> EXPORT_SYMBOL_GPL(pm_generic_thaw);
>
> @@ -192,9 +169,7 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw);
> */
> int pm_generic_resume_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0;
> + return CALL_PM_OP(dev, resume_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
>
> @@ -204,9 +179,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
> */
> int pm_generic_resume_early(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->resume_early ? pm->resume_early(dev) : 0;
> + return CALL_PM_OP(dev, resume_early);
> }
> EXPORT_SYMBOL_GPL(pm_generic_resume_early);
>
> @@ -216,9 +189,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume_early);
> */
> int pm_generic_resume(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->resume ? pm->resume(dev) : 0;
> + return CALL_PM_OP(dev, resume);
> }
> EXPORT_SYMBOL_GPL(pm_generic_resume);
>
> @@ -228,9 +199,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume);
> */
> int pm_generic_restore_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0;
> + return CALL_PM_OP(dev, restore_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
>
> @@ -240,9 +209,7 @@ EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
> */
> int pm_generic_restore_early(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->restore_early ? pm->restore_early(dev) : 0;
> + return CALL_PM_OP(dev, restore_early);
> }
> EXPORT_SYMBOL_GPL(pm_generic_restore_early);
>
> @@ -252,9 +219,7 @@ EXPORT_SYMBOL_GPL(pm_generic_restore_early);
> */
> int pm_generic_restore(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->restore ? pm->restore(dev) : 0;
> + return CALL_PM_OP(dev, restore);
> }
> EXPORT_SYMBOL_GPL(pm_generic_restore);
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH] PM: Introduce CALL_PM_OP macro to reduce code duplication
2025-10-13 18:56 ` Rafael J. Wysocki
@ 2025-10-14 8:32 ` Kumar, Kaushlendra
2025-10-15 5:46 ` Dhruva Gole
1 sibling, 0 replies; 5+ messages in thread
From: Kumar, Kaushlendra @ 2025-10-14 8:32 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: pavel@kernel.org, gregkh@linuxfoundation.org, dakr@kernel.org,
linux-pm@vger.kernel.org
On Tue, Oct 14, 2025 at 12:27 AM Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> Why don't you include the function signature and symbol export into the macro?
Thanks for the suggestion!. I have sent a v2 patch as suggested.
BR,
Kaushlendra
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PM: Introduce CALL_PM_OP macro to reduce code duplication
2025-10-13 18:56 ` Rafael J. Wysocki
2025-10-14 8:32 ` Kumar, Kaushlendra
@ 2025-10-15 5:46 ` Dhruva Gole
1 sibling, 0 replies; 5+ messages in thread
From: Dhruva Gole @ 2025-10-15 5:46 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Kaushlendra Kumar, pavel, gregkh, dakr, linux-pm
On Oct 13, 2025 at 20:56:40 +0200, Rafael J. Wysocki wrote:
> On Fri, Sep 19, 2025 at 2:46 PM Kaushlendra Kumar
> <kaushlendra.kumar@intel.com> wrote:
> >
> > Add CALL_PM_OP macro to eliminate repetitive code patterns in power
> > management generic operations. Replace identical driver PM callback
> > invocation logic across all pm_generic_* functions with a single
> > macro that handles the NULL pointer checks and function calls.
> >
> > This reduces code duplication significantly while maintaining the
> > same functionality and improving code maintainability.
> >
> > Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
> > ---
> > drivers/base/power/generic_ops.c | 85 ++++++++++----------------------
> > 1 file changed, 25 insertions(+), 60 deletions(-)
> >
> > diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
> > index 6502720bb564..c4fc802b8c65 100644
> > --- a/drivers/base/power/generic_ops.c
> > +++ b/drivers/base/power/generic_ops.c
> > @@ -8,6 +8,13 @@
> > #include <linux/pm_runtime.h>
> > #include <linux/export.h>
> >
> > +#define CALL_PM_OP(dev, op) \
> > +({ \
> > +struct device *_dev = (dev); \
> > +const struct dev_pm_ops *pm = _dev->driver ? _dev->driver->pm : NULL; \
> > +pm && pm->op ? pm->op(_dev) : 0; \
> > +})
>
> Why don't you include the function signature and symbol export into the macro?
>
As discussed in the [v2] I am more inclined toward this v1
implementation.
So for v1:
Reviewed-by: Dhruva Gole <d-gole@ti.com>
[v2] https://lore.kernel.org/linux-pm/CAJZ5v0iHcvXHdMfdakd5TUgcAiOGFW8hbvb2k-xb92dz81cGhA@mail.gmail.com
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PM: Introduce CALL_PM_OP macro to reduce code duplication
2025-09-19 12:44 [PATCH] PM: Introduce CALL_PM_OP macro to reduce code duplication Kaushlendra Kumar
2025-10-13 18:56 ` Rafael J. Wysocki
@ 2025-10-20 17:56 ` Rafael J. Wysocki
1 sibling, 0 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2025-10-20 17:56 UTC (permalink / raw)
To: Kaushlendra Kumar; +Cc: rafael, pavel, gregkh, dakr, linux-pm
On Fri, Sep 19, 2025 at 2:46 PM Kaushlendra Kumar
<kaushlendra.kumar@intel.com> wrote:
>
> Add CALL_PM_OP macro to eliminate repetitive code patterns in power
> management generic operations. Replace identical driver PM callback
> invocation logic across all pm_generic_* functions with a single
> macro that handles the NULL pointer checks and function calls.
>
> This reduces code duplication significantly while maintaining the
> same functionality and improving code maintainability.
>
> Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
> ---
> drivers/base/power/generic_ops.c | 85 ++++++++++----------------------
> 1 file changed, 25 insertions(+), 60 deletions(-)
>
> diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
> index 6502720bb564..c4fc802b8c65 100644
> --- a/drivers/base/power/generic_ops.c
> +++ b/drivers/base/power/generic_ops.c
> @@ -8,6 +8,13 @@
> #include <linux/pm_runtime.h>
> #include <linux/export.h>
>
> +#define CALL_PM_OP(dev, op) \
> +({ \
> +struct device *_dev = (dev); \
> +const struct dev_pm_ops *pm = _dev->driver ? _dev->driver->pm : NULL; \
> +pm && pm->op ? pm->op(_dev) : 0; \
> +})
> +
> #ifdef CONFIG_PM
> /**
> * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
> @@ -19,12 +26,7 @@
> */
> int pm_generic_runtime_suspend(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> - int ret;
> -
> - ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : 0;
> -
> - return ret;
> + return CALL_PM_OP(dev, runtime_suspend);
> }
> EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
>
> @@ -38,12 +40,7 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
> */
> int pm_generic_runtime_resume(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> - int ret;
> -
> - ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;
> -
> - return ret;
> + return CALL_PM_OP(dev, runtime_resume);
> }
> EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);
> #endif /* CONFIG_PM */
> @@ -72,9 +69,7 @@ int pm_generic_prepare(struct device *dev)
> */
> int pm_generic_suspend_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0;
> + return CALL_PM_OP(dev, suspend_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
>
> @@ -84,9 +79,7 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
> */
> int pm_generic_suspend_late(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->suspend_late ? pm->suspend_late(dev) : 0;
> + return CALL_PM_OP(dev, suspend_late);
> }
> EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
>
> @@ -96,9 +89,7 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
> */
> int pm_generic_suspend(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->suspend ? pm->suspend(dev) : 0;
> + return CALL_PM_OP(dev, suspend);
> }
> EXPORT_SYMBOL_GPL(pm_generic_suspend);
>
> @@ -108,9 +99,7 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend);
> */
> int pm_generic_freeze_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0;
> + return CALL_PM_OP(dev, freeze_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
>
> @@ -120,9 +109,7 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
> */
> int pm_generic_freeze(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->freeze ? pm->freeze(dev) : 0;
> + return CALL_PM_OP(dev, freeze);
> }
> EXPORT_SYMBOL_GPL(pm_generic_freeze);
>
> @@ -132,9 +119,7 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze);
> */
> int pm_generic_poweroff_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0;
> + return CALL_PM_OP(dev, poweroff_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
>
> @@ -144,9 +129,7 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
> */
> int pm_generic_poweroff_late(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0;
> + return CALL_PM_OP(dev, poweroff_late);
> }
> EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
>
> @@ -156,9 +139,7 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
> */
> int pm_generic_poweroff(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->poweroff ? pm->poweroff(dev) : 0;
> + return CALL_PM_OP(dev, poweroff);
> }
> EXPORT_SYMBOL_GPL(pm_generic_poweroff);
>
> @@ -168,9 +149,7 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff);
> */
> int pm_generic_thaw_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0;
> + return CALL_PM_OP(dev, thaw_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
>
> @@ -180,9 +159,7 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
> */
> int pm_generic_thaw(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->thaw ? pm->thaw(dev) : 0;
> + return CALL_PM_OP(dev, thaw);
> }
> EXPORT_SYMBOL_GPL(pm_generic_thaw);
>
> @@ -192,9 +169,7 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw);
> */
> int pm_generic_resume_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0;
> + return CALL_PM_OP(dev, resume_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
>
> @@ -204,9 +179,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
> */
> int pm_generic_resume_early(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->resume_early ? pm->resume_early(dev) : 0;
> + return CALL_PM_OP(dev, resume_early);
> }
> EXPORT_SYMBOL_GPL(pm_generic_resume_early);
>
> @@ -216,9 +189,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume_early);
> */
> int pm_generic_resume(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->resume ? pm->resume(dev) : 0;
> + return CALL_PM_OP(dev, resume);
> }
> EXPORT_SYMBOL_GPL(pm_generic_resume);
>
> @@ -228,9 +199,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume);
> */
> int pm_generic_restore_noirq(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0;
> + return CALL_PM_OP(dev, restore_noirq);
> }
> EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
>
> @@ -240,9 +209,7 @@ EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
> */
> int pm_generic_restore_early(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->restore_early ? pm->restore_early(dev) : 0;
> + return CALL_PM_OP(dev, restore_early);
> }
> EXPORT_SYMBOL_GPL(pm_generic_restore_early);
>
> @@ -252,9 +219,7 @@ EXPORT_SYMBOL_GPL(pm_generic_restore_early);
> */
> int pm_generic_restore(struct device *dev)
> {
> - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -
> - return pm && pm->restore ? pm->restore(dev) : 0;
> + return CALL_PM_OP(dev, restore);
> }
> EXPORT_SYMBOL_GPL(pm_generic_restore);
>
> --
Applied as 6.19 material with some edits in the subject and changelog,
and some white space adjustments.
Thanks!
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-10-20 17:56 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-19 12:44 [PATCH] PM: Introduce CALL_PM_OP macro to reduce code duplication Kaushlendra Kumar
2025-10-13 18:56 ` Rafael J. Wysocki
2025-10-14 8:32 ` Kumar, Kaushlendra
2025-10-15 5:46 ` Dhruva Gole
2025-10-20 17:56 ` Rafael J. Wysocki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox