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 #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 18 #ifdef CONFIG_PM 19 /** 20 * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. 21 * @dev: Device to suspend. 22 * 23 * If PM operations are defined for the @dev's driver and they include 24 * ->runtime_suspend(), execute it and return its error code. Otherwise, 25 * return 0. 26 */ 27 int pm_generic_runtime_suspend(struct device *dev) 28 { 29 return CALL_PM_OP(dev, runtime_suspend); 30 } 31 EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend); 32 33 /** 34 * pm_generic_runtime_resume - Generic runtime resume callback for subsystems. 35 * @dev: Device to resume. 36 * 37 * If PM operations are defined for the @dev's driver and they include 38 * ->runtime_resume(), execute it and return its error code. Otherwise, 39 * return 0. 40 */ 41 int pm_generic_runtime_resume(struct device *dev) 42 { 43 return CALL_PM_OP(dev, runtime_resume); 44 } 45 EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); 46 #endif /* CONFIG_PM */ 47 48 #ifdef CONFIG_PM_SLEEP 49 /** 50 * pm_generic_prepare - Generic routine preparing a device for power transition. 51 * @dev: Device to prepare. 52 * 53 * Prepare a device for a system-wide power transition. 54 */ 55 int pm_generic_prepare(struct device *dev) 56 { 57 struct device_driver *drv = dev->driver; 58 int ret = 0; 59 60 if (drv && drv->pm && drv->pm->prepare) 61 ret = drv->pm->prepare(dev); 62 63 return ret; 64 } 65 66 /** 67 * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems. 68 * @dev: Device to suspend. 69 */ 70 int pm_generic_suspend_noirq(struct device *dev) 71 { 72 return CALL_PM_OP(dev, suspend_noirq); 73 } 74 EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); 75 76 /** 77 * pm_generic_suspend_late - Generic suspend_late callback for subsystems. 78 * @dev: Device to suspend. 79 */ 80 int pm_generic_suspend_late(struct device *dev) 81 { 82 return CALL_PM_OP(dev, suspend_late); 83 } 84 EXPORT_SYMBOL_GPL(pm_generic_suspend_late); 85 86 /** 87 * pm_generic_suspend - Generic suspend callback for subsystems. 88 * @dev: Device to suspend. 89 */ 90 int pm_generic_suspend(struct device *dev) 91 { 92 return CALL_PM_OP(dev, suspend); 93 } 94 EXPORT_SYMBOL_GPL(pm_generic_suspend); 95 96 /** 97 * pm_generic_freeze_noirq - Generic freeze_noirq callback for subsystems. 98 * @dev: Device to freeze. 99 */ 100 int pm_generic_freeze_noirq(struct device *dev) 101 { 102 return CALL_PM_OP(dev, freeze_noirq); 103 } 104 EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq); 105 106 /** 107 * pm_generic_freeze - Generic freeze callback for subsystems. 108 * @dev: Device to freeze. 109 */ 110 int pm_generic_freeze(struct device *dev) 111 { 112 return CALL_PM_OP(dev, freeze); 113 } 114 EXPORT_SYMBOL_GPL(pm_generic_freeze); 115 116 /** 117 * pm_generic_poweroff_noirq - Generic poweroff_noirq callback for subsystems. 118 * @dev: Device to handle. 119 */ 120 int pm_generic_poweroff_noirq(struct device *dev) 121 { 122 return CALL_PM_OP(dev, poweroff_noirq); 123 } 124 EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq); 125 126 /** 127 * pm_generic_poweroff_late - Generic poweroff_late callback for subsystems. 128 * @dev: Device to handle. 129 */ 130 int pm_generic_poweroff_late(struct device *dev) 131 { 132 return CALL_PM_OP(dev, poweroff_late); 133 } 134 EXPORT_SYMBOL_GPL(pm_generic_poweroff_late); 135 136 /** 137 * pm_generic_poweroff - Generic poweroff callback for subsystems. 138 * @dev: Device to handle. 139 */ 140 int pm_generic_poweroff(struct device *dev) 141 { 142 return CALL_PM_OP(dev, poweroff); 143 } 144 EXPORT_SYMBOL_GPL(pm_generic_poweroff); 145 146 /** 147 * pm_generic_thaw_noirq - Generic thaw_noirq callback for subsystems. 148 * @dev: Device to thaw. 149 */ 150 int pm_generic_thaw_noirq(struct device *dev) 151 { 152 return CALL_PM_OP(dev, thaw_noirq); 153 } 154 EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq); 155 156 /** 157 * pm_generic_thaw - Generic thaw callback for subsystems. 158 * @dev: Device to thaw. 159 */ 160 int pm_generic_thaw(struct device *dev) 161 { 162 return CALL_PM_OP(dev, thaw); 163 } 164 EXPORT_SYMBOL_GPL(pm_generic_thaw); 165 166 /** 167 * pm_generic_resume_noirq - Generic resume_noirq callback for subsystems. 168 * @dev: Device to resume. 169 */ 170 int pm_generic_resume_noirq(struct device *dev) 171 { 172 return CALL_PM_OP(dev, resume_noirq); 173 } 174 EXPORT_SYMBOL_GPL(pm_generic_resume_noirq); 175 176 /** 177 * pm_generic_resume_early - Generic resume_early callback for subsystems. 178 * @dev: Device to resume. 179 */ 180 int pm_generic_resume_early(struct device *dev) 181 { 182 return CALL_PM_OP(dev, resume_early); 183 } 184 EXPORT_SYMBOL_GPL(pm_generic_resume_early); 185 186 /** 187 * pm_generic_resume - Generic resume callback for subsystems. 188 * @dev: Device to resume. 189 */ 190 int pm_generic_resume(struct device *dev) 191 { 192 return CALL_PM_OP(dev, resume); 193 } 194 EXPORT_SYMBOL_GPL(pm_generic_resume); 195 196 /** 197 * pm_generic_restore_noirq - Generic restore_noirq callback for subsystems. 198 * @dev: Device to restore. 199 */ 200 int pm_generic_restore_noirq(struct device *dev) 201 { 202 return CALL_PM_OP(dev, restore_noirq); 203 } 204 EXPORT_SYMBOL_GPL(pm_generic_restore_noirq); 205 206 /** 207 * pm_generic_restore_early - Generic restore_early callback for subsystems. 208 * @dev: Device to resume. 209 */ 210 int pm_generic_restore_early(struct device *dev) 211 { 212 return CALL_PM_OP(dev, restore_early); 213 } 214 EXPORT_SYMBOL_GPL(pm_generic_restore_early); 215 216 /** 217 * pm_generic_restore - Generic restore callback for subsystems. 218 * @dev: Device to restore. 219 */ 220 int pm_generic_restore(struct device *dev) 221 { 222 return CALL_PM_OP(dev, restore); 223 } 224 EXPORT_SYMBOL_GPL(pm_generic_restore); 225 226 /** 227 * pm_generic_complete - Generic routine completing a device power transition. 228 * @dev: Device to handle. 229 * 230 * Complete a device power transition during a system-wide power transition. 231 */ 232 void pm_generic_complete(struct device *dev) 233 { 234 struct device_driver *drv = dev->driver; 235 236 if (drv && drv->pm && drv->pm->complete) 237 drv->pm->complete(dev); 238 } 239 #endif /* CONFIG_PM_SLEEP */ 240