Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6:
PM: Provide generic subsystem-level callbacks
PM / Runtime: Document power.runtime_auto and related functions

+378 -6
+93
Documentation/power/runtime_pm.txt
··· 224 RPM_SUSPENDED, which means that each device is initially regarded by the 225 PM core as 'suspended', regardless of its real hardware status 226 227 All of the above fields are members of the 'power' member of 'struct device'. 228 229 4. Run-time PM Device Helper Functions ··· 335 'power.runtime_error' is set or 'power.disable_depth' is greater than 336 zero) 337 338 It is safe to execute the following helper functions from interrupt context: 339 340 pm_request_idle() ··· 402 finished, so the PM core uses pm_runtime_idle_sync() to invoke the 403 subsystem-level idle callback for the device at that time. 404 405 6. Run-time PM and System Sleep 406 407 Run-time PM and system sleep (i.e., system suspend and hibernation, also known ··· 463 ->prepare() callback and decrements it after calling the ->complete() callback. 464 Hence disabling run-time PM temporarily like this will not cause any run-time 465 suspend callbacks to be lost.
··· 224 RPM_SUSPENDED, which means that each device is initially regarded by the 225 PM core as 'suspended', regardless of its real hardware status 226 227 + unsigned int runtime_auto; 228 + - if set, indicates that the user space has allowed the device driver to 229 + power manage the device at run time via the /sys/devices/.../power/control 230 + interface; it may only be modified with the help of the pm_runtime_allow() 231 + and pm_runtime_forbid() helper functions 232 + 233 All of the above fields are members of the 'power' member of 'struct device'. 234 235 4. Run-time PM Device Helper Functions ··· 329 'power.runtime_error' is set or 'power.disable_depth' is greater than 330 zero) 331 332 + bool pm_runtime_suspended(struct device *dev); 333 + - return true if the device's runtime PM status is 'suspended', or false 334 + otherwise 335 + 336 + void pm_runtime_allow(struct device *dev); 337 + - set the power.runtime_auto flag for the device and decrease its usage 338 + counter (used by the /sys/devices/.../power/control interface to 339 + effectively allow the device to be power managed at run time) 340 + 341 + void pm_runtime_forbid(struct device *dev); 342 + - unset the power.runtime_auto flag for the device and increase its usage 343 + counter (used by the /sys/devices/.../power/control interface to 344 + effectively prevent the device from being power managed at run time) 345 + 346 It is safe to execute the following helper functions from interrupt context: 347 348 pm_request_idle() ··· 382 finished, so the PM core uses pm_runtime_idle_sync() to invoke the 383 subsystem-level idle callback for the device at that time. 384 385 + The user space can effectively disallow the driver of the device to power manage 386 + it at run time by changing the value of its /sys/devices/.../power/control 387 + attribute to "on", which causes pm_runtime_forbid() to be called. In principle, 388 + this mechanism may also be used by the driver to effectively turn off the 389 + run-time power management of the device until the user space turns it on. 390 + Namely, during the initialization the driver can make sure that the run-time PM 391 + status of the device is 'active' and call pm_runtime_forbid(). It should be 392 + noted, however, that if the user space has already intentionally changed the 393 + value of /sys/devices/.../power/control to "auto" to allow the driver to power 394 + manage the device at run time, the driver may confuse it by using 395 + pm_runtime_forbid() this way. 396 + 397 6. Run-time PM and System Sleep 398 399 Run-time PM and system sleep (i.e., system suspend and hibernation, also known ··· 431 ->prepare() callback and decrements it after calling the ->complete() callback. 432 Hence disabling run-time PM temporarily like this will not cause any run-time 433 suspend callbacks to be lost. 434 + 435 + 7. Generic subsystem callbacks 436 + 437 + Subsystems may wish to conserve code space by using the set of generic power 438 + management callbacks provided by the PM core, defined in 439 + driver/base/power/generic_ops.c: 440 + 441 + int pm_generic_runtime_idle(struct device *dev); 442 + - invoke the ->runtime_idle() callback provided by the driver of this 443 + device, if defined, and call pm_runtime_suspend() for this device if the 444 + return value is 0 or the callback is not defined 445 + 446 + int pm_generic_runtime_suspend(struct device *dev); 447 + - invoke the ->runtime_suspend() callback provided by the driver of this 448 + device and return its result, or return -EINVAL if not defined 449 + 450 + int pm_generic_runtime_resume(struct device *dev); 451 + - invoke the ->runtime_resume() callback provided by the driver of this 452 + device and return its result, or return -EINVAL if not defined 453 + 454 + int pm_generic_suspend(struct device *dev); 455 + - if the device has not been suspended at run time, invoke the ->suspend() 456 + callback provided by its driver and return its result, or return 0 if not 457 + defined 458 + 459 + int pm_generic_resume(struct device *dev); 460 + - invoke the ->resume() callback provided by the driver of this device and, 461 + if successful, change the device's runtime PM status to 'active' 462 + 463 + int pm_generic_freeze(struct device *dev); 464 + - if the device has not been suspended at run time, invoke the ->freeze() 465 + callback provided by its driver and return its result, or return 0 if not 466 + defined 467 + 468 + int pm_generic_thaw(struct device *dev); 469 + - if the device has not been suspended at run time, invoke the ->thaw() 470 + callback provided by its driver and return its result, or return 0 if not 471 + defined 472 + 473 + int pm_generic_poweroff(struct device *dev); 474 + - if the device has not been suspended at run time, invoke the ->poweroff() 475 + callback provided by its driver and return its result, or return 0 if not 476 + defined 477 + 478 + int pm_generic_restore(struct device *dev); 479 + - invoke the ->restore() callback provided by the driver of this device and, 480 + if successful, change the device's runtime PM status to 'active' 481 + 482 + These functions can be assigned to the ->runtime_idle(), ->runtime_suspend(), 483 + ->runtime_resume(), ->suspend(), ->resume(), ->freeze(), ->thaw(), ->poweroff(), 484 + or ->restore() callback pointers in the subsystem-level dev_pm_ops structures. 485 + 486 + If a subsystem wishes to use all of them at the same time, it can simply assign 487 + the GENERIC_SUBSYS_PM_OPS macro, defined in include/linux/pm.h, to its 488 + dev_pm_ops structure pointer. 489 + 490 + Device drivers that wish to use the same function as a system suspend, freeze, 491 + poweroff and run-time suspend callback, and similarly for system resume, thaw, 492 + restore, and run-time resume, can achieve this with the help of the 493 + UNIVERSAL_DEV_PM_OPS macro defined in include/linux/pm.h (possibly setting its 494 + last argument to NULL).
+1
drivers/base/power/Makefile
··· 1 obj-$(CONFIG_PM) += sysfs.o 2 obj-$(CONFIG_PM_SLEEP) += main.o 3 obj-$(CONFIG_PM_RUNTIME) += runtime.o 4 obj-$(CONFIG_PM_TRACE_RTC) += trace.o 5 6 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
··· 1 obj-$(CONFIG_PM) += sysfs.o 2 obj-$(CONFIG_PM_SLEEP) += main.o 3 obj-$(CONFIG_PM_RUNTIME) += runtime.o 4 + obj-$(CONFIG_PM_OPS) += generic_ops.o 5 obj-$(CONFIG_PM_TRACE_RTC) += trace.o 6 7 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
+233
drivers/base/power/generic_ops.c
···
··· 1 + /* 2 + * drivers/base/power/generic_ops.c - Generic PM callbacks for subsystems 3 + * 4 + * Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. 5 + * 6 + * This file is released under the GPLv2. 7 + */ 8 + 9 + #include <linux/pm.h> 10 + #include <linux/pm_runtime.h> 11 + 12 + #ifdef CONFIG_PM_RUNTIME 13 + /** 14 + * pm_generic_runtime_idle - Generic runtime idle callback for subsystems. 15 + * @dev: Device to handle. 16 + * 17 + * If PM operations are defined for the @dev's driver and they include 18 + * ->runtime_idle(), execute it and return its error code, if nonzero. 19 + * Otherwise, execute pm_runtime_suspend() for the device and return 0. 20 + */ 21 + int pm_generic_runtime_idle(struct device *dev) 22 + { 23 + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 24 + 25 + if (pm && pm->runtime_idle) { 26 + int ret = pm->runtime_idle(dev); 27 + if (ret) 28 + return ret; 29 + } 30 + 31 + pm_runtime_suspend(dev); 32 + return 0; 33 + } 34 + EXPORT_SYMBOL_GPL(pm_generic_runtime_idle); 35 + 36 + /** 37 + * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. 38 + * @dev: Device to suspend. 39 + * 40 + * If PM operations are defined for the @dev's driver and they include 41 + * ->runtime_suspend(), execute it and return its error code. Otherwise, 42 + * return -EINVAL. 43 + */ 44 + int pm_generic_runtime_suspend(struct device *dev) 45 + { 46 + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 47 + int ret; 48 + 49 + ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : -EINVAL; 50 + 51 + return ret; 52 + } 53 + EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend); 54 + 55 + /** 56 + * pm_generic_runtime_resume - Generic runtime resume callback for subsystems. 57 + * @dev: Device to resume. 58 + * 59 + * If PM operations are defined for the @dev's driver and they include 60 + * ->runtime_resume(), execute it and return its error code. Otherwise, 61 + * return -EINVAL. 62 + */ 63 + int pm_generic_runtime_resume(struct device *dev) 64 + { 65 + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 66 + int ret; 67 + 68 + ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : -EINVAL; 69 + 70 + return ret; 71 + } 72 + EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); 73 + #endif /* CONFIG_PM_RUNTIME */ 74 + 75 + #ifdef CONFIG_PM_SLEEP 76 + /** 77 + * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback. 78 + * @dev: Device to handle. 79 + * @event: PM transition of the system under way. 80 + * 81 + * If the device has not been suspended at run time, execute the 82 + * suspend/freeze/poweroff/thaw callback provided by its driver, if defined, and 83 + * return its error code. Otherwise, return zero. 84 + */ 85 + static int __pm_generic_call(struct device *dev, int event) 86 + { 87 + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 88 + int (*callback)(struct device *); 89 + 90 + if (!pm || pm_runtime_suspended(dev)) 91 + return 0; 92 + 93 + switch (event) { 94 + case PM_EVENT_SUSPEND: 95 + callback = pm->suspend; 96 + break; 97 + case PM_EVENT_FREEZE: 98 + callback = pm->freeze; 99 + break; 100 + case PM_EVENT_HIBERNATE: 101 + callback = pm->poweroff; 102 + break; 103 + case PM_EVENT_THAW: 104 + callback = pm->thaw; 105 + break; 106 + default: 107 + callback = NULL; 108 + break; 109 + } 110 + 111 + return callback ? callback(dev) : 0; 112 + } 113 + 114 + /** 115 + * pm_generic_suspend - Generic suspend callback for subsystems. 116 + * @dev: Device to suspend. 117 + */ 118 + int pm_generic_suspend(struct device *dev) 119 + { 120 + return __pm_generic_call(dev, PM_EVENT_SUSPEND); 121 + } 122 + EXPORT_SYMBOL_GPL(pm_generic_suspend); 123 + 124 + /** 125 + * pm_generic_freeze - Generic freeze callback for subsystems. 126 + * @dev: Device to freeze. 127 + */ 128 + int pm_generic_freeze(struct device *dev) 129 + { 130 + return __pm_generic_call(dev, PM_EVENT_FREEZE); 131 + } 132 + EXPORT_SYMBOL_GPL(pm_generic_freeze); 133 + 134 + /** 135 + * pm_generic_poweroff - Generic poweroff callback for subsystems. 136 + * @dev: Device to handle. 137 + */ 138 + int pm_generic_poweroff(struct device *dev) 139 + { 140 + return __pm_generic_call(dev, PM_EVENT_HIBERNATE); 141 + } 142 + EXPORT_SYMBOL_GPL(pm_generic_poweroff); 143 + 144 + /** 145 + * pm_generic_thaw - Generic thaw callback for subsystems. 146 + * @dev: Device to thaw. 147 + */ 148 + int pm_generic_thaw(struct device *dev) 149 + { 150 + return __pm_generic_call(dev, PM_EVENT_THAW); 151 + } 152 + EXPORT_SYMBOL_GPL(pm_generic_thaw); 153 + 154 + /** 155 + * __pm_generic_resume - Generic resume/restore callback for subsystems. 156 + * @dev: Device to handle. 157 + * @event: PM transition of the system under way. 158 + * 159 + * Execute the resume/resotre callback provided by the @dev's driver, if 160 + * defined. If it returns 0, change the device's runtime PM status to 'active'. 161 + * Return the callback's error code. 162 + */ 163 + static int __pm_generic_resume(struct device *dev, int event) 164 + { 165 + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 166 + int (*callback)(struct device *); 167 + int ret; 168 + 169 + if (!pm) 170 + return 0; 171 + 172 + switch (event) { 173 + case PM_EVENT_RESUME: 174 + callback = pm->resume; 175 + break; 176 + case PM_EVENT_RESTORE: 177 + callback = pm->restore; 178 + break; 179 + default: 180 + callback = NULL; 181 + break; 182 + } 183 + 184 + if (!callback) 185 + return 0; 186 + 187 + ret = callback(dev); 188 + if (!ret) { 189 + pm_runtime_disable(dev); 190 + pm_runtime_set_active(dev); 191 + pm_runtime_enable(dev); 192 + } 193 + 194 + return ret; 195 + } 196 + 197 + /** 198 + * pm_generic_resume - Generic resume callback for subsystems. 199 + * @dev: Device to resume. 200 + */ 201 + int pm_generic_resume(struct device *dev) 202 + { 203 + return __pm_generic_resume(dev, PM_EVENT_RESUME); 204 + } 205 + EXPORT_SYMBOL_GPL(pm_generic_resume); 206 + 207 + /** 208 + * pm_generic_restore - Generic restore callback for subsystems. 209 + * @dev: Device to restore. 210 + */ 211 + int pm_generic_restore(struct device *dev) 212 + { 213 + return __pm_generic_resume(dev, PM_EVENT_RESTORE); 214 + } 215 + EXPORT_SYMBOL_GPL(pm_generic_restore); 216 + #endif /* CONFIG_PM_SLEEP */ 217 + 218 + struct dev_pm_ops generic_subsys_pm_ops = { 219 + #ifdef CONFIG_PM_SLEEP 220 + .suspend = pm_generic_suspend, 221 + .resume = pm_generic_resume, 222 + .freeze = pm_generic_freeze, 223 + .thaw = pm_generic_thaw, 224 + .poweroff = pm_generic_poweroff, 225 + .restore = pm_generic_restore, 226 + #endif 227 + #ifdef CONFIG_PM_RUNTIME 228 + .runtime_suspend = pm_generic_runtime_suspend, 229 + .runtime_resume = pm_generic_runtime_resume, 230 + .runtime_idle = pm_generic_runtime_idle, 231 + #endif 232 + }; 233 + EXPORT_SYMBOL_GPL(generic_subsys_pm_ops);
+45 -6
include/linux/pm.h
··· 215 int (*runtime_idle)(struct device *dev); 216 }; 217 218 /* 219 * Use this if you want to use the same suspend and resume callbacks for suspend 220 * to RAM and hibernation. 221 */ 222 #define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ 223 const struct dev_pm_ops name = { \ 224 - .suspend = suspend_fn, \ 225 - .resume = resume_fn, \ 226 - .freeze = suspend_fn, \ 227 - .thaw = resume_fn, \ 228 - .poweroff = suspend_fn, \ 229 - .restore = resume_fn, \ 230 } 231 232 /** 233 * PM_EVENT_ messages
··· 215 int (*runtime_idle)(struct device *dev); 216 }; 217 218 + #ifdef CONFIG_PM_SLEEP 219 + #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 220 + .suspend = suspend_fn, \ 221 + .resume = resume_fn, \ 222 + .freeze = suspend_fn, \ 223 + .thaw = resume_fn, \ 224 + .poweroff = suspend_fn, \ 225 + .restore = resume_fn, 226 + #else 227 + #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) 228 + #endif 229 + 230 + #ifdef CONFIG_PM_RUNTIME 231 + #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ 232 + .runtime_suspend = suspend_fn, \ 233 + .runtime_resume = resume_fn, \ 234 + .runtime_idle = idle_fn, 235 + #else 236 + #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) 237 + #endif 238 + 239 /* 240 * Use this if you want to use the same suspend and resume callbacks for suspend 241 * to RAM and hibernation. 242 */ 243 #define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ 244 const struct dev_pm_ops name = { \ 245 + SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 246 } 247 + 248 + /* 249 + * Use this for defining a set of PM operations to be used in all situations 250 + * (sustem suspend, hibernation or runtime PM). 251 + */ 252 + #define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ 253 + const struct dev_pm_ops name = { \ 254 + SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 255 + SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ 256 + } 257 + 258 + /* 259 + * Use this for subsystems (bus types, device types, device classes) that don't 260 + * need any special suspend/resume handling in addition to invoking the PM 261 + * callbacks provided by device drivers supporting both the system sleep PM and 262 + * runtime PM, make the pm member point to generic_subsys_pm_ops. 263 + */ 264 + #ifdef CONFIG_PM_OPS 265 + extern struct dev_pm_ops generic_subsys_pm_ops; 266 + #define GENERIC_SUBSYS_PM_OPS (&generic_subsys_pm_ops) 267 + #else 268 + #define GENERIC_SUBSYS_PM_OPS NULL 269 + #endif 270 271 /** 272 * PM_EVENT_ messages
+6
include/linux/pm_runtime.h
··· 62 dev->power.run_wake = enable; 63 } 64 65 #else /* !CONFIG_PM_RUNTIME */ 66 67 static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; } ··· 94 static inline void pm_runtime_put_noidle(struct device *dev) {} 95 static inline bool device_run_wake(struct device *dev) { return false; } 96 static inline void device_set_run_wake(struct device *dev, bool enable) {} 97 98 #endif /* !CONFIG_PM_RUNTIME */ 99
··· 62 dev->power.run_wake = enable; 63 } 64 65 + static inline bool pm_runtime_suspended(struct device *dev) 66 + { 67 + return dev->power.runtime_status == RPM_SUSPENDED; 68 + } 69 + 70 #else /* !CONFIG_PM_RUNTIME */ 71 72 static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; } ··· 89 static inline void pm_runtime_put_noidle(struct device *dev) {} 90 static inline bool device_run_wake(struct device *dev) { return false; } 91 static inline void device_set_run_wake(struct device *dev, bool enable) {} 92 + static inline bool pm_runtime_suspended(struct device *dev) { return false; } 93 94 #endif /* !CONFIG_PM_RUNTIME */ 95