diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 17:53:17 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 17:53:17 -0400 |
| commit | a8cbf22559ceefdcdfac00701e8e6da7518b7e8e (patch) | |
| tree | 63ebd5779a37f809f7daed77dbf27aa3f1e1110c /include/linux | |
| parent | e36f561a2c88394ef2708f1ab300fe8a79e9f651 (diff) | |
| parent | 9c034392533f3e9f00656d5c58478cff2560ef81 (diff) | |
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: (26 commits)
PM / Wakeup: Show wakeup sources statistics in debugfs
PM: Introduce library for device-specific OPPs (v7)
PM: Add sysfs attr for rechecking dev hash from PM trace
PM: Lock PM device list mutex in show_dev_hash()
PM / Runtime: Remove idle notification after failing suspend
PM / Hibernate: Modify signature used to mark swap
PM / Runtime: Reduce code duplication in core helper functions
PM: Allow wakeup events to abort freezing of tasks
PM: runtime: add missed pm_request_autosuspend
PM / Hibernate: Make some boot messages look less scary
PM / Runtime: Implement autosuspend support
PM / Runtime: Add no_callbacks flag
PM / Runtime: Combine runtime PM entry points
PM / Runtime: Merge synchronous and async runtime routines
PM / Runtime: Replace boolean arguments with bitflags
PM / Runtime: Move code in drivers/base/power/runtime.c
sysfs: Add sysfs_merge_group() and sysfs_unmerge_group()
PM: Fix potential issue with failing asynchronous suspend
PM / Wakeup: Introduce wakeup source objects and event statistics (v3)
PM: Fix signed/unsigned warning in dpm_show_time()
...
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/opp.h | 105 | ||||
| -rw-r--r-- | include/linux/pm.h | 38 | ||||
| -rw-r--r-- | include/linux/pm_runtime.h | 121 | ||||
| -rw-r--r-- | include/linux/pm_wakeup.h | 127 | ||||
| -rw-r--r-- | include/linux/resume-trace.h | 2 | ||||
| -rw-r--r-- | include/linux/suspend.h | 6 | ||||
| -rw-r--r-- | include/linux/sysfs.h | 15 |
7 files changed, 356 insertions, 58 deletions
diff --git a/include/linux/opp.h b/include/linux/opp.h new file mode 100644 index 000000000000..5449945d589f --- /dev/null +++ b/include/linux/opp.h | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | /* | ||
| 2 | * Generic OPP Interface | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009-2010 Texas Instruments Incorporated. | ||
| 5 | * Nishanth Menon | ||
| 6 | * Romit Dasgupta | ||
| 7 | * Kevin Hilman | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef __LINUX_OPP_H__ | ||
| 15 | #define __LINUX_OPP_H__ | ||
| 16 | |||
| 17 | #include <linux/err.h> | ||
| 18 | #include <linux/cpufreq.h> | ||
| 19 | |||
| 20 | struct opp; | ||
| 21 | |||
| 22 | #if defined(CONFIG_PM_OPP) | ||
| 23 | |||
| 24 | unsigned long opp_get_voltage(struct opp *opp); | ||
| 25 | |||
| 26 | unsigned long opp_get_freq(struct opp *opp); | ||
| 27 | |||
| 28 | int opp_get_opp_count(struct device *dev); | ||
| 29 | |||
| 30 | struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq, | ||
| 31 | bool available); | ||
| 32 | |||
| 33 | struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq); | ||
| 34 | |||
| 35 | struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq); | ||
| 36 | |||
| 37 | int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt); | ||
| 38 | |||
| 39 | int opp_enable(struct device *dev, unsigned long freq); | ||
| 40 | |||
| 41 | int opp_disable(struct device *dev, unsigned long freq); | ||
| 42 | |||
| 43 | #else | ||
| 44 | static inline unsigned long opp_get_voltage(struct opp *opp) | ||
| 45 | { | ||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | static inline unsigned long opp_get_freq(struct opp *opp) | ||
| 50 | { | ||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | static inline int opp_get_opp_count(struct device *dev) | ||
| 55 | { | ||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | |||
| 59 | static inline struct opp *opp_find_freq_exact(struct device *dev, | ||
| 60 | unsigned long freq, bool available) | ||
| 61 | { | ||
| 62 | return ERR_PTR(-EINVAL); | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline struct opp *opp_find_freq_floor(struct device *dev, | ||
| 66 | unsigned long *freq) | ||
| 67 | { | ||
| 68 | return ERR_PTR(-EINVAL); | ||
| 69 | } | ||
| 70 | |||
| 71 | static inline struct opp *opp_find_freq_ceil(struct device *dev, | ||
| 72 | unsigned long *freq) | ||
| 73 | { | ||
| 74 | return ERR_PTR(-EINVAL); | ||
| 75 | } | ||
| 76 | |||
| 77 | static inline int opp_add(struct device *dev, unsigned long freq, | ||
| 78 | unsigned long u_volt) | ||
| 79 | { | ||
| 80 | return -EINVAL; | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline int opp_enable(struct device *dev, unsigned long freq) | ||
| 84 | { | ||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline int opp_disable(struct device *dev, unsigned long freq) | ||
| 89 | { | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | #endif /* CONFIG_PM */ | ||
| 93 | |||
| 94 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP) | ||
| 95 | int opp_init_cpufreq_table(struct device *dev, | ||
| 96 | struct cpufreq_frequency_table **table); | ||
| 97 | #else | ||
| 98 | static inline int opp_init_cpufreq_table(struct device *dev, | ||
| 99 | struct cpufreq_frequency_table **table) | ||
| 100 | { | ||
| 101 | return -EINVAL; | ||
| 102 | } | ||
| 103 | #endif /* CONFIG_CPU_FREQ */ | ||
| 104 | |||
| 105 | #endif /* __LINUX_OPP_H__ */ | ||
diff --git a/include/linux/pm.h b/include/linux/pm.h index 52e8c55ff314..40f3f45702ba 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
| @@ -41,6 +41,12 @@ extern void (*pm_power_off_prepare)(void); | |||
| 41 | 41 | ||
| 42 | struct device; | 42 | struct device; |
| 43 | 43 | ||
| 44 | #ifdef CONFIG_PM | ||
| 45 | extern const char power_group_name[]; /* = "power" */ | ||
| 46 | #else | ||
| 47 | #define power_group_name NULL | ||
| 48 | #endif | ||
| 49 | |||
| 44 | typedef struct pm_message { | 50 | typedef struct pm_message { |
| 45 | int event; | 51 | int event; |
| 46 | } pm_message_t; | 52 | } pm_message_t; |
| @@ -438,6 +444,9 @@ enum rpm_status { | |||
| 438 | * | 444 | * |
| 439 | * 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 |
| 440 | * | 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 | * | ||
| 441 | * 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 |
| 442 | */ | 451 | */ |
| 443 | 452 | ||
| @@ -445,26 +454,28 @@ enum rpm_request { | |||
| 445 | RPM_REQ_NONE = 0, | 454 | RPM_REQ_NONE = 0, |
| 446 | RPM_REQ_IDLE, | 455 | RPM_REQ_IDLE, |
| 447 | RPM_REQ_SUSPEND, | 456 | RPM_REQ_SUSPEND, |
| 457 | RPM_REQ_AUTOSUSPEND, | ||
| 448 | RPM_REQ_RESUME, | 458 | RPM_REQ_RESUME, |
| 449 | }; | 459 | }; |
| 450 | 460 | ||
| 461 | struct wakeup_source; | ||
| 462 | |||
| 451 | struct dev_pm_info { | 463 | struct dev_pm_info { |
| 452 | pm_message_t power_state; | 464 | pm_message_t power_state; |
| 453 | unsigned int can_wakeup:1; | 465 | unsigned int can_wakeup:1; |
| 454 | unsigned int should_wakeup:1; | ||
| 455 | unsigned async_suspend:1; | 466 | unsigned async_suspend:1; |
| 456 | enum dpm_state status; /* Owned by the PM core */ | 467 | enum dpm_state status; /* Owned by the PM core */ |
| 468 | spinlock_t lock; | ||
| 457 | #ifdef CONFIG_PM_SLEEP | 469 | #ifdef CONFIG_PM_SLEEP |
| 458 | struct list_head entry; | 470 | struct list_head entry; |
| 459 | struct completion completion; | 471 | struct completion completion; |
| 460 | unsigned long wakeup_count; | 472 | struct wakeup_source *wakeup; |
| 461 | #endif | 473 | #endif |
| 462 | #ifdef CONFIG_PM_RUNTIME | 474 | #ifdef CONFIG_PM_RUNTIME |
| 463 | struct timer_list suspend_timer; | 475 | struct timer_list suspend_timer; |
| 464 | unsigned long timer_expires; | 476 | unsigned long timer_expires; |
| 465 | struct work_struct work; | 477 | struct work_struct work; |
| 466 | wait_queue_head_t wait_queue; | 478 | wait_queue_head_t wait_queue; |
| 467 | spinlock_t lock; | ||
| 468 | atomic_t usage_count; | 479 | atomic_t usage_count; |
| 469 | atomic_t child_count; | 480 | atomic_t child_count; |
| 470 | unsigned int disable_depth:3; | 481 | unsigned int disable_depth:3; |
| @@ -474,9 +485,14 @@ struct dev_pm_info { | |||
| 474 | unsigned int deferred_resume:1; | 485 | unsigned int deferred_resume:1; |
| 475 | unsigned int run_wake:1; | 486 | unsigned int run_wake:1; |
| 476 | unsigned int runtime_auto:1; | 487 | unsigned int runtime_auto:1; |
| 488 | unsigned int no_callbacks:1; | ||
| 489 | unsigned int use_autosuspend:1; | ||
| 490 | unsigned int timer_autosuspends:1; | ||
| 477 | enum rpm_request request; | 491 | enum rpm_request request; |
| 478 | enum rpm_status runtime_status; | 492 | enum rpm_status runtime_status; |
| 479 | int runtime_error; | 493 | int runtime_error; |
| 494 | int autosuspend_delay; | ||
| 495 | unsigned long last_busy; | ||
| 480 | unsigned long active_jiffies; | 496 | unsigned long active_jiffies; |
| 481 | unsigned long suspended_jiffies; | 497 | unsigned long suspended_jiffies; |
| 482 | unsigned long accounting_timestamp; | 498 | unsigned long accounting_timestamp; |
| @@ -558,12 +574,7 @@ extern void __suspend_report_result(const char *function, void *fn, int ret); | |||
| 558 | __suspend_report_result(__func__, fn, ret); \ | 574 | __suspend_report_result(__func__, fn, ret); \ |
| 559 | } while (0) | 575 | } while (0) |
| 560 | 576 | ||
| 561 | extern void device_pm_wait_for_dev(struct device *sub, struct device *dev); | 577 | extern int device_pm_wait_for_dev(struct device *sub, struct device *dev); |
| 562 | |||
| 563 | /* drivers/base/power/wakeup.c */ | ||
| 564 | extern void pm_wakeup_event(struct device *dev, unsigned int msec); | ||
| 565 | extern void pm_stay_awake(struct device *dev); | ||
| 566 | extern void pm_relax(void); | ||
| 567 | #else /* !CONFIG_PM_SLEEP */ | 578 | #else /* !CONFIG_PM_SLEEP */ |
| 568 | 579 | ||
| 569 | #define device_pm_lock() do {} while (0) | 580 | #define device_pm_lock() do {} while (0) |
| @@ -576,11 +587,10 @@ static inline int dpm_suspend_start(pm_message_t state) | |||
| 576 | 587 | ||
| 577 | #define suspend_report_result(fn, ret) do {} while (0) | 588 | #define suspend_report_result(fn, ret) do {} while (0) |
| 578 | 589 | ||
| 579 | static inline void device_pm_wait_for_dev(struct device *a, struct device *b) {} | 590 | static inline int device_pm_wait_for_dev(struct device *a, struct device *b) |
| 580 | 591 | { | |
| 581 | static inline void pm_wakeup_event(struct device *dev, unsigned int msec) {} | 592 | return 0; |
| 582 | static inline void pm_stay_awake(struct device *dev) {} | 593 | } |
| 583 | static inline void pm_relax(void) {} | ||
| 584 | #endif /* !CONFIG_PM_SLEEP */ | 594 | #endif /* !CONFIG_PM_SLEEP */ |
| 585 | 595 | ||
| 586 | /* How to reorder dpm_list after device_move() */ | 596 | /* How to reorder dpm_list after device_move() */ |
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 6e81888c6222..3ec2358f8692 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h | |||
| @@ -12,18 +12,24 @@ | |||
| 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 | |||
| 17 | /* Runtime PM flag argument bits */ | ||
| 18 | #define RPM_ASYNC 0x01 /* Request is asynchronous */ | ||
| 19 | #define RPM_NOWAIT 0x02 /* Don't wait for concurrent | ||
| 20 | state change */ | ||
| 21 | #define RPM_GET_PUT 0x04 /* Increment/decrement the | ||
| 22 | usage_count */ | ||
| 23 | #define RPM_AUTO 0x08 /* Use autosuspend_delay */ | ||
| 24 | |||
| 15 | #ifdef CONFIG_PM_RUNTIME | 25 | #ifdef CONFIG_PM_RUNTIME |
| 16 | 26 | ||
| 17 | extern struct workqueue_struct *pm_wq; | 27 | extern struct workqueue_struct *pm_wq; |
| 18 | 28 | ||
| 19 | extern int pm_runtime_idle(struct device *dev); | 29 | extern int __pm_runtime_idle(struct device *dev, int rpmflags); |
| 20 | extern int pm_runtime_suspend(struct device *dev); | 30 | extern int __pm_runtime_suspend(struct device *dev, int rpmflags); |
| 21 | extern int pm_runtime_resume(struct device *dev); | 31 | extern int __pm_runtime_resume(struct device *dev, int rpmflags); |
| 22 | extern int pm_request_idle(struct device *dev); | ||
| 23 | extern int pm_schedule_suspend(struct device *dev, unsigned int delay); | 32 | extern int pm_schedule_suspend(struct device *dev, unsigned int delay); |
| 24 | extern int pm_request_resume(struct device *dev); | ||
| 25 | extern int __pm_runtime_get(struct device *dev, bool sync); | ||
| 26 | extern int __pm_runtime_put(struct device *dev, bool sync); | ||
| 27 | extern int __pm_runtime_set_status(struct device *dev, unsigned int status); | 33 | extern int __pm_runtime_set_status(struct device *dev, unsigned int status); |
| 28 | extern int pm_runtime_barrier(struct device *dev); | 34 | extern int pm_runtime_barrier(struct device *dev); |
| 29 | extern void pm_runtime_enable(struct device *dev); | 35 | extern void pm_runtime_enable(struct device *dev); |
| @@ -33,6 +39,10 @@ extern void pm_runtime_forbid(struct device *dev); | |||
| 33 | extern int pm_generic_runtime_idle(struct device *dev); | 39 | extern int pm_generic_runtime_idle(struct device *dev); |
| 34 | extern int pm_generic_runtime_suspend(struct device *dev); | 40 | extern int pm_generic_runtime_suspend(struct device *dev); |
| 35 | extern int pm_generic_runtime_resume(struct device *dev); | 41 | extern int pm_generic_runtime_resume(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); | ||
| 36 | 46 | ||
| 37 | static inline bool pm_children_suspended(struct device *dev) | 47 | static inline bool pm_children_suspended(struct device *dev) |
| 38 | { | 48 | { |
| @@ -70,19 +80,29 @@ static inline bool pm_runtime_suspended(struct device *dev) | |||
| 70 | return dev->power.runtime_status == RPM_SUSPENDED; | 80 | return dev->power.runtime_status == RPM_SUSPENDED; |
| 71 | } | 81 | } |
| 72 | 82 | ||
| 83 | static inline void pm_runtime_mark_last_busy(struct device *dev) | ||
| 84 | { | ||
| 85 | ACCESS_ONCE(dev->power.last_busy) = jiffies; | ||
| 86 | } | ||
| 87 | |||
| 73 | #else /* !CONFIG_PM_RUNTIME */ | 88 | #else /* !CONFIG_PM_RUNTIME */ |
| 74 | 89 | ||
| 75 | static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; } | 90 | static inline int __pm_runtime_idle(struct device *dev, int rpmflags) |
| 76 | static inline int pm_runtime_suspend(struct device *dev) { return -ENOSYS; } | 91 | { |
| 77 | static inline int pm_runtime_resume(struct device *dev) { return 0; } | 92 | return -ENOSYS; |
| 78 | static inline int pm_request_idle(struct device *dev) { return -ENOSYS; } | 93 | } |
| 94 | static inline int __pm_runtime_suspend(struct device *dev, int rpmflags) | ||
| 95 | { | ||
| 96 | return -ENOSYS; | ||
| 97 | } | ||
| 98 | static inline int __pm_runtime_resume(struct device *dev, int rpmflags) | ||
| 99 | { | ||
| 100 | return 1; | ||
| 101 | } | ||
| 79 | static inline int pm_schedule_suspend(struct device *dev, unsigned int delay) | 102 | static inline int pm_schedule_suspend(struct device *dev, unsigned int delay) |
| 80 | { | 103 | { |
| 81 | return -ENOSYS; | 104 | return -ENOSYS; |
| 82 | } | 105 | } |
| 83 | static inline int pm_request_resume(struct device *dev) { return 0; } | ||
| 84 | static inline int __pm_runtime_get(struct device *dev, bool sync) { return 1; } | ||
| 85 | static inline int __pm_runtime_put(struct device *dev, bool sync) { return 0; } | ||
| 86 | static inline int __pm_runtime_set_status(struct device *dev, | 106 | static inline int __pm_runtime_set_status(struct device *dev, |
| 87 | unsigned int status) { return 0; } | 107 | unsigned int status) { return 0; } |
| 88 | static inline int pm_runtime_barrier(struct device *dev) { return 0; } | 108 | static inline int pm_runtime_barrier(struct device *dev) { return 0; } |
| @@ -102,27 +122,82 @@ static inline bool pm_runtime_suspended(struct device *dev) { return false; } | |||
| 102 | static inline int pm_generic_runtime_idle(struct device *dev) { return 0; } | 122 | static inline int pm_generic_runtime_idle(struct device *dev) { return 0; } |
| 103 | static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } | 123 | static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } |
| 104 | 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; } |
| 125 | static inline void pm_runtime_no_callbacks(struct device *dev) {} | ||
| 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; } | ||
| 105 | 134 | ||
| 106 | #endif /* !CONFIG_PM_RUNTIME */ | 135 | #endif /* !CONFIG_PM_RUNTIME */ |
| 107 | 136 | ||
| 137 | static inline int pm_runtime_idle(struct device *dev) | ||
| 138 | { | ||
| 139 | return __pm_runtime_idle(dev, 0); | ||
| 140 | } | ||
| 141 | |||
| 142 | static inline int pm_runtime_suspend(struct device *dev) | ||
| 143 | { | ||
| 144 | return __pm_runtime_suspend(dev, 0); | ||
| 145 | } | ||
| 146 | |||
| 147 | static inline int pm_runtime_autosuspend(struct device *dev) | ||
| 148 | { | ||
| 149 | return __pm_runtime_suspend(dev, RPM_AUTO); | ||
| 150 | } | ||
| 151 | |||
| 152 | static inline int pm_runtime_resume(struct device *dev) | ||
| 153 | { | ||
| 154 | return __pm_runtime_resume(dev, 0); | ||
| 155 | } | ||
| 156 | |||
| 157 | static inline int pm_request_idle(struct device *dev) | ||
| 158 | { | ||
| 159 | return __pm_runtime_idle(dev, RPM_ASYNC); | ||
| 160 | } | ||
| 161 | |||
| 162 | static inline int pm_request_resume(struct device *dev) | ||
| 163 | { | ||
| 164 | return __pm_runtime_resume(dev, RPM_ASYNC); | ||
| 165 | } | ||
| 166 | |||
| 167 | static inline int pm_request_autosuspend(struct device *dev) | ||
| 168 | { | ||
| 169 | return __pm_runtime_suspend(dev, RPM_ASYNC | RPM_AUTO); | ||
| 170 | } | ||
| 171 | |||
| 108 | static inline int pm_runtime_get(struct device *dev) | 172 | static inline int pm_runtime_get(struct device *dev) |
| 109 | { | 173 | { |
| 110 | return __pm_runtime_get(dev, false); | 174 | return __pm_runtime_resume(dev, RPM_GET_PUT | RPM_ASYNC); |
| 111 | } | 175 | } |
| 112 | 176 | ||
| 113 | static inline int pm_runtime_get_sync(struct device *dev) | 177 | static inline int pm_runtime_get_sync(struct device *dev) |
| 114 | { | 178 | { |
| 115 | return __pm_runtime_get(dev, true); | 179 | return __pm_runtime_resume(dev, RPM_GET_PUT); |
| 116 | } | 180 | } |
| 117 | 181 | ||
| 118 | static inline int pm_runtime_put(struct device *dev) | 182 | static inline int pm_runtime_put(struct device *dev) |
| 119 | { | 183 | { |
| 120 | return __pm_runtime_put(dev, false); | 184 | return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC); |
| 185 | } | ||
| 186 | |||
| 187 | static inline int pm_runtime_put_autosuspend(struct device *dev) | ||
| 188 | { | ||
| 189 | return __pm_runtime_suspend(dev, | ||
| 190 | RPM_GET_PUT | RPM_ASYNC | RPM_AUTO); | ||
| 121 | } | 191 | } |
| 122 | 192 | ||
| 123 | static inline int pm_runtime_put_sync(struct device *dev) | 193 | static inline int pm_runtime_put_sync(struct device *dev) |
| 124 | { | 194 | { |
| 125 | return __pm_runtime_put(dev, true); | 195 | return __pm_runtime_idle(dev, RPM_GET_PUT); |
| 196 | } | ||
| 197 | |||
| 198 | static inline int pm_runtime_put_sync_autosuspend(struct device *dev) | ||
| 199 | { | ||
| 200 | return __pm_runtime_suspend(dev, RPM_GET_PUT | RPM_AUTO); | ||
| 126 | } | 201 | } |
| 127 | 202 | ||
| 128 | static inline int pm_runtime_set_active(struct device *dev) | 203 | static inline int pm_runtime_set_active(struct device *dev) |
| @@ -140,4 +215,14 @@ static inline void pm_runtime_disable(struct device *dev) | |||
| 140 | __pm_runtime_disable(dev, true); | 215 | __pm_runtime_disable(dev, true); |
| 141 | } | 216 | } |
| 142 | 217 | ||
| 218 | static inline void pm_runtime_use_autosuspend(struct device *dev) | ||
| 219 | { | ||
| 220 | __pm_runtime_use_autosuspend(dev, true); | ||
| 221 | } | ||
| 222 | |||
| 223 | static inline void pm_runtime_dont_use_autosuspend(struct device *dev) | ||
| 224 | { | ||
| 225 | __pm_runtime_use_autosuspend(dev, false); | ||
| 226 | } | ||
| 227 | |||
| 143 | #endif | 228 | #endif |
diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 76aca48722ae..9cff00dd6b63 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * pm_wakeup.h - Power management wakeup interface | 2 | * pm_wakeup.h - Power management wakeup interface |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2008 Alan Stern | 4 | * Copyright (C) 2008 Alan Stern |
| 5 | * Copyright (C) 2010 Rafael J. Wysocki, Novell Inc. | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -27,19 +28,77 @@ | |||
| 27 | 28 | ||
| 28 | #include <linux/types.h> | 29 | #include <linux/types.h> |
| 29 | 30 | ||
| 30 | #ifdef CONFIG_PM | 31 | /** |
| 31 | 32 | * struct wakeup_source - Representation of wakeup sources | |
| 32 | /* Changes to device_may_wakeup take effect on the next pm state change. | ||
| 33 | * | 33 | * |
| 34 | * By default, most devices should leave wakeup disabled. The exceptions | 34 | * @total_time: Total time this wakeup source has been active. |
| 35 | * are devices that everyone expects to be wakeup sources: keyboards, | 35 | * @max_time: Maximum time this wakeup source has been continuously active. |
| 36 | * power buttons, possibly network interfaces, etc. | 36 | * @last_time: Monotonic clock when the wakeup source's was activated last time. |
| 37 | * @event_count: Number of signaled wakeup events. | ||
| 38 | * @active_count: Number of times the wakeup sorce was activated. | ||
| 39 | * @relax_count: Number of times the wakeup sorce was deactivated. | ||
| 40 | * @hit_count: Number of times the wakeup sorce might abort system suspend. | ||
| 41 | * @active: Status of the wakeup source. | ||
| 37 | */ | 42 | */ |
| 38 | static inline void device_init_wakeup(struct device *dev, bool val) | 43 | struct wakeup_source { |
| 44 | char *name; | ||
| 45 | struct list_head entry; | ||
| 46 | spinlock_t lock; | ||
| 47 | struct timer_list timer; | ||
| 48 | unsigned long timer_expires; | ||
| 49 | ktime_t total_time; | ||
| 50 | ktime_t max_time; | ||
| 51 | ktime_t last_time; | ||
| 52 | unsigned long event_count; | ||
| 53 | unsigned long active_count; | ||
| 54 | unsigned long relax_count; | ||
| 55 | unsigned long hit_count; | ||
| 56 | unsigned int active:1; | ||
| 57 | }; | ||
| 58 | |||
| 59 | #ifdef CONFIG_PM_SLEEP | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Changes to device_may_wakeup take effect on the next pm state change. | ||
| 63 | */ | ||
| 64 | |||
| 65 | static inline void device_set_wakeup_capable(struct device *dev, bool capable) | ||
| 66 | { | ||
| 67 | dev->power.can_wakeup = capable; | ||
| 68 | } | ||
| 69 | |||
| 70 | static inline bool device_can_wakeup(struct device *dev) | ||
| 71 | { | ||
| 72 | return dev->power.can_wakeup; | ||
| 73 | } | ||
| 74 | |||
| 75 | |||
| 76 | |||
| 77 | static inline bool device_may_wakeup(struct device *dev) | ||
| 39 | { | 78 | { |
| 40 | dev->power.can_wakeup = dev->power.should_wakeup = val; | 79 | return dev->power.can_wakeup && !!dev->power.wakeup; |
| 41 | } | 80 | } |
| 42 | 81 | ||
| 82 | /* drivers/base/power/wakeup.c */ | ||
| 83 | extern struct wakeup_source *wakeup_source_create(const char *name); | ||
| 84 | extern void wakeup_source_destroy(struct wakeup_source *ws); | ||
| 85 | extern void wakeup_source_add(struct wakeup_source *ws); | ||
| 86 | extern void wakeup_source_remove(struct wakeup_source *ws); | ||
| 87 | extern struct wakeup_source *wakeup_source_register(const char *name); | ||
| 88 | extern void wakeup_source_unregister(struct wakeup_source *ws); | ||
| 89 | extern int device_wakeup_enable(struct device *dev); | ||
| 90 | extern int device_wakeup_disable(struct device *dev); | ||
| 91 | extern int device_init_wakeup(struct device *dev, bool val); | ||
| 92 | extern int device_set_wakeup_enable(struct device *dev, bool enable); | ||
| 93 | extern void __pm_stay_awake(struct wakeup_source *ws); | ||
| 94 | extern void pm_stay_awake(struct device *dev); | ||
| 95 | extern void __pm_relax(struct wakeup_source *ws); | ||
| 96 | extern void pm_relax(struct device *dev); | ||
| 97 | extern void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec); | ||
| 98 | extern void pm_wakeup_event(struct device *dev, unsigned int msec); | ||
| 99 | |||
| 100 | #else /* !CONFIG_PM_SLEEP */ | ||
| 101 | |||
| 43 | static inline void device_set_wakeup_capable(struct device *dev, bool capable) | 102 | static inline void device_set_wakeup_capable(struct device *dev, bool capable) |
| 44 | { | 103 | { |
| 45 | dev->power.can_wakeup = capable; | 104 | dev->power.can_wakeup = capable; |
| @@ -50,43 +109,63 @@ static inline bool device_can_wakeup(struct device *dev) | |||
| 50 | return dev->power.can_wakeup; | 109 | return dev->power.can_wakeup; |
| 51 | } | 110 | } |
| 52 | 111 | ||
| 53 | static inline void device_set_wakeup_enable(struct device *dev, bool enable) | 112 | static inline bool device_may_wakeup(struct device *dev) |
| 54 | { | 113 | { |
| 55 | dev->power.should_wakeup = enable; | 114 | return false; |
| 56 | } | 115 | } |
| 57 | 116 | ||
| 58 | static inline bool device_may_wakeup(struct device *dev) | 117 | static inline struct wakeup_source *wakeup_source_create(const char *name) |
| 59 | { | 118 | { |
| 60 | return dev->power.can_wakeup && dev->power.should_wakeup; | 119 | return NULL; |
| 61 | } | 120 | } |
| 62 | 121 | ||
| 63 | #else /* !CONFIG_PM */ | 122 | static inline void wakeup_source_destroy(struct wakeup_source *ws) {} |
| 123 | |||
| 124 | static inline void wakeup_source_add(struct wakeup_source *ws) {} | ||
| 64 | 125 | ||
| 65 | /* For some reason the following routines work even without CONFIG_PM */ | 126 | static inline void wakeup_source_remove(struct wakeup_source *ws) {} |
| 66 | static inline void device_init_wakeup(struct device *dev, bool val) | 127 | |
| 128 | static inline struct wakeup_source *wakeup_source_register(const char *name) | ||
| 67 | { | 129 | { |
| 68 | dev->power.can_wakeup = val; | 130 | return NULL; |
| 69 | } | 131 | } |
| 70 | 132 | ||
| 71 | static inline void device_set_wakeup_capable(struct device *dev, bool capable) | 133 | static inline void wakeup_source_unregister(struct wakeup_source *ws) {} |
| 134 | |||
| 135 | static inline int device_wakeup_enable(struct device *dev) | ||
| 72 | { | 136 | { |
| 73 | dev->power.can_wakeup = capable; | 137 | return -EINVAL; |
| 74 | } | 138 | } |
| 75 | 139 | ||
| 76 | static inline bool device_can_wakeup(struct device *dev) | 140 | static inline int device_wakeup_disable(struct device *dev) |
| 77 | { | 141 | { |
| 78 | return dev->power.can_wakeup; | 142 | return 0; |
| 79 | } | 143 | } |
| 80 | 144 | ||
| 81 | static inline void device_set_wakeup_enable(struct device *dev, bool enable) | 145 | static inline int device_init_wakeup(struct device *dev, bool val) |
| 82 | { | 146 | { |
| 147 | dev->power.can_wakeup = val; | ||
| 148 | return val ? -EINVAL : 0; | ||
| 83 | } | 149 | } |
| 84 | 150 | ||
| 85 | static inline bool device_may_wakeup(struct device *dev) | 151 | |
| 152 | static inline int device_set_wakeup_enable(struct device *dev, bool enable) | ||
| 86 | { | 153 | { |
| 87 | return false; | 154 | return -EINVAL; |
| 88 | } | 155 | } |
| 89 | 156 | ||
| 90 | #endif /* !CONFIG_PM */ | 157 | static inline void __pm_stay_awake(struct wakeup_source *ws) {} |
| 158 | |||
| 159 | static inline void pm_stay_awake(struct device *dev) {} | ||
| 160 | |||
| 161 | static inline void __pm_relax(struct wakeup_source *ws) {} | ||
| 162 | |||
| 163 | static inline void pm_relax(struct device *dev) {} | ||
| 164 | |||
| 165 | static inline void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec) {} | ||
| 166 | |||
| 167 | static inline void pm_wakeup_event(struct device *dev, unsigned int msec) {} | ||
| 168 | |||
| 169 | #endif /* !CONFIG_PM_SLEEP */ | ||
| 91 | 170 | ||
| 92 | #endif /* _LINUX_PM_WAKEUP_H */ | 171 | #endif /* _LINUX_PM_WAKEUP_H */ |
diff --git a/include/linux/resume-trace.h b/include/linux/resume-trace.h index bc8c3881c729..f31db2368782 100644 --- a/include/linux/resume-trace.h +++ b/include/linux/resume-trace.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #ifdef CONFIG_PM_TRACE | 4 | #ifdef CONFIG_PM_TRACE |
| 5 | #include <asm/resume-trace.h> | 5 | #include <asm/resume-trace.h> |
| 6 | #include <linux/types.h> | ||
| 6 | 7 | ||
| 7 | extern int pm_trace_enabled; | 8 | extern int pm_trace_enabled; |
| 8 | 9 | ||
| @@ -14,6 +15,7 @@ static inline int pm_trace_is_enabled(void) | |||
| 14 | struct device; | 15 | struct device; |
| 15 | extern void set_trace_device(struct device *); | 16 | extern void set_trace_device(struct device *); |
| 16 | extern void generate_resume_trace(const void *tracedata, unsigned int user); | 17 | extern void generate_resume_trace(const void *tracedata, unsigned int user); |
| 18 | extern int show_trace_dev_match(char *buf, size_t size); | ||
| 17 | 19 | ||
| 18 | #define TRACE_DEVICE(dev) do { \ | 20 | #define TRACE_DEVICE(dev) do { \ |
| 19 | if (pm_trace_enabled) \ | 21 | if (pm_trace_enabled) \ |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 4af270ec2204..26697514c5ec 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
| @@ -293,8 +293,8 @@ extern int unregister_pm_notifier(struct notifier_block *nb); | |||
| 293 | extern bool events_check_enabled; | 293 | extern bool events_check_enabled; |
| 294 | 294 | ||
| 295 | extern bool pm_check_wakeup_events(void); | 295 | extern bool pm_check_wakeup_events(void); |
| 296 | extern bool pm_get_wakeup_count(unsigned long *count); | 296 | extern bool pm_get_wakeup_count(unsigned int *count); |
| 297 | extern bool pm_save_wakeup_count(unsigned long count); | 297 | extern bool pm_save_wakeup_count(unsigned int count); |
| 298 | #else /* !CONFIG_PM_SLEEP */ | 298 | #else /* !CONFIG_PM_SLEEP */ |
| 299 | 299 | ||
| 300 | static inline int register_pm_notifier(struct notifier_block *nb) | 300 | static inline int register_pm_notifier(struct notifier_block *nb) |
| @@ -308,6 +308,8 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) | |||
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | #define pm_notifier(fn, pri) do { (void)(fn); } while (0) | 310 | #define pm_notifier(fn, pri) do { (void)(fn); } while (0) |
| 311 | |||
| 312 | static inline bool pm_check_wakeup_events(void) { return true; } | ||
| 311 | #endif /* !CONFIG_PM_SLEEP */ | 313 | #endif /* !CONFIG_PM_SLEEP */ |
| 312 | 314 | ||
| 313 | extern struct mutex pm_mutex; | 315 | extern struct mutex pm_mutex; |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 96eb576d82fd..30b881555fa5 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
| @@ -164,6 +164,10 @@ int sysfs_add_file_to_group(struct kobject *kobj, | |||
| 164 | const struct attribute *attr, const char *group); | 164 | const struct attribute *attr, const char *group); |
| 165 | void sysfs_remove_file_from_group(struct kobject *kobj, | 165 | void sysfs_remove_file_from_group(struct kobject *kobj, |
| 166 | const struct attribute *attr, const char *group); | 166 | const struct attribute *attr, const char *group); |
| 167 | int sysfs_merge_group(struct kobject *kobj, | ||
| 168 | const struct attribute_group *grp); | ||
| 169 | void sysfs_unmerge_group(struct kobject *kobj, | ||
| 170 | const struct attribute_group *grp); | ||
| 167 | 171 | ||
| 168 | void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr); | 172 | void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr); |
| 169 | void sysfs_notify_dirent(struct sysfs_dirent *sd); | 173 | void sysfs_notify_dirent(struct sysfs_dirent *sd); |
| @@ -302,6 +306,17 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj, | |||
| 302 | { | 306 | { |
| 303 | } | 307 | } |
| 304 | 308 | ||
| 309 | static inline int sysfs_merge_group(struct kobject *kobj, | ||
| 310 | const struct attribute_group *grp) | ||
| 311 | { | ||
| 312 | return 0; | ||
| 313 | } | ||
| 314 | |||
| 315 | static inline void sysfs_unmerge_group(struct kobject *kobj, | ||
| 316 | const struct attribute_group *grp) | ||
| 317 | { | ||
| 318 | } | ||
| 319 | |||
| 305 | static inline void sysfs_notify(struct kobject *kobj, const char *dir, | 320 | static inline void sysfs_notify(struct kobject *kobj, const char *dir, |
| 306 | const char *attr) | 321 | const char *attr) |
| 307 | { | 322 | { |
