aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/main.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-07-19 04:47:38 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:42 -0400
commit6c961dfb7c903cfd1cd71b506863894038fd704f (patch)
tree32890d6ef2cf735243d804778a5b62951aed4ef5 /kernel/power/main.c
parentccd4b65aef4be2278543fde5b999e55a4d694fd8 (diff)
PM: Reduce code duplication between main.c and user.c
The SNAPSHOT_S2RAM ioctl code is outdated and it should not duplicate the suspend code in kernel/power/main.c. Fix that. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Cc: Nigel Cunningham <nigel@nigel.suspend2.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/power/main.c')
-rw-r--r--kernel/power/main.c99
1 files changed, 55 insertions, 44 deletions
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 4d26ad394fb3..32147b57c3bf 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -65,14 +65,11 @@ static inline void pm_finish(suspend_state_t state)
65 65
66/** 66/**
67 * suspend_prepare - Do prep work before entering low-power state. 67 * suspend_prepare - Do prep work before entering low-power state.
68 * @state: State we're entering.
69 * 68 *
70 * This is common code that is called for each state that we're 69 * This is common code that is called for each state that we're entering.
71 * entering. Allocate a console, stop all processes, then make sure 70 * Run suspend notifiers, allocate a console and stop all processes.
72 * the platform can enter the requested state.
73 */ 71 */
74 72static int suspend_prepare(void)
75static int suspend_prepare(suspend_state_t state)
76{ 73{
77 int error; 74 int error;
78 unsigned int free_pages; 75 unsigned int free_pages;
@@ -91,43 +88,18 @@ static int suspend_prepare(suspend_state_t state)
91 goto Thaw; 88 goto Thaw;
92 } 89 }
93 90
94 if ((free_pages = global_page_state(NR_FREE_PAGES)) 91 free_pages = global_page_state(NR_FREE_PAGES);
95 < FREE_PAGE_NUMBER) { 92 if (free_pages < FREE_PAGE_NUMBER) {
96 pr_debug("PM: free some memory\n"); 93 pr_debug("PM: free some memory\n");
97 shrink_all_memory(FREE_PAGE_NUMBER - free_pages); 94 shrink_all_memory(FREE_PAGE_NUMBER - free_pages);
98 if (nr_free_pages() < FREE_PAGE_NUMBER) { 95 if (nr_free_pages() < FREE_PAGE_NUMBER) {
99 error = -ENOMEM; 96 error = -ENOMEM;
100 printk(KERN_ERR "PM: No enough memory\n"); 97 printk(KERN_ERR "PM: No enough memory\n");
101 goto Thaw;
102 } 98 }
103 } 99 }
104
105 if (pm_ops->set_target) {
106 error = pm_ops->set_target(state);
107 if (error)
108 goto Thaw;
109 }
110 suspend_console();
111 error = device_suspend(PMSG_SUSPEND);
112 if (error) {
113 printk(KERN_ERR "Some devices failed to suspend\n");
114 goto Resume_console;
115 }
116 if (pm_ops->prepare) {
117 if ((error = pm_ops->prepare(state)))
118 goto Resume_devices;
119 }
120
121 error = disable_nonboot_cpus();
122 if (!error) 100 if (!error)
123 return 0; 101 return 0;
124 102
125 enable_nonboot_cpus();
126 pm_finish(state);
127 Resume_devices:
128 device_resume();
129 Resume_console:
130 resume_console();
131 Thaw: 103 Thaw:
132 thaw_processes(); 104 thaw_processes();
133 pm_restore_console(); 105 pm_restore_console();
@@ -148,6 +120,12 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void)
148 local_irq_enable(); 120 local_irq_enable();
149} 121}
150 122
123/**
124 * suspend_enter - enter the desired system sleep state.
125 * @state: state to enter
126 *
127 * This function should be called after devices have been suspended.
128 */
151int suspend_enter(suspend_state_t state) 129int suspend_enter(suspend_state_t state)
152{ 130{
153 int error = 0; 131 int error = 0;
@@ -167,21 +145,55 @@ int suspend_enter(suspend_state_t state)
167 return error; 145 return error;
168} 146}
169 147
148/**
149 * suspend_devices_and_enter - suspend devices and enter the desired system sleep
150 * state.
151 * @state: state to enter
152 */
153int suspend_devices_and_enter(suspend_state_t state)
154{
155 int error;
156
157 if (!pm_ops)
158 return -ENOSYS;
159
160 if (pm_ops->set_target) {
161 error = pm_ops->set_target(state);
162 if (error)
163 return error;
164 }
165 suspend_console();
166 error = device_suspend(PMSG_SUSPEND);
167 if (error) {
168 printk(KERN_ERR "Some devices failed to suspend\n");
169 goto Resume_console;
170 }
171 if (pm_ops->prepare) {
172 error = pm_ops->prepare(state);
173 if (error)
174 goto Resume_devices;
175 }
176 error = disable_nonboot_cpus();
177 if (!error)
178 suspend_enter(state);
179
180 enable_nonboot_cpus();
181 pm_finish(state);
182 Resume_devices:
183 device_resume();
184 Resume_console:
185 resume_console();
186 return error;
187}
170 188
171/** 189/**
172 * suspend_finish - Do final work before exiting suspend sequence. 190 * suspend_finish - Do final work before exiting suspend sequence.
173 * @state: State we're coming out of.
174 * 191 *
175 * Call platform code to clean up, restart processes, and free the 192 * Call platform code to clean up, restart processes, and free the
176 * console that we've allocated. This is not called for suspend-to-disk. 193 * console that we've allocated. This is not called for suspend-to-disk.
177 */ 194 */
178 195static void suspend_finish(void)
179static void suspend_finish(suspend_state_t state)
180{ 196{
181 enable_nonboot_cpus();
182 pm_finish(state);
183 device_resume();
184 resume_console();
185 thaw_processes(); 197 thaw_processes();
186 pm_restore_console(); 198 pm_restore_console();
187 pm_notifier_call_chain(PM_POST_SUSPEND); 199 pm_notifier_call_chain(PM_POST_SUSPEND);
@@ -216,7 +228,6 @@ static inline int valid_state(suspend_state_t state)
216 * Then, do the setup for suspend, enter the state, and cleaup (after 228 * Then, do the setup for suspend, enter the state, and cleaup (after
217 * we've woken up). 229 * we've woken up).
218 */ 230 */
219
220static int enter_state(suspend_state_t state) 231static int enter_state(suspend_state_t state)
221{ 232{
222 int error; 233 int error;
@@ -227,14 +238,14 @@ static int enter_state(suspend_state_t state)
227 return -EBUSY; 238 return -EBUSY;
228 239
229 pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); 240 pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
230 if ((error = suspend_prepare(state))) 241 if ((error = suspend_prepare()))
231 goto Unlock; 242 goto Unlock;
232 243
233 pr_debug("PM: Entering %s sleep\n", pm_states[state]); 244 pr_debug("PM: Entering %s sleep\n", pm_states[state]);
234 error = suspend_enter(state); 245 error = suspend_devices_and_enter(state);
235 246
236 pr_debug("PM: Finishing wakeup.\n"); 247 pr_debug("PM: Finishing wakeup.\n");
237 suspend_finish(state); 248 suspend_finish();
238 Unlock: 249 Unlock:
239 mutex_unlock(&pm_mutex); 250 mutex_unlock(&pm_mutex);
240 return error; 251 return error;