1// SPDX-License-Identifier: GPL-2.0 2/* 3 * drivers/base/power/generic_ops.c - Generic PM callbacks for subsystems 4 * 5 * Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. 6 */ 7#include <linux/pm.h> 8#include <linux/pm_runtime.h> 9#include <linux/export.h> 10 11#ifdef CONFIG_PM 12/** 13 * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. 14 * @dev: Device to suspend. 15 * 16 * If PM operations are defined for the @dev's driver and they include 17 * ->runtime_suspend(), execute it and return its error code. Otherwise, 18 * return 0. 19 */ 20int pm_generic_runtime_suspend(struct device *dev) 21{ 22 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 23 int ret; 24 25 ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : 0; 26 27 return ret; 28} 29EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend); 30 31/** 32 * pm_generic_runtime_resume - Generic runtime resume callback for subsystems. 33 * @dev: Device to resume. 34 * 35 * If PM operations are defined for the @dev's driver and they include 36 * ->runtime_resume(), execute it and return its error code. Otherwise, 37 * return 0. 38 */ 39int pm_generic_runtime_resume(struct device *dev) 40{ 41 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 42 int ret; 43 44 ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0; 45 46 return ret; 47} 48EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); 49#endif /* CONFIG_PM */ 50 51#ifdef CONFIG_PM_SLEEP 52/** 53 * pm_generic_prepare - Generic routine preparing a device for power transition. 54 * @dev: Device to prepare. 55 * 56 * Prepare a device for a system-wide power transition. 57 */ 58int pm_generic_prepare(struct device *dev) 59{ 60 struct device_driver *drv = dev->driver; 61 int ret = 0; 62 63 if (drv && drv->pm && drv->pm->prepare) 64 ret = drv->pm->prepare(dev); 65 66 return ret; 67} 68 69/** 70 * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems. 71 * @dev: Device to suspend. 72 */ 73int pm_generic_suspend_noirq(struct device *dev) 74{ 75 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 76 77 return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0; 78} 79EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); 80 81/** 82 * pm_generic_suspend_late - Generic suspend_late callback for subsystems. 83 * @dev: Device to suspend. 84 */ 85int pm_generic_suspend_late(struct device *dev) 86{ 87 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 88 89 return pm && pm->suspend_late ? pm->suspend_late(dev) : 0; 90} 91EXPORT_SYMBOL_GPL(pm_generic_suspend_late); 92 93/** 94 * pm_generic_suspend - Generic suspend callback for subsystems. 95 * @dev: Device to suspend. 96 */ 97int pm_generic_suspend(struct device *dev) 98{ 99 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 100 101 return pm && pm->suspend ? pm->suspend(dev) : 0; 102} 103EXPORT_SYMBOL_GPL(pm_generic_suspend); 104 105/** 106 * pm_generic_freeze_noirq - Generic freeze_noirq callback for subsystems. 107 * @dev: Device to freeze. 108 */ 109int pm_generic_freeze_noirq(struct device *dev) 110{ 111 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 112 113 return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0; 114} 115EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq); 116 117/** 118 * pm_generic_freeze_late - Generic freeze_late callback for subsystems. 119 * @dev: Device to freeze. 120 */ 121int pm_generic_freeze_late(struct device *dev) 122{ 123 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 124 125 return pm && pm->freeze_late ? pm->freeze_late(dev) : 0; 126} 127EXPORT_SYMBOL_GPL(pm_generic_freeze_late); 128 129/** 130 * pm_generic_freeze - Generic freeze callback for subsystems. 131 * @dev: Device to freeze. 132 */ 133int pm_generic_freeze(struct device *dev) 134{ 135 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 136 137 return pm && pm->freeze ? pm->freeze(dev) : 0; 138} 139EXPORT_SYMBOL_GPL(pm_generic_freeze); 140 141/** 142 * pm_generic_poweroff_noirq - Generic poweroff_noirq callback for subsystems. 143 * @dev: Device to handle. 144 */ 145int pm_generic_poweroff_noirq(struct device *dev) 146{ 147 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 148 149 return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0; 150} 151EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq); 152 153/** 154 * pm_generic_poweroff_late - Generic poweroff_late callback for subsystems. 155 * @dev: Device to handle. 156 */ 157int pm_generic_poweroff_late(struct device *dev) 158{ 159 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 160 161 return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0; 162} 163EXPORT_SYMBOL_GPL(pm_generic_poweroff_late); 164 165/** 166 * pm_generic_poweroff - Generic poweroff callback for subsystems. 167 * @dev: Device to handle. 168 */ 169int pm_generic_poweroff(struct device *dev) 170{ 171 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 172 173 return pm && pm->poweroff ? pm->poweroff(dev) : 0; 174} 175EXPORT_SYMBOL_GPL(pm_generic_poweroff); 176 177/** 178 * pm_generic_thaw_noirq - Generic thaw_noirq callback for subsystems. 179 * @dev: Device to thaw. 180 */ 181int pm_generic_thaw_noirq(struct device *dev) 182{ 183 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 184 185 return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0; 186} 187EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq); 188 189/** 190 * pm_generic_thaw_early - Generic thaw_early callback for subsystems. 191 * @dev: Device to thaw. 192 */ 193int pm_generic_thaw_early(struct device *dev) 194{ 195 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 196 197 return pm && pm->thaw_early ? pm->thaw_early(dev) : 0; 198} 199EXPORT_SYMBOL_GPL(pm_generic_thaw_early); 200 201/** 202 * pm_generic_thaw - Generic thaw callback for subsystems. 203 * @dev: Device to thaw. 204 */ 205int pm_generic_thaw(struct device *dev) 206{ 207 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 208 209 return pm && pm->thaw ? pm->thaw(dev) : 0; 210} 211EXPORT_SYMBOL_GPL(pm_generic_thaw); 212 213/** 214 * pm_generic_resume_noirq - Generic resume_noirq callback for subsystems. 215 * @dev: Device to resume. 216 */ 217int pm_generic_resume_noirq(struct device *dev) 218{ 219 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 220 221 return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0; 222} 223EXPORT_SYMBOL_GPL(pm_generic_resume_noirq); 224 225/** 226 * pm_generic_resume_early - Generic resume_early callback for subsystems. 227 * @dev: Device to resume. 228 */ 229int pm_generic_resume_early(struct device *dev) 230{ 231 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 232 233 return pm && pm->resume_early ? pm->resume_early(dev) : 0; 234} 235EXPORT_SYMBOL_GPL(pm_generic_resume_early); 236 237/** 238 * pm_generic_resume - Generic resume callback for subsystems. 239 * @dev: Device to resume. 240 */ 241int pm_generic_resume(struct device *dev) 242{ 243 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 244 245 return pm && pm->resume ? pm->resume(dev) : 0; 246} 247EXPORT_SYMBOL_GPL(pm_generic_resume); 248 249/** 250 * pm_generic_restore_noirq - Generic restore_noirq callback for subsystems. 251 * @dev: Device to restore. 252 */ 253int pm_generic_restore_noirq(struct device *dev) 254{ 255 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 256 257 return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0; 258} 259EXPORT_SYMBOL_GPL(pm_generic_restore_noirq); 260 261/** 262 * pm_generic_restore_early - Generic restore_early callback for subsystems. 263 * @dev: Device to resume. 264 */ 265int pm_generic_restore_early(struct device *dev) 266{ 267 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 268 269 return pm && pm->restore_early ? pm->restore_early(dev) : 0; 270} 271EXPORT_SYMBOL_GPL(pm_generic_restore_early); 272 273/** 274 * pm_generic_restore - Generic restore callback for subsystems. 275 * @dev: Device to restore. 276 */ 277int pm_generic_restore(struct device *dev) 278{ 279 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 280 281 return pm && pm->restore ? pm->restore(dev) : 0; 282} 283EXPORT_SYMBOL_GPL(pm_generic_restore); 284 285/** 286 * pm_generic_complete - Generic routine completing a device power transition. 287 * @dev: Device to handle. 288 * 289 * Complete a device power transition during a system-wide power transition. 290 */ 291void pm_generic_complete(struct device *dev) 292{ 293 struct device_driver *drv = dev->driver; 294 295 if (drv && drv->pm && drv->pm->complete) 296 drv->pm->complete(dev); 297} 298#endif /* CONFIG_PM_SLEEP */ 299