aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-07-22 18:57:53 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-07-22 18:57:53 -0400
commit8490fdf923fc6cf6c31a53b73cafdf582a9642f0 (patch)
tree9451305b272f26b09026417f01dbf62eed886a9f /kernel
parentd431cbc53cb787a7f82d7d2fe0af65156db4d27a (diff)
PM / sleep: Move platform suspend operations to separate functions
After the introduction of freeze_ops it makes more sense to move all of the platform suspend operations to separate functions that each will do all of the necessary checks and choose the right callback to execute istead of doing all that in the core code which makes it generally harder to follow. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/suspend.c120
1 files changed, 77 insertions, 43 deletions
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 83f5b3e70d95..9a071bea80eb 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -36,12 +36,6 @@ const char *pm_states[PM_SUSPEND_MAX];
36 36
37static const struct platform_suspend_ops *suspend_ops; 37static const struct platform_suspend_ops *suspend_ops;
38static const struct platform_freeze_ops *freeze_ops; 38static const struct platform_freeze_ops *freeze_ops;
39
40static bool need_suspend_ops(suspend_state_t state)
41{
42 return state > PM_SUSPEND_FREEZE;
43}
44
45static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head); 39static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head);
46static bool suspend_freeze_wake; 40static bool suspend_freeze_wake;
47 41
@@ -139,6 +133,65 @@ int suspend_valid_only_mem(suspend_state_t state)
139} 133}
140EXPORT_SYMBOL_GPL(suspend_valid_only_mem); 134EXPORT_SYMBOL_GPL(suspend_valid_only_mem);
141 135
136static bool sleep_state_supported(suspend_state_t state)
137{
138 return state == PM_SUSPEND_FREEZE || (suspend_ops && suspend_ops->enter);
139}
140
141static int platform_suspend_prepare(suspend_state_t state)
142{
143 return state != PM_SUSPEND_FREEZE && suspend_ops->prepare ?
144 suspend_ops->prepare() : 0;
145}
146
147static int platform_suspend_prepare_late(suspend_state_t state)
148{
149 return state != PM_SUSPEND_FREEZE && suspend_ops->prepare_late ?
150 suspend_ops->prepare_late() : 0;
151}
152
153static void platform_suspend_wake(suspend_state_t state)
154{
155 if (state != PM_SUSPEND_FREEZE && suspend_ops->wake)
156 suspend_ops->wake();
157}
158
159static void platform_suspend_finish(suspend_state_t state)
160{
161 if (state != PM_SUSPEND_FREEZE && suspend_ops->finish)
162 suspend_ops->finish();
163}
164
165static int platform_suspend_begin(suspend_state_t state)
166{
167 if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->begin)
168 return freeze_ops->begin();
169 else if (suspend_ops->begin)
170 return suspend_ops->begin(state);
171 else
172 return 0;
173}
174
175static void platform_suspend_end(suspend_state_t state)
176{
177 if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->end)
178 freeze_ops->end();
179 else if (suspend_ops->end)
180 suspend_ops->end();
181}
182
183static void platform_suspend_recover(suspend_state_t state)
184{
185 if (state != PM_SUSPEND_FREEZE && suspend_ops->recover)
186 suspend_ops->recover();
187}
188
189static bool platform_suspend_again(suspend_state_t state)
190{
191 return state != PM_SUSPEND_FREEZE && suspend_ops->suspend_again ?
192 suspend_ops->suspend_again() : false;
193}
194
142static int suspend_test(int level) 195static int suspend_test(int level)
143{ 196{
144#ifdef CONFIG_PM_DEBUG 197#ifdef CONFIG_PM_DEBUG
@@ -162,7 +215,7 @@ static int suspend_prepare(suspend_state_t state)
162{ 215{
163 int error; 216 int error;
164 217
165 if (need_suspend_ops(state) && (!suspend_ops || !suspend_ops->enter)) 218 if (!sleep_state_supported(state))
166 return -EPERM; 219 return -EPERM;
167 220
168 pm_prepare_console(); 221 pm_prepare_console();
@@ -208,23 +261,18 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
208{ 261{
209 int error; 262 int error;
210 263
211 if (need_suspend_ops(state) && suspend_ops->prepare) { 264 error = platform_suspend_prepare(state);
212 error = suspend_ops->prepare(); 265 if (error)
213 if (error) 266 goto Platform_finish;
214 goto Platform_finish;
215 }
216 267
217 error = dpm_suspend_end(PMSG_SUSPEND); 268 error = dpm_suspend_end(PMSG_SUSPEND);
218 if (error) { 269 if (error) {
219 printk(KERN_ERR "PM: Some devices failed to power down\n"); 270 printk(KERN_ERR "PM: Some devices failed to power down\n");
220 goto Platform_finish; 271 goto Platform_finish;
221 } 272 }
222 273 error = platform_suspend_prepare_late(state);
223 if (need_suspend_ops(state) && suspend_ops->prepare_late) { 274 if (error)
224 error = suspend_ops->prepare_late(); 275 goto Platform_wake;
225 if (error)
226 goto Platform_wake;
227 }
228 276
229 if (suspend_test(TEST_PLATFORM)) 277 if (suspend_test(TEST_PLATFORM))
230 goto Platform_wake; 278 goto Platform_wake;
@@ -272,15 +320,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
272 ftrace_start(); 320 ftrace_start();
273 321
274 Platform_wake: 322 Platform_wake:
275 if (need_suspend_ops(state) && suspend_ops->wake) 323 platform_suspend_wake(state);
276 suspend_ops->wake();
277
278 dpm_resume_start(PMSG_RESUME); 324 dpm_resume_start(PMSG_RESUME);
279 325
280 Platform_finish: 326 Platform_finish:
281 if (need_suspend_ops(state) && suspend_ops->finish) 327 platform_suspend_finish(state);
282 suspend_ops->finish();
283
284 return error; 328 return error;
285} 329}
286 330
@@ -293,18 +337,13 @@ int suspend_devices_and_enter(suspend_state_t state)
293 int error; 337 int error;
294 bool wakeup = false; 338 bool wakeup = false;
295 339
296 if (need_suspend_ops(state) && !suspend_ops) 340 if (!sleep_state_supported(state))
297 return -ENOSYS; 341 return -ENOSYS;
298 342
299 if (need_suspend_ops(state) && suspend_ops->begin) { 343 error = platform_suspend_begin(state);
300 error = suspend_ops->begin(state); 344 if (error)
301 if (error) 345 goto Close;
302 goto Close; 346
303 } else if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->begin) {
304 error = freeze_ops->begin();
305 if (error)
306 goto Close;
307 }
308 suspend_console(); 347 suspend_console();
309 suspend_test_start(); 348 suspend_test_start();
310 error = dpm_suspend_start(PMSG_SUSPEND); 349 error = dpm_suspend_start(PMSG_SUSPEND);
@@ -318,25 +357,20 @@ int suspend_devices_and_enter(suspend_state_t state)
318 357
319 do { 358 do {
320 error = suspend_enter(state, &wakeup); 359 error = suspend_enter(state, &wakeup);
321 } while (!error && !wakeup && need_suspend_ops(state) 360 } while (!error && !wakeup && platform_suspend_again(state));
322 && suspend_ops->suspend_again && suspend_ops->suspend_again());
323 361
324 Resume_devices: 362 Resume_devices:
325 suspend_test_start(); 363 suspend_test_start();
326 dpm_resume_end(PMSG_RESUME); 364 dpm_resume_end(PMSG_RESUME);
327 suspend_test_finish("resume devices"); 365 suspend_test_finish("resume devices");
328 resume_console(); 366 resume_console();
329 Close:
330 if (need_suspend_ops(state) && suspend_ops->end)
331 suspend_ops->end();
332 else if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->end)
333 freeze_ops->end();
334 367
368 Close:
369 platform_suspend_end(state);
335 return error; 370 return error;
336 371
337 Recover_platform: 372 Recover_platform:
338 if (need_suspend_ops(state) && suspend_ops->recover) 373 platform_suspend_recover(state);
339 suspend_ops->recover();
340 goto Resume_devices; 374 goto Resume_devices;
341} 375}
342 376