aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/power/devices.txt14
-rw-r--r--Documentation/power/notifiers.txt51
-rw-r--r--drivers/base/power/main.c18
-rw-r--r--include/linux/pm.h4
-rw-r--r--kernel/power/hibernate.c17
5 files changed, 61 insertions, 43 deletions
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index 1971bcf48a60..88880839ece4 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -279,11 +279,15 @@ When the system goes into the standby or memory sleep state, the phases are:
279 time.) Unlike the other suspend-related phases, during the prepare 279 time.) Unlike the other suspend-related phases, during the prepare
280 phase the device tree is traversed top-down. 280 phase the device tree is traversed top-down.
281 281
282 The prepare phase uses only a bus callback. After the callback method 282 In addition to that, if device drivers need to allocate additional
283 returns, no new children may be registered below the device. The method 283 memory to be able to hadle device suspend correctly, that should be
284 may also prepare the device or driver in some way for the upcoming 284 done in the prepare phase.
285 system power transition, but it should not put the device into a 285
286 low-power state. 286 After the prepare callback method returns, no new children may be
287 registered below the device. The method may also prepare the device or
288 driver in some way for the upcoming system power transition (for
289 example, by allocating additional memory required for this purpose), but
290 it should not put the device into a low-power state.
287 291
288 2. The suspend methods should quiesce the device to stop it from performing 292 2. The suspend methods should quiesce the device to stop it from performing
289 I/O. They also may save the device registers and put it into the 293 I/O. They also may save the device registers and put it into the
diff --git a/Documentation/power/notifiers.txt b/Documentation/power/notifiers.txt
index cf980709122a..c2a4a346c0d9 100644
--- a/Documentation/power/notifiers.txt
+++ b/Documentation/power/notifiers.txt
@@ -1,46 +1,41 @@
1Suspend notifiers 1Suspend notifiers
2 (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL 2 (C) 2007-2011 Rafael J. Wysocki <rjw@sisk.pl>, GPL
3 3
4There are some operations that device drivers may want to carry out in their 4There are some operations that subsystems or drivers may want to carry out
5.suspend() routines, but shouldn't, because they can cause the hibernation or 5before hibernation/suspend or after restore/resume, but they require the system
6suspend to fail. For example, a driver may want to allocate a substantial amount 6to be fully functional, so the drivers' and subsystems' .suspend() and .resume()
7of memory (like 50 MB) in .suspend(), but that shouldn't be done after the 7or even .prepare() and .complete() callbacks are not suitable for this purpose.
8swsusp's memory shrinker has run. 8For example, device drivers may want to upload firmware to their devices after
9 9resume/restore, but they cannot do it by calling request_firmware() from their
10Also, there may be some operations, that subsystems want to carry out before a 10.resume() or .complete() routines (user land processes are frozen at these
11hibernation/suspend or after a restore/resume, requiring the system to be fully 11points). The solution may be to load the firmware into memory before processes
12functional, so the drivers' .suspend() and .resume() routines are not suitable 12are frozen and upload it from there in the .resume() routine.
13for this purpose. For example, device drivers may want to upload firmware to 13A suspend/hibernation notifier may be used for this purpose.
14their devices after a restore from a hibernation image, but they cannot do it by 14
15calling request_firmware() from their .resume() routines (user land processes 15The subsystems or drivers having such needs can register suspend notifiers that
16are frozen at this point). The solution may be to load the firmware into 16will be called upon the following events by the PM core:
17memory before processes are frozen and upload it from there in the .resume()
18routine. Of course, a hibernation notifier may be used for this purpose.
19
20The subsystems that have such needs can register suspend notifiers that will be
21called upon the following events by the suspend core:
22 17
23PM_HIBERNATION_PREPARE The system is going to hibernate or suspend, tasks will 18PM_HIBERNATION_PREPARE The system is going to hibernate or suspend, tasks will
24 be frozen immediately. 19 be frozen immediately.
25 20
26PM_POST_HIBERNATION The system memory state has been restored from a 21PM_POST_HIBERNATION The system memory state has been restored from a
27 hibernation image or an error occurred during the 22 hibernation image or an error occurred during
28 hibernation. Device drivers' .resume() callbacks have 23 hibernation. Device drivers' restore callbacks have
29 been executed and tasks have been thawed. 24 been executed and tasks have been thawed.
30 25
31PM_RESTORE_PREPARE The system is going to restore a hibernation image. 26PM_RESTORE_PREPARE The system is going to restore a hibernation image.
32 If all goes well the restored kernel will issue a 27 If all goes well, the restored kernel will issue a
33 PM_POST_HIBERNATION notification. 28 PM_POST_HIBERNATION notification.
34 29
35PM_POST_RESTORE An error occurred during the hibernation restore. 30PM_POST_RESTORE An error occurred during restore from hibernation.
36 Device drivers' .resume() callbacks have been executed 31 Device drivers' restore callbacks have been executed
37 and tasks have been thawed. 32 and tasks have been thawed.
38 33
39PM_SUSPEND_PREPARE The system is preparing for a suspend. 34PM_SUSPEND_PREPARE The system is preparing for suspend.
40 35
41PM_POST_SUSPEND The system has just resumed or an error occurred during 36PM_POST_SUSPEND The system has just resumed or an error occurred during
42 the suspend. Device drivers' .resume() callbacks have 37 suspend. Device drivers' resume callbacks have been
43 been executed and tasks have been thawed. 38 executed and tasks have been thawed.
44 39
45It is generally assumed that whatever the notifiers do for 40It is generally assumed that whatever the notifiers do for
46PM_HIBERNATION_PREPARE, should be undone for PM_POST_HIBERNATION. Analogously, 41PM_HIBERNATION_PREPARE, should be undone for PM_POST_HIBERNATION. Analogously,
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 3b354560f306..aa6320207745 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -579,11 +579,13 @@ static bool is_async(struct device *dev)
579 * Execute the appropriate "resume" callback for all devices whose status 579 * Execute the appropriate "resume" callback for all devices whose status
580 * indicates that they are suspended. 580 * indicates that they are suspended.
581 */ 581 */
582static void dpm_resume(pm_message_t state) 582void dpm_resume(pm_message_t state)
583{ 583{
584 struct device *dev; 584 struct device *dev;
585 ktime_t starttime = ktime_get(); 585 ktime_t starttime = ktime_get();
586 586
587 might_sleep();
588
587 mutex_lock(&dpm_list_mtx); 589 mutex_lock(&dpm_list_mtx);
588 pm_transition = state; 590 pm_transition = state;
589 async_error = 0; 591 async_error = 0;
@@ -656,10 +658,12 @@ static void device_complete(struct device *dev, pm_message_t state)
656 * Execute the ->complete() callbacks for all devices whose PM status is not 658 * Execute the ->complete() callbacks for all devices whose PM status is not
657 * DPM_ON (this allows new devices to be registered). 659 * DPM_ON (this allows new devices to be registered).
658 */ 660 */
659static void dpm_complete(pm_message_t state) 661void dpm_complete(pm_message_t state)
660{ 662{
661 struct list_head list; 663 struct list_head list;
662 664
665 might_sleep();
666
663 INIT_LIST_HEAD(&list); 667 INIT_LIST_HEAD(&list);
664 mutex_lock(&dpm_list_mtx); 668 mutex_lock(&dpm_list_mtx);
665 while (!list_empty(&dpm_prepared_list)) { 669 while (!list_empty(&dpm_prepared_list)) {
@@ -688,7 +692,6 @@ static void dpm_complete(pm_message_t state)
688 */ 692 */
689void dpm_resume_end(pm_message_t state) 693void dpm_resume_end(pm_message_t state)
690{ 694{
691 might_sleep();
692 dpm_resume(state); 695 dpm_resume(state);
693 dpm_complete(state); 696 dpm_complete(state);
694} 697}
@@ -912,11 +915,13 @@ static int device_suspend(struct device *dev)
912 * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices. 915 * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
913 * @state: PM transition of the system being carried out. 916 * @state: PM transition of the system being carried out.
914 */ 917 */
915static int dpm_suspend(pm_message_t state) 918int dpm_suspend(pm_message_t state)
916{ 919{
917 ktime_t starttime = ktime_get(); 920 ktime_t starttime = ktime_get();
918 int error = 0; 921 int error = 0;
919 922
923 might_sleep();
924
920 mutex_lock(&dpm_list_mtx); 925 mutex_lock(&dpm_list_mtx);
921 pm_transition = state; 926 pm_transition = state;
922 async_error = 0; 927 async_error = 0;
@@ -1003,10 +1008,12 @@ static int device_prepare(struct device *dev, pm_message_t state)
1003 * 1008 *
1004 * Execute the ->prepare() callback(s) for all devices. 1009 * Execute the ->prepare() callback(s) for all devices.
1005 */ 1010 */
1006static int dpm_prepare(pm_message_t state) 1011int dpm_prepare(pm_message_t state)
1007{ 1012{
1008 int error = 0; 1013 int error = 0;
1009 1014
1015 might_sleep();
1016
1010 mutex_lock(&dpm_list_mtx); 1017 mutex_lock(&dpm_list_mtx);
1011 while (!list_empty(&dpm_list)) { 1018 while (!list_empty(&dpm_list)) {
1012 struct device *dev = to_device(dpm_list.next); 1019 struct device *dev = to_device(dpm_list.next);
@@ -1055,7 +1062,6 @@ int dpm_suspend_start(pm_message_t state)
1055{ 1062{
1056 int error; 1063 int error;
1057 1064
1058 might_sleep();
1059 error = dpm_prepare(state); 1065 error = dpm_prepare(state);
1060 if (!error) 1066 if (!error)
1061 error = dpm_suspend(state); 1067 error = dpm_suspend(state);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 3cc3e7e589f0..dce7c7148771 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -533,10 +533,14 @@ struct dev_power_domain {
533extern void device_pm_lock(void); 533extern void device_pm_lock(void);
534extern void dpm_resume_noirq(pm_message_t state); 534extern void dpm_resume_noirq(pm_message_t state);
535extern void dpm_resume_end(pm_message_t state); 535extern void dpm_resume_end(pm_message_t state);
536extern void dpm_resume(pm_message_t state);
537extern void dpm_complete(pm_message_t state);
536 538
537extern void device_pm_unlock(void); 539extern void device_pm_unlock(void);
538extern int dpm_suspend_noirq(pm_message_t state); 540extern int dpm_suspend_noirq(pm_message_t state);
539extern int dpm_suspend_start(pm_message_t state); 541extern int dpm_suspend_start(pm_message_t state);
542extern int dpm_suspend(pm_message_t state);
543extern int dpm_prepare(pm_message_t state);
540 544
541extern void __suspend_report_result(const char *function, void *fn, int ret); 545extern void __suspend_report_result(const char *function, void *fn, int ret);
542 546
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 95a2ac40f48c..f9bec56d8825 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -327,20 +327,25 @@ static int create_image(int platform_mode)
327 327
328int hibernation_snapshot(int platform_mode) 328int hibernation_snapshot(int platform_mode)
329{ 329{
330 pm_message_t msg = PMSG_RECOVER;
330 int error; 331 int error;
331 332
332 error = platform_begin(platform_mode); 333 error = platform_begin(platform_mode);
333 if (error) 334 if (error)
334 goto Close; 335 goto Close;
335 336
337 error = dpm_prepare(PMSG_FREEZE);
338 if (error)
339 goto Complete_devices;
340
336 /* Preallocate image memory before shutting down devices. */ 341 /* Preallocate image memory before shutting down devices. */
337 error = hibernate_preallocate_memory(); 342 error = hibernate_preallocate_memory();
338 if (error) 343 if (error)
339 goto Close; 344 goto Complete_devices;
340 345
341 suspend_console(); 346 suspend_console();
342 pm_restrict_gfp_mask(); 347 pm_restrict_gfp_mask();
343 error = dpm_suspend_start(PMSG_FREEZE); 348 error = dpm_suspend(PMSG_FREEZE);
344 if (error) 349 if (error)
345 goto Recover_platform; 350 goto Recover_platform;
346 351
@@ -358,13 +363,17 @@ int hibernation_snapshot(int platform_mode)
358 if (error || !in_suspend) 363 if (error || !in_suspend)
359 swsusp_free(); 364 swsusp_free();
360 365
361 dpm_resume_end(in_suspend ? 366 msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE;
362 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 367 dpm_resume(msg);
363 368
364 if (error || !in_suspend) 369 if (error || !in_suspend)
365 pm_restore_gfp_mask(); 370 pm_restore_gfp_mask();
366 371
367 resume_console(); 372 resume_console();
373
374 Complete_devices:
375 dpm_complete(msg);
376
368 Close: 377 Close:
369 platform_end(platform_mode); 378 platform_end(platform_mode);
370 return error; 379 return error;