Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PM: sleep: Introduce CALL_PM_OP() macro to simplify code

Add CALL_PM_OP() macro to eliminate a repetitive code pattern in
power management generic operations.

Replace analogous 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 size while maintaining the same functionality and
improving code maintainability.

Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
Reviewed-by: Dhruva Gole <d-gole@ti.com>
Link: https://patch.msgid.link/20250919124437.3075016-1-kaushlendra.kumar@intel.com
[ rjw: Subject and changelog edits, adjust white space ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Kaushlendra Kumar and committed by
Rafael J. Wysocki
5a151c23 b57100a3

+25 -60
+25 -60
drivers/base/power/generic_ops.c
··· 8 8 #include <linux/pm_runtime.h> 9 9 #include <linux/export.h> 10 10 11 + #define CALL_PM_OP(dev, op) \ 12 + ({ \ 13 + struct device *_dev = (dev); \ 14 + const struct dev_pm_ops *pm = _dev->driver ? _dev->driver->pm : NULL; \ 15 + pm && pm->op ? pm->op(_dev) : 0; \ 16 + }) 17 + 11 18 #ifdef CONFIG_PM 12 19 /** 13 20 * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. ··· 26 19 */ 27 20 int pm_generic_runtime_suspend(struct device *dev) 28 21 { 29 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 30 - int ret; 31 - 32 - ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : 0; 33 - 34 - return ret; 22 + return CALL_PM_OP(dev, runtime_suspend); 35 23 } 36 24 EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend); 37 25 ··· 40 38 */ 41 39 int pm_generic_runtime_resume(struct device *dev) 42 40 { 43 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 44 - int ret; 45 - 46 - ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0; 47 - 48 - return ret; 41 + return CALL_PM_OP(dev, runtime_resume); 49 42 } 50 43 EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); 51 44 #endif /* CONFIG_PM */ ··· 69 72 */ 70 73 int pm_generic_suspend_noirq(struct device *dev) 71 74 { 72 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 73 - 74 - return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0; 75 + return CALL_PM_OP(dev, suspend_noirq); 75 76 } 76 77 EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); 77 78 ··· 79 84 */ 80 85 int pm_generic_suspend_late(struct device *dev) 81 86 { 82 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 83 - 84 - return pm && pm->suspend_late ? pm->suspend_late(dev) : 0; 87 + return CALL_PM_OP(dev, suspend_late); 85 88 } 86 89 EXPORT_SYMBOL_GPL(pm_generic_suspend_late); 87 90 ··· 89 96 */ 90 97 int pm_generic_suspend(struct device *dev) 91 98 { 92 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 93 - 94 - return pm && pm->suspend ? pm->suspend(dev) : 0; 99 + return CALL_PM_OP(dev, suspend); 95 100 } 96 101 EXPORT_SYMBOL_GPL(pm_generic_suspend); 97 102 ··· 99 108 */ 100 109 int pm_generic_freeze_noirq(struct device *dev) 101 110 { 102 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 103 - 104 - return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0; 111 + return CALL_PM_OP(dev, freeze_noirq); 105 112 } 106 113 EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq); 107 114 ··· 109 120 */ 110 121 int pm_generic_freeze(struct device *dev) 111 122 { 112 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 113 - 114 - return pm && pm->freeze ? pm->freeze(dev) : 0; 123 + return CALL_PM_OP(dev, freeze); 115 124 } 116 125 EXPORT_SYMBOL_GPL(pm_generic_freeze); 117 126 ··· 119 132 */ 120 133 int pm_generic_poweroff_noirq(struct device *dev) 121 134 { 122 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 123 - 124 - return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0; 135 + return CALL_PM_OP(dev, poweroff_noirq); 125 136 } 126 137 EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq); 127 138 ··· 129 144 */ 130 145 int pm_generic_poweroff_late(struct device *dev) 131 146 { 132 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 133 - 134 - return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0; 147 + return CALL_PM_OP(dev, poweroff_late); 135 148 } 136 149 EXPORT_SYMBOL_GPL(pm_generic_poweroff_late); 137 150 ··· 139 156 */ 140 157 int pm_generic_poweroff(struct device *dev) 141 158 { 142 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 143 - 144 - return pm && pm->poweroff ? pm->poweroff(dev) : 0; 159 + return CALL_PM_OP(dev, poweroff); 145 160 } 146 161 EXPORT_SYMBOL_GPL(pm_generic_poweroff); 147 162 ··· 149 168 */ 150 169 int pm_generic_thaw_noirq(struct device *dev) 151 170 { 152 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 153 - 154 - return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0; 171 + return CALL_PM_OP(dev, thaw_noirq); 155 172 } 156 173 EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq); 157 174 ··· 159 180 */ 160 181 int pm_generic_thaw(struct device *dev) 161 182 { 162 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 163 - 164 - return pm && pm->thaw ? pm->thaw(dev) : 0; 183 + return CALL_PM_OP(dev, thaw); 165 184 } 166 185 EXPORT_SYMBOL_GPL(pm_generic_thaw); 167 186 ··· 169 192 */ 170 193 int pm_generic_resume_noirq(struct device *dev) 171 194 { 172 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 173 - 174 - return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0; 195 + return CALL_PM_OP(dev, resume_noirq); 175 196 } 176 197 EXPORT_SYMBOL_GPL(pm_generic_resume_noirq); 177 198 ··· 179 204 */ 180 205 int pm_generic_resume_early(struct device *dev) 181 206 { 182 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 183 - 184 - return pm && pm->resume_early ? pm->resume_early(dev) : 0; 207 + return CALL_PM_OP(dev, resume_early); 185 208 } 186 209 EXPORT_SYMBOL_GPL(pm_generic_resume_early); 187 210 ··· 189 216 */ 190 217 int pm_generic_resume(struct device *dev) 191 218 { 192 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 193 - 194 - return pm && pm->resume ? pm->resume(dev) : 0; 219 + return CALL_PM_OP(dev, resume); 195 220 } 196 221 EXPORT_SYMBOL_GPL(pm_generic_resume); 197 222 ··· 199 228 */ 200 229 int pm_generic_restore_noirq(struct device *dev) 201 230 { 202 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 203 - 204 - return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0; 231 + return CALL_PM_OP(dev, restore_noirq); 205 232 } 206 233 EXPORT_SYMBOL_GPL(pm_generic_restore_noirq); 207 234 ··· 209 240 */ 210 241 int pm_generic_restore_early(struct device *dev) 211 242 { 212 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 213 - 214 - return pm && pm->restore_early ? pm->restore_early(dev) : 0; 243 + return CALL_PM_OP(dev, restore_early); 215 244 } 216 245 EXPORT_SYMBOL_GPL(pm_generic_restore_early); 217 246 ··· 219 252 */ 220 253 int pm_generic_restore(struct device *dev) 221 254 { 222 - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 223 - 224 - return pm && pm->restore ? pm->restore(dev) : 0; 255 + return CALL_PM_OP(dev, restore); 225 256 } 226 257 EXPORT_SYMBOL_GPL(pm_generic_restore); 227 258