diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-devices-power | 18 | ||||
| -rw-r--r-- | Documentation/power/runtime_pm.txt | 190 | ||||
| -rw-r--r-- | drivers/base/power/runtime.c | 186 | ||||
| -rw-r--r-- | drivers/base/power/sysfs.c | 40 | ||||
| -rw-r--r-- | include/linux/pm.h | 8 | ||||
| -rw-r--r-- | include/linux/pm_runtime.h | 45 |
6 files changed, 473 insertions, 14 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-power b/Documentation/ABI/testing/sysfs-devices-power index 6bb2dd3c3a71..7628cd1bc36a 100644 --- a/Documentation/ABI/testing/sysfs-devices-power +++ b/Documentation/ABI/testing/sysfs-devices-power | |||
| @@ -147,3 +147,21 @@ Description: | |||
| 147 | milliseconds. This attribute is read-only. If the device is | 147 | milliseconds. This attribute is read-only. If the device is |
| 148 | not enabled to wake up the system from sleep states, this | 148 | not enabled to wake up the system from sleep states, this |
| 149 | attribute is empty. | 149 | attribute is empty. |
| 150 | |||
| 151 | What: /sys/devices/.../power/autosuspend_delay_ms | ||
| 152 | Date: September 2010 | ||
| 153 | Contact: Alan Stern <stern@rowland.harvard.edu> | ||
| 154 | Description: | ||
| 155 | The /sys/devices/.../power/autosuspend_delay_ms attribute | ||
| 156 | contains the autosuspend delay value (in milliseconds). Some | ||
| 157 | drivers do not want their device to suspend as soon as it | ||
| 158 | becomes idle at run time; they want the device to remain | ||
| 159 | inactive for a certain minimum period of time first. That | ||
| 160 | period is called the autosuspend delay. Negative values will | ||
| 161 | prevent the device from being suspended at run time (similar | ||
| 162 | to writing "on" to the power/control attribute). Values >= | ||
| 163 | 1000 will cause the autosuspend timer expiration to be rounded | ||
| 164 | up to the nearest second. | ||
| 165 | |||
| 166 | Not all drivers support this attribute. If it isn't supported, | ||
| 167 | attempts to read or write it will yield I/O errors. | ||
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 9ba49b21ac86..489e9bacd165 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt | |||
| @@ -158,7 +158,8 @@ rules: | |||
| 158 | to execute it, the other callbacks will not be executed for the same device. | 158 | to execute it, the other callbacks will not be executed for the same device. |
| 159 | 159 | ||
| 160 | * A request to execute ->runtime_resume() will cancel any pending or | 160 | * A request to execute ->runtime_resume() will cancel any pending or |
| 161 | scheduled requests to execute the other callbacks for the same device. | 161 | scheduled requests to execute the other callbacks for the same device, |
| 162 | except for scheduled autosuspends. | ||
| 162 | 163 | ||
| 163 | 3. Run-time PM Device Fields | 164 | 3. Run-time PM Device Fields |
| 164 | 165 | ||
| @@ -166,7 +167,7 @@ The following device run-time PM fields are present in 'struct dev_pm_info', as | |||
| 166 | defined in include/linux/pm.h: | 167 | defined in include/linux/pm.h: |
| 167 | 168 | ||
| 168 | struct timer_list suspend_timer; | 169 | struct timer_list suspend_timer; |
| 169 | - timer used for scheduling (delayed) suspend request | 170 | - timer used for scheduling (delayed) suspend and autosuspend requests |
| 170 | 171 | ||
| 171 | unsigned long timer_expires; | 172 | unsigned long timer_expires; |
| 172 | - timer expiration time, in jiffies (if this is different from zero, the | 173 | - timer expiration time, in jiffies (if this is different from zero, the |
| @@ -236,6 +237,23 @@ defined in include/linux/pm.h: | |||
| 236 | Section 8); it may be modified only by the pm_runtime_no_callbacks() | 237 | Section 8); it may be modified only by the pm_runtime_no_callbacks() |
| 237 | helper function | 238 | helper function |
| 238 | 239 | ||
| 240 | unsigned int use_autosuspend; | ||
| 241 | - indicates that the device's driver supports delayed autosuspend (see | ||
| 242 | Section 9); it may be modified only by the | ||
| 243 | pm_runtime{_dont}_use_autosuspend() helper functions | ||
| 244 | |||
| 245 | unsigned int timer_autosuspends; | ||
| 246 | - indicates that the PM core should attempt to carry out an autosuspend | ||
| 247 | when the timer expires rather than a normal suspend | ||
| 248 | |||
| 249 | int autosuspend_delay; | ||
| 250 | - the delay time (in milliseconds) to be used for autosuspend | ||
| 251 | |||
| 252 | unsigned long last_busy; | ||
| 253 | - the time (in jiffies) when the pm_runtime_mark_last_busy() helper | ||
| 254 | function was last called for this device; used in calculating inactivity | ||
| 255 | periods for autosuspend | ||
| 256 | |||
| 239 | All of the above fields are members of the 'power' member of 'struct device'. | 257 | All of the above fields are members of the 'power' member of 'struct device'. |
| 240 | 258 | ||
| 241 | 4. Run-time PM Device Helper Functions | 259 | 4. Run-time PM Device Helper Functions |
| @@ -261,6 +279,12 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: | |||
| 261 | error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt | 279 | error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt |
| 262 | to suspend the device again in future | 280 | to suspend the device again in future |
| 263 | 281 | ||
| 282 | int pm_runtime_autosuspend(struct device *dev); | ||
| 283 | - same as pm_runtime_suspend() except that the autosuspend delay is taken | ||
| 284 | into account; if pm_runtime_autosuspend_expiration() says the delay has | ||
| 285 | not yet expired then an autosuspend is scheduled for the appropriate time | ||
| 286 | and 0 is returned | ||
| 287 | |||
| 264 | int pm_runtime_resume(struct device *dev); | 288 | int pm_runtime_resume(struct device *dev); |
| 265 | - execute the subsystem-level resume callback for the device; returns 0 on | 289 | - execute the subsystem-level resume callback for the device; returns 0 on |
| 266 | success, 1 if the device's run-time PM status was already 'active' or | 290 | success, 1 if the device's run-time PM status was already 'active' or |
| @@ -273,6 +297,11 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: | |||
| 273 | device (the request is represented by a work item in pm_wq); returns 0 on | 297 | device (the request is represented by a work item in pm_wq); returns 0 on |
| 274 | success or error code if the request has not been queued up | 298 | success or error code if the request has not been queued up |
| 275 | 299 | ||
| 300 | int pm_request_autosuspend(struct device *dev); | ||
| 301 | - schedule the execution of the subsystem-level suspend callback for the | ||
| 302 | device when the autosuspend delay has expired; if the delay has already | ||
| 303 | expired then the work item is queued up immediately | ||
| 304 | |||
| 276 | int pm_schedule_suspend(struct device *dev, unsigned int delay); | 305 | int pm_schedule_suspend(struct device *dev, unsigned int delay); |
| 277 | - schedule the execution of the subsystem-level suspend callback for the | 306 | - schedule the execution of the subsystem-level suspend callback for the |
| 278 | device in future, where 'delay' is the time to wait before queuing up a | 307 | device in future, where 'delay' is the time to wait before queuing up a |
| @@ -304,12 +333,20 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: | |||
| 304 | - decrement the device's usage counter | 333 | - decrement the device's usage counter |
| 305 | 334 | ||
| 306 | int pm_runtime_put(struct device *dev); | 335 | int pm_runtime_put(struct device *dev); |
| 307 | - decrement the device's usage counter, run pm_request_idle(dev) and return | 336 | - decrement the device's usage counter; if the result is 0 then run |
| 308 | its result | 337 | pm_request_idle(dev) and return its result |
| 338 | |||
| 339 | int pm_runtime_put_autosuspend(struct device *dev); | ||
| 340 | - decrement the device's usage counter; if the result is 0 then run | ||
| 341 | pm_request_autosuspend(dev) and return its result | ||
| 309 | 342 | ||
| 310 | int pm_runtime_put_sync(struct device *dev); | 343 | int pm_runtime_put_sync(struct device *dev); |
| 311 | - decrement the device's usage counter, run pm_runtime_idle(dev) and return | 344 | - decrement the device's usage counter; if the result is 0 then run |
| 312 | its result | 345 | pm_runtime_idle(dev) and return its result |
| 346 | |||
| 347 | int pm_runtime_put_sync_autosuspend(struct device *dev); | ||
| 348 | - decrement the device's usage counter; if the result is 0 then run | ||
| 349 | pm_runtime_autosuspend(dev) and return its result | ||
| 313 | 350 | ||
| 314 | void pm_runtime_enable(struct device *dev); | 351 | void pm_runtime_enable(struct device *dev); |
| 315 | - enable the run-time PM helper functions to run the device bus type's | 352 | - enable the run-time PM helper functions to run the device bus type's |
| @@ -360,19 +397,46 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: | |||
| 360 | PM attributes from /sys/devices/.../power (or prevent them from being | 397 | PM attributes from /sys/devices/.../power (or prevent them from being |
| 361 | added when the device is registered) | 398 | added when the device is registered) |
| 362 | 399 | ||
| 400 | void pm_runtime_mark_last_busy(struct device *dev); | ||
| 401 | - set the power.last_busy field to the current time | ||
| 402 | |||
| 403 | void pm_runtime_use_autosuspend(struct device *dev); | ||
| 404 | - set the power.use_autosuspend flag, enabling autosuspend delays | ||
| 405 | |||
| 406 | void pm_runtime_dont_use_autosuspend(struct device *dev); | ||
| 407 | - clear the power.use_autosuspend flag, disabling autosuspend delays | ||
| 408 | |||
| 409 | void pm_runtime_set_autosuspend_delay(struct device *dev, int delay); | ||
| 410 | - set the power.autosuspend_delay value to 'delay' (expressed in | ||
| 411 | milliseconds); if 'delay' is negative then run-time suspends are | ||
| 412 | prevented | ||
| 413 | |||
| 414 | unsigned long pm_runtime_autosuspend_expiration(struct device *dev); | ||
| 415 | - calculate the time when the current autosuspend delay period will expire, | ||
| 416 | based on power.last_busy and power.autosuspend_delay; if the delay time | ||
| 417 | is 1000 ms or larger then the expiration time is rounded up to the | ||
| 418 | nearest second; returns 0 if the delay period has already expired or | ||
| 419 | power.use_autosuspend isn't set, otherwise returns the expiration time | ||
| 420 | in jiffies | ||
| 421 | |||
| 363 | It is safe to execute the following helper functions from interrupt context: | 422 | It is safe to execute the following helper functions from interrupt context: |
| 364 | 423 | ||
| 365 | pm_request_idle() | 424 | pm_request_idle() |
| 425 | pm_request_autosuspend() | ||
| 366 | pm_schedule_suspend() | 426 | pm_schedule_suspend() |
| 367 | pm_request_resume() | 427 | pm_request_resume() |
| 368 | pm_runtime_get_noresume() | 428 | pm_runtime_get_noresume() |
| 369 | pm_runtime_get() | 429 | pm_runtime_get() |
| 370 | pm_runtime_put_noidle() | 430 | pm_runtime_put_noidle() |
| 371 | pm_runtime_put() | 431 | pm_runtime_put() |
| 432 | pm_runtime_put_autosuspend() | ||
| 433 | pm_runtime_enable() | ||
| 372 | pm_suspend_ignore_children() | 434 | pm_suspend_ignore_children() |
| 373 | pm_runtime_set_active() | 435 | pm_runtime_set_active() |
| 374 | pm_runtime_set_suspended() | 436 | pm_runtime_set_suspended() |
| 375 | pm_runtime_enable() | 437 | pm_runtime_suspended() |
| 438 | pm_runtime_mark_last_busy() | ||
| 439 | pm_runtime_autosuspend_expiration() | ||
| 376 | 440 | ||
| 377 | 5. Run-time PM Initialization, Device Probing and Removal | 441 | 5. Run-time PM Initialization, Device Probing and Removal |
| 378 | 442 | ||
| @@ -561,3 +625,115 @@ As a consequence, the PM core will never directly inform the device's subsystem | |||
| 561 | or driver about run-time power changes. Instead, the driver for the device's | 625 | or driver about run-time power changes. Instead, the driver for the device's |
| 562 | parent must take responsibility for telling the device's driver when the | 626 | parent must take responsibility for telling the device's driver when the |
| 563 | parent's power state changes. | 627 | parent's power state changes. |
| 628 | |||
| 629 | 9. Autosuspend, or automatically-delayed suspends | ||
| 630 | |||
| 631 | Changing a device's power state isn't free; it requires both time and energy. | ||
| 632 | A device should be put in a low-power state only when there's some reason to | ||
| 633 | think it will remain in that state for a substantial time. A common heuristic | ||
| 634 | says that a device which hasn't been used for a while is liable to remain | ||
| 635 | unused; following this advice, drivers should not allow devices to be suspended | ||
| 636 | at run-time until they have been inactive for some minimum period. Even when | ||
| 637 | the heuristic ends up being non-optimal, it will still prevent devices from | ||
| 638 | "bouncing" too rapidly between low-power and full-power states. | ||
| 639 | |||
| 640 | The term "autosuspend" is an historical remnant. It doesn't mean that the | ||
| 641 | device is automatically suspended (the subsystem or driver still has to call | ||
| 642 | the appropriate PM routines); rather it means that run-time suspends will | ||
| 643 | automatically be delayed until the desired period of inactivity has elapsed. | ||
| 644 | |||
| 645 | Inactivity is determined based on the power.last_busy field. Drivers should | ||
| 646 | call pm_runtime_mark_last_busy() to update this field after carrying out I/O, | ||
| 647 | typically just before calling pm_runtime_put_autosuspend(). The desired length | ||
| 648 | of the inactivity period is a matter of policy. Subsystems can set this length | ||
| 649 | initially by calling pm_runtime_set_autosuspend_delay(), but after device | ||
| 650 | registration the length should be controlled by user space, using the | ||
| 651 | /sys/devices/.../power/autosuspend_delay_ms attribute. | ||
| 652 | |||
| 653 | In order to use autosuspend, subsystems or drivers must call | ||
| 654 | pm_runtime_use_autosuspend() (preferably before registering the device), and | ||
| 655 | thereafter they should use the various *_autosuspend() helper functions instead | ||
| 656 | of the non-autosuspend counterparts: | ||
| 657 | |||
| 658 | Instead of: pm_runtime_suspend use: pm_runtime_autosuspend; | ||
| 659 | Instead of: pm_schedule_suspend use: pm_request_autosuspend; | ||
| 660 | Instead of: pm_runtime_put use: pm_runtime_put_autosuspend; | ||
| 661 | Instead of: pm_runtime_put_sync use: pm_runtime_put_sync_autosuspend. | ||
| 662 | |||
| 663 | Drivers may also continue to use the non-autosuspend helper functions; they | ||
| 664 | will behave normally, not taking the autosuspend delay into account. | ||
| 665 | Similarly, if the power.use_autosuspend field isn't set then the autosuspend | ||
| 666 | helper functions will behave just like the non-autosuspend counterparts. | ||
| 667 | |||
| 668 | The implementation is well suited for asynchronous use in interrupt contexts. | ||
| 669 | However such use inevitably involves races, because the PM core can't | ||
| 670 | synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. | ||
| 671 | This synchronization must be handled by the driver, using its private lock. | ||
| 672 | Here is a schematic pseudo-code example: | ||
| 673 | |||
| 674 | foo_read_or_write(struct foo_priv *foo, void *data) | ||
| 675 | { | ||
| 676 | lock(&foo->private_lock); | ||
| 677 | add_request_to_io_queue(foo, data); | ||
| 678 | if (foo->num_pending_requests++ == 0) | ||
| 679 | pm_runtime_get(&foo->dev); | ||
| 680 | if (!foo->is_suspended) | ||
| 681 | foo_process_next_request(foo); | ||
| 682 | unlock(&foo->private_lock); | ||
| 683 | } | ||
| 684 | |||
| 685 | foo_io_completion(struct foo_priv *foo, void *req) | ||
| 686 | { | ||
| 687 | lock(&foo->private_lock); | ||
| 688 | if (--foo->num_pending_requests == 0) { | ||
| 689 | pm_runtime_mark_last_busy(&foo->dev); | ||
| 690 | pm_runtime_put_autosuspend(&foo->dev); | ||
| 691 | } else { | ||
| 692 | foo_process_next_request(foo); | ||
| 693 | } | ||
| 694 | unlock(&foo->private_lock); | ||
| 695 | /* Send req result back to the user ... */ | ||
| 696 | } | ||
| 697 | |||
| 698 | int foo_runtime_suspend(struct device *dev) | ||
| 699 | { | ||
| 700 | struct foo_priv foo = container_of(dev, ...); | ||
| 701 | int ret = 0; | ||
| 702 | |||
| 703 | lock(&foo->private_lock); | ||
| 704 | if (foo->num_pending_requests > 0) { | ||
| 705 | ret = -EBUSY; | ||
| 706 | } else { | ||
| 707 | /* ... suspend the device ... */ | ||
| 708 | foo->is_suspended = 1; | ||
| 709 | } | ||
| 710 | unlock(&foo->private_lock); | ||
| 711 | return ret; | ||
| 712 | } | ||
| 713 | |||
| 714 | int foo_runtime_resume(struct device *dev) | ||
| 715 | { | ||
| 716 | struct foo_priv foo = container_of(dev, ...); | ||
| 717 | |||
| 718 | lock(&foo->private_lock); | ||
| 719 | /* ... resume the device ... */ | ||
| 720 | foo->is_suspended = 0; | ||
| 721 | pm_runtime_mark_last_busy(&foo->dev); | ||
| 722 | if (foo->num_pending_requests > 0) | ||
| 723 | foo_process_requests(foo); | ||
| 724 | unlock(&foo->private_lock); | ||
| 725 | return 0; | ||
| 726 | } | ||
| 727 | |||
| 728 | The important point is that after foo_io_completion() asks for an autosuspend, | ||
| 729 | the foo_runtime_suspend() callback may race with foo_read_or_write(). | ||
| 730 | Therefore foo_runtime_suspend() has to check whether there are any pending I/O | ||
| 731 | requests (while holding the private lock) before allowing the suspend to | ||
| 732 | proceed. | ||
| 733 | |||
| 734 | In addition, the power.autosuspend_delay field can be changed by user space at | ||
| 735 | any time. If a driver cares about this, it can call | ||
| 736 | pm_runtime_autosuspend_expiration() from within the ->runtime_suspend() | ||
| 737 | callback while holding its private lock. If the function returns a nonzero | ||
| 738 | value then the delay has not yet expired and the callback should return | ||
| 739 | -EAGAIN. | ||
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 5bd4daa93ef1..cd4e100a1362 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | 9 | ||
| 10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
| 11 | #include <linux/pm_runtime.h> | 11 | #include <linux/pm_runtime.h> |
| 12 | #include <linux/jiffies.h> | ||
| 13 | #include "power.h" | 12 | #include "power.h" |
| 14 | 13 | ||
| 15 | static int rpm_resume(struct device *dev, int rpmflags); | 14 | static int rpm_resume(struct device *dev, int rpmflags); |
| @@ -79,6 +78,53 @@ static void pm_runtime_cancel_pending(struct device *dev) | |||
| 79 | dev->power.request = RPM_REQ_NONE; | 78 | dev->power.request = RPM_REQ_NONE; |
| 80 | } | 79 | } |
| 81 | 80 | ||
| 81 | /* | ||
| 82 | * pm_runtime_autosuspend_expiration - Get a device's autosuspend-delay expiration time. | ||
| 83 | * @dev: Device to handle. | ||
| 84 | * | ||
| 85 | * Compute the autosuspend-delay expiration time based on the device's | ||
| 86 | * power.last_busy time. If the delay has already expired or is disabled | ||
| 87 | * (negative) or the power.use_autosuspend flag isn't set, return 0. | ||
| 88 | * Otherwise return the expiration time in jiffies (adjusted to be nonzero). | ||
| 89 | * | ||
| 90 | * This function may be called either with or without dev->power.lock held. | ||
| 91 | * Either way it can be racy, since power.last_busy may be updated at any time. | ||
| 92 | */ | ||
| 93 | unsigned long pm_runtime_autosuspend_expiration(struct device *dev) | ||
| 94 | { | ||
| 95 | int autosuspend_delay; | ||
| 96 | long elapsed; | ||
| 97 | unsigned long last_busy; | ||
| 98 | unsigned long expires = 0; | ||
| 99 | |||
| 100 | if (!dev->power.use_autosuspend) | ||
| 101 | goto out; | ||
| 102 | |||
| 103 | autosuspend_delay = ACCESS_ONCE(dev->power.autosuspend_delay); | ||
| 104 | if (autosuspend_delay < 0) | ||
| 105 | goto out; | ||
| 106 | |||
| 107 | last_busy = ACCESS_ONCE(dev->power.last_busy); | ||
| 108 | elapsed = jiffies - last_busy; | ||
| 109 | if (elapsed < 0) | ||
| 110 | goto out; /* jiffies has wrapped around. */ | ||
| 111 | |||
| 112 | /* | ||
| 113 | * If the autosuspend_delay is >= 1 second, align the timer by rounding | ||
| 114 | * up to the nearest second. | ||
| 115 | */ | ||
| 116 | expires = last_busy + msecs_to_jiffies(autosuspend_delay); | ||
| 117 | if (autosuspend_delay >= 1000) | ||
| 118 | expires = round_jiffies(expires); | ||
| 119 | expires += !expires; | ||
| 120 | if (elapsed >= expires - last_busy) | ||
| 121 | expires = 0; /* Already expired. */ | ||
| 122 | |||
| 123 | out: | ||
| 124 | return expires; | ||
| 125 | } | ||
| 126 | EXPORT_SYMBOL_GPL(pm_runtime_autosuspend_expiration); | ||
| 127 | |||
| 82 | /** | 128 | /** |
| 83 | * rpm_check_suspend_allowed - Test whether a device may be suspended. | 129 | * rpm_check_suspend_allowed - Test whether a device may be suspended. |
| 84 | * @dev: Device to test. | 130 | * @dev: Device to test. |
| @@ -234,6 +280,32 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
| 234 | if (retval) | 280 | if (retval) |
| 235 | goto out; | 281 | goto out; |
| 236 | 282 | ||
| 283 | /* If the autosuspend_delay time hasn't expired yet, reschedule. */ | ||
| 284 | if ((rpmflags & RPM_AUTO) | ||
| 285 | && dev->power.runtime_status != RPM_SUSPENDING) { | ||
| 286 | unsigned long expires = pm_runtime_autosuspend_expiration(dev); | ||
| 287 | |||
| 288 | if (expires != 0) { | ||
| 289 | /* Pending requests need to be canceled. */ | ||
| 290 | dev->power.request = RPM_REQ_NONE; | ||
| 291 | |||
| 292 | /* | ||
| 293 | * Optimization: If the timer is already running and is | ||
| 294 | * set to expire at or before the autosuspend delay, | ||
| 295 | * avoid the overhead of resetting it. Just let it | ||
| 296 | * expire; pm_suspend_timer_fn() will take care of the | ||
| 297 | * rest. | ||
| 298 | */ | ||
| 299 | if (!(dev->power.timer_expires && time_before_eq( | ||
| 300 | dev->power.timer_expires, expires))) { | ||
| 301 | dev->power.timer_expires = expires; | ||
| 302 | mod_timer(&dev->power.suspend_timer, expires); | ||
| 303 | } | ||
| 304 | dev->power.timer_autosuspends = 1; | ||
| 305 | goto out; | ||
| 306 | } | ||
| 307 | } | ||
| 308 | |||
| 237 | /* Other scheduled or pending requests need to be canceled. */ | 309 | /* Other scheduled or pending requests need to be canceled. */ |
| 238 | pm_runtime_cancel_pending(dev); | 310 | pm_runtime_cancel_pending(dev); |
| 239 | 311 | ||
| @@ -268,7 +340,8 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
| 268 | 340 | ||
| 269 | /* Carry out an asynchronous or a synchronous suspend. */ | 341 | /* Carry out an asynchronous or a synchronous suspend. */ |
| 270 | if (rpmflags & RPM_ASYNC) { | 342 | if (rpmflags & RPM_ASYNC) { |
| 271 | dev->power.request = RPM_REQ_SUSPEND; | 343 | dev->power.request = (rpmflags & RPM_AUTO) ? |
| 344 | RPM_REQ_AUTOSUSPEND : RPM_REQ_SUSPEND; | ||
| 272 | if (!dev->power.request_pending) { | 345 | if (!dev->power.request_pending) { |
| 273 | dev->power.request_pending = true; | 346 | dev->power.request_pending = true; |
| 274 | queue_work(pm_wq, &dev->power.work); | 347 | queue_work(pm_wq, &dev->power.work); |
| @@ -383,8 +456,15 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
| 383 | if (retval) | 456 | if (retval) |
| 384 | goto out; | 457 | goto out; |
| 385 | 458 | ||
| 386 | /* Other scheduled or pending requests need to be canceled. */ | 459 | /* |
| 387 | pm_runtime_cancel_pending(dev); | 460 | * Other scheduled or pending requests need to be canceled. Small |
| 461 | * optimization: If an autosuspend timer is running, leave it running | ||
| 462 | * rather than cancelling it now only to restart it again in the near | ||
| 463 | * future. | ||
| 464 | */ | ||
| 465 | dev->power.request = RPM_REQ_NONE; | ||
| 466 | if (!dev->power.timer_autosuspends) | ||
| 467 | pm_runtime_deactivate_timer(dev); | ||
| 388 | 468 | ||
| 389 | if (dev->power.runtime_status == RPM_ACTIVE) { | 469 | if (dev->power.runtime_status == RPM_ACTIVE) { |
| 390 | retval = 1; | 470 | retval = 1; |
| @@ -568,6 +648,9 @@ static void pm_runtime_work(struct work_struct *work) | |||
| 568 | case RPM_REQ_SUSPEND: | 648 | case RPM_REQ_SUSPEND: |
| 569 | rpm_suspend(dev, RPM_NOWAIT); | 649 | rpm_suspend(dev, RPM_NOWAIT); |
| 570 | break; | 650 | break; |
| 651 | case RPM_REQ_AUTOSUSPEND: | ||
| 652 | rpm_suspend(dev, RPM_NOWAIT | RPM_AUTO); | ||
| 653 | break; | ||
| 571 | case RPM_REQ_RESUME: | 654 | case RPM_REQ_RESUME: |
| 572 | rpm_resume(dev, RPM_NOWAIT); | 655 | rpm_resume(dev, RPM_NOWAIT); |
| 573 | break; | 656 | break; |
| @@ -595,7 +678,8 @@ static void pm_suspend_timer_fn(unsigned long data) | |||
| 595 | /* If 'expire' is after 'jiffies' we've been called too early. */ | 678 | /* If 'expire' is after 'jiffies' we've been called too early. */ |
| 596 | if (expires > 0 && !time_after(expires, jiffies)) { | 679 | if (expires > 0 && !time_after(expires, jiffies)) { |
| 597 | dev->power.timer_expires = 0; | 680 | dev->power.timer_expires = 0; |
| 598 | rpm_suspend(dev, RPM_ASYNC); | 681 | rpm_suspend(dev, dev->power.timer_autosuspends ? |
| 682 | (RPM_ASYNC | RPM_AUTO) : RPM_ASYNC); | ||
| 599 | } | 683 | } |
| 600 | 684 | ||
| 601 | spin_unlock_irqrestore(&dev->power.lock, flags); | 685 | spin_unlock_irqrestore(&dev->power.lock, flags); |
| @@ -627,6 +711,7 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay) | |||
| 627 | 711 | ||
| 628 | dev->power.timer_expires = jiffies + msecs_to_jiffies(delay); | 712 | dev->power.timer_expires = jiffies + msecs_to_jiffies(delay); |
| 629 | dev->power.timer_expires += !dev->power.timer_expires; | 713 | dev->power.timer_expires += !dev->power.timer_expires; |
| 714 | dev->power.timer_autosuspends = 0; | ||
| 630 | mod_timer(&dev->power.suspend_timer, dev->power.timer_expires); | 715 | mod_timer(&dev->power.suspend_timer, dev->power.timer_expires); |
| 631 | 716 | ||
| 632 | out: | 717 | out: |
| @@ -670,7 +755,9 @@ EXPORT_SYMBOL_GPL(__pm_runtime_idle); | |||
| 670 | * @dev: Device to suspend. | 755 | * @dev: Device to suspend. |
| 671 | * @rpmflags: Flag bits. | 756 | * @rpmflags: Flag bits. |
| 672 | * | 757 | * |
| 673 | * Carry out a suspend, either synchronous or asynchronous. | 758 | * If the RPM_GET_PUT flag is set, decrement the device's usage count and |
| 759 | * return immediately if it is larger than zero. Then carry out a suspend, | ||
| 760 | * either synchronous or asynchronous. | ||
| 674 | * | 761 | * |
| 675 | * This routine may be called in atomic context if the RPM_ASYNC flag is set. | 762 | * This routine may be called in atomic context if the RPM_ASYNC flag is set. |
| 676 | */ | 763 | */ |
| @@ -679,6 +766,11 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags) | |||
| 679 | unsigned long flags; | 766 | unsigned long flags; |
| 680 | int retval; | 767 | int retval; |
| 681 | 768 | ||
| 769 | if (rpmflags & RPM_GET_PUT) { | ||
| 770 | if (!atomic_dec_and_test(&dev->power.usage_count)) | ||
| 771 | return 0; | ||
| 772 | } | ||
| 773 | |||
| 682 | spin_lock_irqsave(&dev->power.lock, flags); | 774 | spin_lock_irqsave(&dev->power.lock, flags); |
| 683 | retval = rpm_suspend(dev, rpmflags); | 775 | retval = rpm_suspend(dev, rpmflags); |
| 684 | spin_unlock_irqrestore(&dev->power.lock, flags); | 776 | spin_unlock_irqrestore(&dev->power.lock, flags); |
| @@ -980,7 +1072,7 @@ void pm_runtime_allow(struct device *dev) | |||
| 980 | 1072 | ||
| 981 | dev->power.runtime_auto = true; | 1073 | dev->power.runtime_auto = true; |
| 982 | if (atomic_dec_and_test(&dev->power.usage_count)) | 1074 | if (atomic_dec_and_test(&dev->power.usage_count)) |
| 983 | rpm_idle(dev, 0); | 1075 | rpm_idle(dev, RPM_AUTO); |
| 984 | 1076 | ||
| 985 | out: | 1077 | out: |
| 986 | spin_unlock_irq(&dev->power.lock); | 1078 | spin_unlock_irq(&dev->power.lock); |
| @@ -1007,6 +1099,86 @@ void pm_runtime_no_callbacks(struct device *dev) | |||
| 1007 | EXPORT_SYMBOL_GPL(pm_runtime_no_callbacks); | 1099 | EXPORT_SYMBOL_GPL(pm_runtime_no_callbacks); |
| 1008 | 1100 | ||
| 1009 | /** | 1101 | /** |
| 1102 | * update_autosuspend - Handle a change to a device's autosuspend settings. | ||
| 1103 | * @dev: Device to handle. | ||
| 1104 | * @old_delay: The former autosuspend_delay value. | ||
| 1105 | * @old_use: The former use_autosuspend value. | ||
| 1106 | * | ||
| 1107 | * Prevent runtime suspend if the new delay is negative and use_autosuspend is | ||
| 1108 | * set; otherwise allow it. Send an idle notification if suspends are allowed. | ||
| 1109 | * | ||
| 1110 | * This function must be called under dev->power.lock with interrupts disabled. | ||
| 1111 | */ | ||
| 1112 | static void update_autosuspend(struct device *dev, int old_delay, int old_use) | ||
| 1113 | { | ||
| 1114 | int delay = dev->power.autosuspend_delay; | ||
| 1115 | |||
| 1116 | /* Should runtime suspend be prevented now? */ | ||
| 1117 | if (dev->power.use_autosuspend && delay < 0) { | ||
| 1118 | |||
| 1119 | /* If it used to be allowed then prevent it. */ | ||
| 1120 | if (!old_use || old_delay >= 0) { | ||
| 1121 | atomic_inc(&dev->power.usage_count); | ||
| 1122 | rpm_resume(dev, 0); | ||
| 1123 | } | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | /* Runtime suspend should be allowed now. */ | ||
| 1127 | else { | ||
| 1128 | |||
| 1129 | /* If it used to be prevented then allow it. */ | ||
| 1130 | if (old_use && old_delay < 0) | ||
| 1131 | atomic_dec(&dev->power.usage_count); | ||
| 1132 | |||
| 1133 | /* Maybe we can autosuspend now. */ | ||
| 1134 | rpm_idle(dev, RPM_AUTO); | ||
| 1135 | } | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | /** | ||
| 1139 | * pm_runtime_set_autosuspend_delay - Set a device's autosuspend_delay value. | ||
| 1140 | * @dev: Device to handle. | ||
| 1141 | * @delay: Value of the new delay in milliseconds. | ||
| 1142 | * | ||
| 1143 | * Set the device's power.autosuspend_delay value. If it changes to negative | ||
| 1144 | * and the power.use_autosuspend flag is set, prevent run-time suspends. If it | ||
| 1145 | * changes the other way, allow run-time suspends. | ||
| 1146 | */ | ||
| 1147 | void pm_runtime_set_autosuspend_delay(struct device *dev, int delay) | ||
| 1148 | { | ||
| 1149 | int old_delay, old_use; | ||
| 1150 | |||
| 1151 | spin_lock_irq(&dev->power.lock); | ||
| 1152 | old_delay = dev->power.autosuspend_delay; | ||
| 1153 | old_use = dev->power.use_autosuspend; | ||
| 1154 | dev->power.autosuspend_delay = delay; | ||
| 1155 | update_autosuspend(dev, old_delay, old_use); | ||
| 1156 | spin_unlock_irq(&dev->power.lock); | ||
| 1157 | } | ||
| 1158 | EXPORT_SYMBOL_GPL(pm_runtime_set_autosuspend_delay); | ||
| 1159 | |||
| 1160 | /** | ||
| 1161 | * __pm_runtime_use_autosuspend - Set a device's use_autosuspend flag. | ||
| 1162 | * @dev: Device to handle. | ||
| 1163 | * @use: New value for use_autosuspend. | ||
| 1164 | * | ||
| 1165 | * Set the device's power.use_autosuspend flag, and allow or prevent run-time | ||
| 1166 | * suspends as needed. | ||
| 1167 | */ | ||
| 1168 | void __pm_runtime_use_autosuspend(struct device *dev, bool use) | ||
| 1169 | { | ||
| 1170 | int old_delay, old_use; | ||
| 1171 | |||
| 1172 | spin_lock_irq(&dev->power.lock); | ||
| 1173 | old_delay = dev->power.autosuspend_delay; | ||
| 1174 | old_use = dev->power.use_autosuspend; | ||
| 1175 | dev->power.use_autosuspend = use; | ||
| 1176 | update_autosuspend(dev, old_delay, old_use); | ||
| 1177 | spin_unlock_irq(&dev->power.lock); | ||
| 1178 | } | ||
| 1179 | EXPORT_SYMBOL_GPL(__pm_runtime_use_autosuspend); | ||
| 1180 | |||
| 1181 | /** | ||
| 1010 | * pm_runtime_init - Initialize run-time PM fields in given device object. | 1182 | * pm_runtime_init - Initialize run-time PM fields in given device object. |
| 1011 | * @dev: Device object to initialize. | 1183 | * @dev: Device object to initialize. |
| 1012 | */ | 1184 | */ |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index b5708c47ce2d..0b1e46bf3e56 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
| @@ -75,6 +75,18 @@ | |||
| 75 | * attribute is set to "enabled" by bus type code or device drivers and in | 75 | * attribute is set to "enabled" by bus type code or device drivers and in |
| 76 | * that cases it should be safe to leave the default value. | 76 | * that cases it should be safe to leave the default value. |
| 77 | * | 77 | * |
| 78 | * autosuspend_delay_ms - Report/change a device's autosuspend_delay value | ||
| 79 | * | ||
| 80 | * Some drivers don't want to carry out a runtime suspend as soon as a | ||
| 81 | * device becomes idle; they want it always to remain idle for some period | ||
| 82 | * of time before suspending it. This period is the autosuspend_delay | ||
| 83 | * value (expressed in milliseconds) and it can be controlled by the user. | ||
| 84 | * If the value is negative then the device will never be runtime | ||
| 85 | * suspended. | ||
| 86 | * | ||
| 87 | * NOTE: The autosuspend_delay_ms attribute and the autosuspend_delay | ||
| 88 | * value are used only if the driver calls pm_runtime_use_autosuspend(). | ||
| 89 | * | ||
| 78 | * wakeup_count - Report the number of wakeup events related to the device | 90 | * wakeup_count - Report the number of wakeup events related to the device |
| 79 | */ | 91 | */ |
| 80 | 92 | ||
| @@ -173,6 +185,33 @@ static ssize_t rtpm_status_show(struct device *dev, | |||
| 173 | } | 185 | } |
| 174 | 186 | ||
| 175 | static DEVICE_ATTR(runtime_status, 0444, rtpm_status_show, NULL); | 187 | static DEVICE_ATTR(runtime_status, 0444, rtpm_status_show, NULL); |
| 188 | |||
| 189 | static ssize_t autosuspend_delay_ms_show(struct device *dev, | ||
| 190 | struct device_attribute *attr, char *buf) | ||
| 191 | { | ||
| 192 | if (!dev->power.use_autosuspend) | ||
| 193 | return -EIO; | ||
| 194 | return sprintf(buf, "%d\n", dev->power.autosuspend_delay); | ||
| 195 | } | ||
| 196 | |||
| 197 | static ssize_t autosuspend_delay_ms_store(struct device *dev, | ||
| 198 | struct device_attribute *attr, const char *buf, size_t n) | ||
| 199 | { | ||
| 200 | long delay; | ||
| 201 | |||
| 202 | if (!dev->power.use_autosuspend) | ||
| 203 | return -EIO; | ||
| 204 | |||
| 205 | if (strict_strtol(buf, 10, &delay) != 0 || delay != (int) delay) | ||
| 206 | return -EINVAL; | ||
| 207 | |||
| 208 | pm_runtime_set_autosuspend_delay(dev, delay); | ||
| 209 | return n; | ||
| 210 | } | ||
| 211 | |||
| 212 | static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show, | ||
| 213 | autosuspend_delay_ms_store); | ||
| 214 | |||
| 176 | #endif | 215 | #endif |
| 177 | 216 | ||
| 178 | static ssize_t | 217 | static ssize_t |
| @@ -428,6 +467,7 @@ static struct attribute *runtime_attrs[] = { | |||
| 428 | &dev_attr_control.attr, | 467 | &dev_attr_control.attr, |
| 429 | &dev_attr_runtime_suspended_time.attr, | 468 | &dev_attr_runtime_suspended_time.attr, |
| 430 | &dev_attr_runtime_active_time.attr, | 469 | &dev_attr_runtime_active_time.attr, |
| 470 | &dev_attr_autosuspend_delay_ms.attr, | ||
| 431 | NULL, | 471 | NULL, |
| 432 | }; | 472 | }; |
| 433 | static struct attribute_group pm_runtime_attr_group = { | 473 | static struct attribute_group pm_runtime_attr_group = { |
diff --git a/include/linux/pm.h b/include/linux/pm.h index abd81ffaba3c..40f3f45702ba 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
| @@ -444,6 +444,9 @@ enum rpm_status { | |||
| 444 | * | 444 | * |
| 445 | * RPM_REQ_SUSPEND Run the device bus type's ->runtime_suspend() callback | 445 | * RPM_REQ_SUSPEND Run the device bus type's ->runtime_suspend() callback |
| 446 | * | 446 | * |
| 447 | * RPM_REQ_AUTOSUSPEND Same as RPM_REQ_SUSPEND, but not until the device has | ||
| 448 | * been inactive for as long as power.autosuspend_delay | ||
| 449 | * | ||
| 447 | * RPM_REQ_RESUME Run the device bus type's ->runtime_resume() callback | 450 | * RPM_REQ_RESUME Run the device bus type's ->runtime_resume() callback |
| 448 | */ | 451 | */ |
| 449 | 452 | ||
| @@ -451,6 +454,7 @@ enum rpm_request { | |||
| 451 | RPM_REQ_NONE = 0, | 454 | RPM_REQ_NONE = 0, |
| 452 | RPM_REQ_IDLE, | 455 | RPM_REQ_IDLE, |
| 453 | RPM_REQ_SUSPEND, | 456 | RPM_REQ_SUSPEND, |
| 457 | RPM_REQ_AUTOSUSPEND, | ||
| 454 | RPM_REQ_RESUME, | 458 | RPM_REQ_RESUME, |
| 455 | }; | 459 | }; |
| 456 | 460 | ||
| @@ -482,9 +486,13 @@ struct dev_pm_info { | |||
| 482 | unsigned int run_wake:1; | 486 | unsigned int run_wake:1; |
| 483 | unsigned int runtime_auto:1; | 487 | unsigned int runtime_auto:1; |
| 484 | unsigned int no_callbacks:1; | 488 | unsigned int no_callbacks:1; |
| 489 | unsigned int use_autosuspend:1; | ||
| 490 | unsigned int timer_autosuspends:1; | ||
| 485 | enum rpm_request request; | 491 | enum rpm_request request; |
| 486 | enum rpm_status runtime_status; | 492 | enum rpm_status runtime_status; |
| 487 | int runtime_error; | 493 | int runtime_error; |
| 494 | int autosuspend_delay; | ||
| 495 | unsigned long last_busy; | ||
| 488 | unsigned long active_jiffies; | 496 | unsigned long active_jiffies; |
| 489 | unsigned long suspended_jiffies; | 497 | unsigned long suspended_jiffies; |
| 490 | unsigned long accounting_timestamp; | 498 | unsigned long accounting_timestamp; |
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 8ca52f7c357e..99ed1aa8f933 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h | |||
| @@ -12,12 +12,15 @@ | |||
| 12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| 13 | #include <linux/pm.h> | 13 | #include <linux/pm.h> |
| 14 | 14 | ||
| 15 | #include <linux/jiffies.h> | ||
| 16 | |||
| 15 | /* Runtime PM flag argument bits */ | 17 | /* Runtime PM flag argument bits */ |
| 16 | #define RPM_ASYNC 0x01 /* Request is asynchronous */ | 18 | #define RPM_ASYNC 0x01 /* Request is asynchronous */ |
| 17 | #define RPM_NOWAIT 0x02 /* Don't wait for concurrent | 19 | #define RPM_NOWAIT 0x02 /* Don't wait for concurrent |
| 18 | state change */ | 20 | state change */ |
| 19 | #define RPM_GET_PUT 0x04 /* Increment/decrement the | 21 | #define RPM_GET_PUT 0x04 /* Increment/decrement the |
| 20 | usage_count */ | 22 | usage_count */ |
| 23 | #define RPM_AUTO 0x08 /* Use autosuspend_delay */ | ||
| 21 | 24 | ||
| 22 | #ifdef CONFIG_PM_RUNTIME | 25 | #ifdef CONFIG_PM_RUNTIME |
| 23 | 26 | ||
| @@ -37,6 +40,9 @@ extern int pm_generic_runtime_idle(struct device *dev); | |||
| 37 | extern int pm_generic_runtime_suspend(struct device *dev); | 40 | extern int pm_generic_runtime_suspend(struct device *dev); |
| 38 | extern int pm_generic_runtime_resume(struct device *dev); | 41 | extern int pm_generic_runtime_resume(struct device *dev); |
| 39 | extern void pm_runtime_no_callbacks(struct device *dev); | 42 | extern void pm_runtime_no_callbacks(struct device *dev); |
| 43 | extern void __pm_runtime_use_autosuspend(struct device *dev, bool use); | ||
| 44 | extern void pm_runtime_set_autosuspend_delay(struct device *dev, int delay); | ||
| 45 | extern unsigned long pm_runtime_autosuspend_expiration(struct device *dev); | ||
| 40 | 46 | ||
| 41 | static inline bool pm_children_suspended(struct device *dev) | 47 | static inline bool pm_children_suspended(struct device *dev) |
| 42 | { | 48 | { |
| @@ -74,6 +80,11 @@ static inline bool pm_runtime_suspended(struct device *dev) | |||
| 74 | return dev->power.runtime_status == RPM_SUSPENDED; | 80 | return dev->power.runtime_status == RPM_SUSPENDED; |
| 75 | } | 81 | } |
| 76 | 82 | ||
| 83 | static inline void pm_runtime_mark_last_busy(struct device *dev) | ||
| 84 | { | ||
| 85 | ACCESS_ONCE(dev->power.last_busy) = jiffies; | ||
| 86 | } | ||
| 87 | |||
| 77 | #else /* !CONFIG_PM_RUNTIME */ | 88 | #else /* !CONFIG_PM_RUNTIME */ |
| 78 | 89 | ||
| 79 | static inline int __pm_runtime_idle(struct device *dev, int rpmflags) | 90 | static inline int __pm_runtime_idle(struct device *dev, int rpmflags) |
| @@ -113,6 +124,14 @@ static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } | |||
| 113 | static inline int pm_generic_runtime_resume(struct device *dev) { return 0; } | 124 | static inline int pm_generic_runtime_resume(struct device *dev) { return 0; } |
| 114 | static inline void pm_runtime_no_callbacks(struct device *dev) {} | 125 | static inline void pm_runtime_no_callbacks(struct device *dev) {} |
| 115 | 126 | ||
| 127 | static inline void pm_runtime_mark_last_busy(struct device *dev) {} | ||
| 128 | static inline void __pm_runtime_use_autosuspend(struct device *dev, | ||
| 129 | bool use) {} | ||
| 130 | static inline void pm_runtime_set_autosuspend_delay(struct device *dev, | ||
| 131 | int delay) {} | ||
| 132 | static inline unsigned long pm_runtime_autosuspend_expiration( | ||
| 133 | struct device *dev) { return 0; } | ||
| 134 | |||
| 116 | #endif /* !CONFIG_PM_RUNTIME */ | 135 | #endif /* !CONFIG_PM_RUNTIME */ |
| 117 | 136 | ||
| 118 | static inline int pm_runtime_idle(struct device *dev) | 137 | static inline int pm_runtime_idle(struct device *dev) |
| @@ -125,6 +144,11 @@ static inline int pm_runtime_suspend(struct device *dev) | |||
| 125 | return __pm_runtime_suspend(dev, 0); | 144 | return __pm_runtime_suspend(dev, 0); |
| 126 | } | 145 | } |
| 127 | 146 | ||
| 147 | static inline int pm_runtime_autosuspend(struct device *dev) | ||
| 148 | { | ||
| 149 | return __pm_runtime_suspend(dev, RPM_AUTO); | ||
| 150 | } | ||
| 151 | |||
| 128 | static inline int pm_runtime_resume(struct device *dev) | 152 | static inline int pm_runtime_resume(struct device *dev) |
| 129 | { | 153 | { |
| 130 | return __pm_runtime_resume(dev, 0); | 154 | return __pm_runtime_resume(dev, 0); |
| @@ -155,11 +179,22 @@ static inline int pm_runtime_put(struct device *dev) | |||
| 155 | return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC); | 179 | return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC); |
| 156 | } | 180 | } |
| 157 | 181 | ||
| 182 | static inline int pm_runtime_put_autosuspend(struct device *dev) | ||
| 183 | { | ||
| 184 | return __pm_runtime_suspend(dev, | ||
| 185 | RPM_GET_PUT | RPM_ASYNC | RPM_AUTO); | ||
| 186 | } | ||
| 187 | |||
| 158 | static inline int pm_runtime_put_sync(struct device *dev) | 188 | static inline int pm_runtime_put_sync(struct device *dev) |
| 159 | { | 189 | { |
| 160 | return __pm_runtime_idle(dev, RPM_GET_PUT); | 190 | return __pm_runtime_idle(dev, RPM_GET_PUT); |
| 161 | } | 191 | } |
| 162 | 192 | ||
| 193 | static inline int pm_runtime_put_sync_autosuspend(struct device *dev) | ||
| 194 | { | ||
| 195 | return __pm_runtime_suspend(dev, RPM_GET_PUT | RPM_AUTO); | ||
| 196 | } | ||
| 197 | |||
| 163 | static inline int pm_runtime_set_active(struct device *dev) | 198 | static inline int pm_runtime_set_active(struct device *dev) |
| 164 | { | 199 | { |
| 165 | return __pm_runtime_set_status(dev, RPM_ACTIVE); | 200 | return __pm_runtime_set_status(dev, RPM_ACTIVE); |
| @@ -175,4 +210,14 @@ static inline void pm_runtime_disable(struct device *dev) | |||
| 175 | __pm_runtime_disable(dev, true); | 210 | __pm_runtime_disable(dev, true); |
| 176 | } | 211 | } |
| 177 | 212 | ||
| 213 | static inline void pm_runtime_use_autosuspend(struct device *dev) | ||
| 214 | { | ||
| 215 | __pm_runtime_use_autosuspend(dev, true); | ||
| 216 | } | ||
| 217 | |||
| 218 | static inline void pm_runtime_dont_use_autosuspend(struct device *dev) | ||
| 219 | { | ||
| 220 | __pm_runtime_use_autosuspend(dev, false); | ||
| 221 | } | ||
| 222 | |||
| 178 | #endif | 223 | #endif |
