aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-02-10 04:43:31 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-11 13:51:19 -0500
commite3c7db621bed4afb8e231cb005057f2feb5db557 (patch)
tree2a9f21bb058e789290ff37f3a6bea690d8b81504 /kernel/power
parentc1725f2af89f1eda3cb9007290971b55084569a4 (diff)
[PATCH] PM: Change code ordering in main.c
As indicated in a recent thread on Linux-PM, it's necessary to call pm_ops->finish() before devce_resume(), but enable_nonboot_cpus() has to be called before pm_ops->finish() (cf. http://lists.osdl.org/pipermail/linux-pm/2006-November/004164.html). For consistency, it seems reasonable to call disable_nonboot_cpus() after device_suspend(). This way the suspend code will remain symmetrical with respect to the resume code and it may allow us to speed up things in the future by suspending and resuming devices and/or saving the suspend image in many threads. The following series of patches reorders the suspend and resume code so that nonboot CPUs are disabled after devices have been suspended and enabled before the devices are resumed. It also causes pm_ops->finish() to be called after enable_nonboot_cpus() wherever necessary. This patch: Change the ordering of code in kernel/power/main.c so that device_suspend() is called before disable_nonboot_cpus() and pm_ops->finish() is called after enable_nonboot_cpus() and before device_resume(), as indicated by recent discussion on Linux-PM (cf. http://lists.osdl.org/pipermail/linux-pm/2006-November/004164.html). Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Cc: Greg KH <greg@kroah.com> Cc: Nigel Cunningham <nigel@suspend2.net> Cc: Patrick Mochel <mochel@digitalimplant.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/power')
-rw-r--r--kernel/power/main.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 47ca5a2b653b..e1c413120469 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -44,6 +44,11 @@ void pm_set_ops(struct pm_ops * ops)
44 mutex_unlock(&pm_mutex); 44 mutex_unlock(&pm_mutex);
45} 45}
46 46
47static inline void pm_finish(suspend_state_t state)
48{
49 if (pm_ops->finish)
50 pm_ops->finish(state);
51}
47 52
48/** 53/**
49 * suspend_prepare - Do prep work before entering low-power state. 54 * suspend_prepare - Do prep work before entering low-power state.
@@ -64,10 +69,6 @@ static int suspend_prepare(suspend_state_t state)
64 69
65 pm_prepare_console(); 70 pm_prepare_console();
66 71
67 error = disable_nonboot_cpus();
68 if (error)
69 goto Enable_cpu;
70
71 if (freeze_processes()) { 72 if (freeze_processes()) {
72 error = -EAGAIN; 73 error = -EAGAIN;
73 goto Thaw; 74 goto Thaw;
@@ -90,18 +91,22 @@ static int suspend_prepare(suspend_state_t state)
90 } 91 }
91 92
92 suspend_console(); 93 suspend_console();
93 if ((error = device_suspend(PMSG_SUSPEND))) { 94 error = device_suspend(PMSG_SUSPEND);
95 if (error) {
94 printk(KERN_ERR "Some devices failed to suspend\n"); 96 printk(KERN_ERR "Some devices failed to suspend\n");
95 goto Finish; 97 goto Resume_devices;
96 } 98 }
97 return 0; 99 error = disable_nonboot_cpus();
98 Finish: 100 if (!error)
99 if (pm_ops->finish) 101 return 0;
100 pm_ops->finish(state); 102
103 enable_nonboot_cpus();
104 Resume_devices:
105 pm_finish(state);
106 device_resume();
107 resume_console();
101 Thaw: 108 Thaw:
102 thaw_processes(); 109 thaw_processes();
103 Enable_cpu:
104 enable_nonboot_cpus();
105 pm_restore_console(); 110 pm_restore_console();
106 return error; 111 return error;
107} 112}
@@ -136,12 +141,11 @@ int suspend_enter(suspend_state_t state)
136 141
137static void suspend_finish(suspend_state_t state) 142static void suspend_finish(suspend_state_t state)
138{ 143{
144 enable_nonboot_cpus();
145 pm_finish(state);
139 device_resume(); 146 device_resume();
140 resume_console(); 147 resume_console();
141 thaw_processes(); 148 thaw_processes();
142 enable_nonboot_cpus();
143 if (pm_ops && pm_ops->finish)
144 pm_ops->finish(state);
145 pm_restore_console(); 149 pm_restore_console();
146} 150}
147 151