diff options
Diffstat (limited to 'kernel/power/main.c')
-rw-r--r-- | kernel/power/main.c | 89 |
1 files changed, 52 insertions, 37 deletions
diff --git a/kernel/power/main.c b/kernel/power/main.c index 239988873971..f172f41858bb 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -57,16 +57,6 @@ int pm_notifier_call_chain(unsigned long val) | |||
57 | #ifdef CONFIG_PM_DEBUG | 57 | #ifdef CONFIG_PM_DEBUG |
58 | int pm_test_level = TEST_NONE; | 58 | int pm_test_level = TEST_NONE; |
59 | 59 | ||
60 | static int suspend_test(int level) | ||
61 | { | ||
62 | if (pm_test_level == level) { | ||
63 | printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); | ||
64 | mdelay(5000); | ||
65 | return 1; | ||
66 | } | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static const char * const pm_tests[__TEST_AFTER_LAST] = { | 60 | static const char * const pm_tests[__TEST_AFTER_LAST] = { |
71 | [TEST_NONE] = "none", | 61 | [TEST_NONE] = "none", |
72 | [TEST_CORE] = "core", | 62 | [TEST_CORE] = "core", |
@@ -125,14 +115,24 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, | |||
125 | } | 115 | } |
126 | 116 | ||
127 | power_attr(pm_test); | 117 | power_attr(pm_test); |
128 | #else /* !CONFIG_PM_DEBUG */ | 118 | #endif /* CONFIG_PM_DEBUG */ |
129 | static inline int suspend_test(int level) { return 0; } | ||
130 | #endif /* !CONFIG_PM_DEBUG */ | ||
131 | 119 | ||
132 | #endif /* CONFIG_PM_SLEEP */ | 120 | #endif /* CONFIG_PM_SLEEP */ |
133 | 121 | ||
134 | #ifdef CONFIG_SUSPEND | 122 | #ifdef CONFIG_SUSPEND |
135 | 123 | ||
124 | static int suspend_test(int level) | ||
125 | { | ||
126 | #ifdef CONFIG_PM_DEBUG | ||
127 | if (pm_test_level == level) { | ||
128 | printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); | ||
129 | mdelay(5000); | ||
130 | return 1; | ||
131 | } | ||
132 | #endif /* !CONFIG_PM_DEBUG */ | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | #ifdef CONFIG_PM_TEST_SUSPEND | 136 | #ifdef CONFIG_PM_TEST_SUSPEND |
137 | 137 | ||
138 | /* | 138 | /* |
@@ -287,25 +287,55 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void) | |||
287 | */ | 287 | */ |
288 | static int suspend_enter(suspend_state_t state) | 288 | static int suspend_enter(suspend_state_t state) |
289 | { | 289 | { |
290 | int error = 0; | 290 | int error; |
291 | 291 | ||
292 | device_pm_lock(); | 292 | device_pm_lock(); |
293 | arch_suspend_disable_irqs(); | ||
294 | BUG_ON(!irqs_disabled()); | ||
295 | 293 | ||
296 | if ((error = device_power_down(PMSG_SUSPEND))) { | 294 | error = device_power_down(PMSG_SUSPEND); |
295 | if (error) { | ||
297 | printk(KERN_ERR "PM: Some devices failed to power down\n"); | 296 | printk(KERN_ERR "PM: Some devices failed to power down\n"); |
298 | goto Done; | 297 | goto Done; |
299 | } | 298 | } |
300 | 299 | ||
301 | if (!suspend_test(TEST_CORE)) | 300 | if (suspend_ops->prepare) { |
302 | error = suspend_ops->enter(state); | 301 | error = suspend_ops->prepare(); |
302 | if (error) | ||
303 | goto Power_up_devices; | ||
304 | } | ||
305 | |||
306 | if (suspend_test(TEST_PLATFORM)) | ||
307 | goto Platfrom_finish; | ||
308 | |||
309 | error = disable_nonboot_cpus(); | ||
310 | if (error || suspend_test(TEST_CPUS)) | ||
311 | goto Enable_cpus; | ||
312 | |||
313 | arch_suspend_disable_irqs(); | ||
314 | BUG_ON(!irqs_disabled()); | ||
315 | |||
316 | error = sysdev_suspend(PMSG_SUSPEND); | ||
317 | if (!error) { | ||
318 | if (!suspend_test(TEST_CORE)) | ||
319 | error = suspend_ops->enter(state); | ||
320 | sysdev_resume(); | ||
321 | } | ||
303 | 322 | ||
304 | device_power_up(PMSG_RESUME); | ||
305 | Done: | ||
306 | arch_suspend_enable_irqs(); | 323 | arch_suspend_enable_irqs(); |
307 | BUG_ON(irqs_disabled()); | 324 | BUG_ON(irqs_disabled()); |
325 | |||
326 | Enable_cpus: | ||
327 | enable_nonboot_cpus(); | ||
328 | |||
329 | Platfrom_finish: | ||
330 | if (suspend_ops->finish) | ||
331 | suspend_ops->finish(); | ||
332 | |||
333 | Power_up_devices: | ||
334 | device_power_up(PMSG_RESUME); | ||
335 | |||
336 | Done: | ||
308 | device_pm_unlock(); | 337 | device_pm_unlock(); |
338 | |||
309 | return error; | 339 | return error; |
310 | } | 340 | } |
311 | 341 | ||
@@ -337,23 +367,8 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
337 | if (suspend_test(TEST_DEVICES)) | 367 | if (suspend_test(TEST_DEVICES)) |
338 | goto Recover_platform; | 368 | goto Recover_platform; |
339 | 369 | ||
340 | if (suspend_ops->prepare) { | 370 | suspend_enter(state); |
341 | error = suspend_ops->prepare(); | ||
342 | if (error) | ||
343 | goto Resume_devices; | ||
344 | } | ||
345 | |||
346 | if (suspend_test(TEST_PLATFORM)) | ||
347 | goto Finish; | ||
348 | |||
349 | error = disable_nonboot_cpus(); | ||
350 | if (!error && !suspend_test(TEST_CPUS)) | ||
351 | suspend_enter(state); | ||
352 | 371 | ||
353 | enable_nonboot_cpus(); | ||
354 | Finish: | ||
355 | if (suspend_ops->finish) | ||
356 | suspend_ops->finish(); | ||
357 | Resume_devices: | 372 | Resume_devices: |
358 | suspend_test_start(); | 373 | suspend_test_start(); |
359 | device_resume(PMSG_RESUME); | 374 | device_resume(PMSG_RESUME); |