diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/power/process.c | 2 | ||||
-rw-r--r-- | kernel/power/suspend.c | 35 |
2 files changed, 30 insertions, 7 deletions
diff --git a/kernel/power/process.c b/kernel/power/process.c index c7209f060eeb..78672d324a6e 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -132,7 +132,7 @@ int freeze_processes(void) | |||
132 | if (!pm_freezing) | 132 | if (!pm_freezing) |
133 | atomic_inc(&system_freezing_cnt); | 133 | atomic_inc(&system_freezing_cnt); |
134 | 134 | ||
135 | pm_wakeup_clear(); | 135 | pm_wakeup_clear(true); |
136 | pr_info("Freezing user space processes ... "); | 136 | pr_info("Freezing user space processes ... "); |
137 | pm_freezing = true; | 137 | pm_freezing = true; |
138 | error = try_to_freeze_tasks(true); | 138 | error = try_to_freeze_tasks(true); |
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 15e6baef5c73..3ecf275d7e44 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c | |||
@@ -72,6 +72,8 @@ static void freeze_begin(void) | |||
72 | 72 | ||
73 | static void freeze_enter(void) | 73 | static void freeze_enter(void) |
74 | { | 74 | { |
75 | trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, true); | ||
76 | |||
75 | spin_lock_irq(&suspend_freeze_lock); | 77 | spin_lock_irq(&suspend_freeze_lock); |
76 | if (pm_wakeup_pending()) | 78 | if (pm_wakeup_pending()) |
77 | goto out; | 79 | goto out; |
@@ -84,11 +86,9 @@ static void freeze_enter(void) | |||
84 | 86 | ||
85 | /* Push all the CPUs into the idle loop. */ | 87 | /* Push all the CPUs into the idle loop. */ |
86 | wake_up_all_idle_cpus(); | 88 | wake_up_all_idle_cpus(); |
87 | pr_debug("PM: suspend-to-idle\n"); | ||
88 | /* Make the current CPU wait so it can enter the idle loop too. */ | 89 | /* Make the current CPU wait so it can enter the idle loop too. */ |
89 | wait_event(suspend_freeze_wait_head, | 90 | wait_event(suspend_freeze_wait_head, |
90 | suspend_freeze_state == FREEZE_STATE_WAKE); | 91 | suspend_freeze_state == FREEZE_STATE_WAKE); |
91 | pr_debug("PM: resume from suspend-to-idle\n"); | ||
92 | 92 | ||
93 | cpuidle_pause(); | 93 | cpuidle_pause(); |
94 | put_online_cpus(); | 94 | put_online_cpus(); |
@@ -98,6 +98,31 @@ static void freeze_enter(void) | |||
98 | out: | 98 | out: |
99 | suspend_freeze_state = FREEZE_STATE_NONE; | 99 | suspend_freeze_state = FREEZE_STATE_NONE; |
100 | spin_unlock_irq(&suspend_freeze_lock); | 100 | spin_unlock_irq(&suspend_freeze_lock); |
101 | |||
102 | trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, false); | ||
103 | } | ||
104 | |||
105 | static void s2idle_loop(void) | ||
106 | { | ||
107 | pr_debug("PM: suspend-to-idle\n"); | ||
108 | |||
109 | do { | ||
110 | freeze_enter(); | ||
111 | |||
112 | if (freeze_ops && freeze_ops->wake) | ||
113 | freeze_ops->wake(); | ||
114 | |||
115 | dpm_resume_noirq(PMSG_RESUME); | ||
116 | if (freeze_ops && freeze_ops->sync) | ||
117 | freeze_ops->sync(); | ||
118 | |||
119 | if (pm_wakeup_pending()) | ||
120 | break; | ||
121 | |||
122 | pm_wakeup_clear(false); | ||
123 | } while (!dpm_suspend_noirq(PMSG_SUSPEND)); | ||
124 | |||
125 | pr_debug("PM: resume from suspend-to-idle\n"); | ||
101 | } | 126 | } |
102 | 127 | ||
103 | void freeze_wake(void) | 128 | void freeze_wake(void) |
@@ -371,10 +396,8 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) | |||
371 | * all the devices are suspended. | 396 | * all the devices are suspended. |
372 | */ | 397 | */ |
373 | if (state == PM_SUSPEND_FREEZE) { | 398 | if (state == PM_SUSPEND_FREEZE) { |
374 | trace_suspend_resume(TPS("machine_suspend"), state, true); | 399 | s2idle_loop(); |
375 | freeze_enter(); | 400 | goto Platform_early_resume; |
376 | trace_suspend_resume(TPS("machine_suspend"), state, false); | ||
377 | goto Platform_wake; | ||
378 | } | 401 | } |
379 | 402 | ||
380 | error = disable_nonboot_cpus(); | 403 | error = disable_nonboot_cpus(); |