diff options
Diffstat (limited to 'kernel/power/suspend.c')
| -rw-r--r-- | kernel/power/suspend.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 1c41ba215419..b6b71ad2208f 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c | |||
| @@ -44,6 +44,7 @@ void suspend_set_ops(const struct platform_suspend_ops *ops) | |||
| 44 | suspend_ops = ops; | 44 | suspend_ops = ops; |
| 45 | mutex_unlock(&pm_mutex); | 45 | mutex_unlock(&pm_mutex); |
| 46 | } | 46 | } |
| 47 | EXPORT_SYMBOL_GPL(suspend_set_ops); | ||
| 47 | 48 | ||
| 48 | bool valid_state(suspend_state_t state) | 49 | bool valid_state(suspend_state_t state) |
| 49 | { | 50 | { |
| @@ -65,6 +66,7 @@ int suspend_valid_only_mem(suspend_state_t state) | |||
| 65 | { | 66 | { |
| 66 | return state == PM_SUSPEND_MEM; | 67 | return state == PM_SUSPEND_MEM; |
| 67 | } | 68 | } |
| 69 | EXPORT_SYMBOL_GPL(suspend_valid_only_mem); | ||
| 68 | 70 | ||
| 69 | static int suspend_test(int level) | 71 | static int suspend_test(int level) |
| 70 | { | 72 | { |
| @@ -126,12 +128,13 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void) | |||
| 126 | } | 128 | } |
| 127 | 129 | ||
| 128 | /** | 130 | /** |
| 129 | * suspend_enter - enter the desired system sleep state. | 131 | * suspend_enter - enter the desired system sleep state. |
| 130 | * @state: state to enter | 132 | * @state: State to enter |
| 133 | * @wakeup: Returns information that suspend should not be entered again. | ||
| 131 | * | 134 | * |
| 132 | * This function should be called after devices have been suspended. | 135 | * This function should be called after devices have been suspended. |
| 133 | */ | 136 | */ |
| 134 | static int suspend_enter(suspend_state_t state) | 137 | static int suspend_enter(suspend_state_t state, bool *wakeup) |
| 135 | { | 138 | { |
| 136 | int error; | 139 | int error; |
| 137 | 140 | ||
| @@ -165,7 +168,8 @@ static int suspend_enter(suspend_state_t state) | |||
| 165 | 168 | ||
| 166 | error = syscore_suspend(); | 169 | error = syscore_suspend(); |
| 167 | if (!error) { | 170 | if (!error) { |
| 168 | if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) { | 171 | *wakeup = pm_wakeup_pending(); |
| 172 | if (!(suspend_test(TEST_CORE) || *wakeup)) { | ||
| 169 | error = suspend_ops->enter(state); | 173 | error = suspend_ops->enter(state); |
| 170 | events_check_enabled = false; | 174 | events_check_enabled = false; |
| 171 | } | 175 | } |
| @@ -199,6 +203,7 @@ static int suspend_enter(suspend_state_t state) | |||
| 199 | int suspend_devices_and_enter(suspend_state_t state) | 203 | int suspend_devices_and_enter(suspend_state_t state) |
| 200 | { | 204 | { |
| 201 | int error; | 205 | int error; |
| 206 | bool wakeup = false; | ||
| 202 | 207 | ||
| 203 | if (!suspend_ops) | 208 | if (!suspend_ops) |
| 204 | return -ENOSYS; | 209 | return -ENOSYS; |
| @@ -220,7 +225,10 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
| 220 | if (suspend_test(TEST_DEVICES)) | 225 | if (suspend_test(TEST_DEVICES)) |
| 221 | goto Recover_platform; | 226 | goto Recover_platform; |
| 222 | 227 | ||
| 223 | error = suspend_enter(state); | 228 | do { |
| 229 | error = suspend_enter(state, &wakeup); | ||
| 230 | } while (!error && !wakeup | ||
| 231 | && suspend_ops->suspend_again && suspend_ops->suspend_again()); | ||
| 224 | 232 | ||
| 225 | Resume_devices: | 233 | Resume_devices: |
| 226 | suspend_test_start(); | 234 | suspend_test_start(); |
