aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-02-10 04:43:35 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-11 13:51:20 -0500
commit2b5b09b3b576d7323d8b4244429a83f16dc5446a (patch)
tree17c53ee9972226c13d9872d3f5ad0f20a279cda8
parentd12c610e08022a1b84d6bd4412c189214d32e713 (diff)
[PATCH] swsusp: Change pm_ops handling by userland interface
Make the userland interface of swsusp call pm_ops->finish() after enable_nonboot_cpus() and before resume_device(), as indicated by the recent discussion on Linux-PM (cf. http://lists.osdl.org/pipermail/linux-pm/2006-November/004164.html). This patch changes the SNAPSHOT_PMOPS ioctl so that its first function, PMOPS_PREPARE, only sets a switch turning the platform suspend mode on, and its last function, PMOPS_FINISH, only checks if the platform mode is enabled. This should allow the older userland tools to work with new kernels without any modifications. The changes here only affect the userland interface of swsusp. 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>
-rw-r--r--kernel/power/user.c71
1 files changed, 59 insertions, 12 deletions
diff --git a/kernel/power/user.c b/kernel/power/user.c
index b70d83d6b16e..dd09efe7df54 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -37,6 +37,7 @@ static struct snapshot_data {
37 int mode; 37 int mode;
38 char frozen; 38 char frozen;
39 char ready; 39 char ready;
40 char platform_suspend;
40} snapshot_state; 41} snapshot_state;
41 42
42static atomic_t device_available = ATOMIC_INIT(1); 43static atomic_t device_available = ATOMIC_INIT(1);
@@ -66,6 +67,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
66 data->bitmap = NULL; 67 data->bitmap = NULL;
67 data->frozen = 0; 68 data->frozen = 0;
68 data->ready = 0; 69 data->ready = 0;
70 data->platform_suspend = 0;
69 71
70 return 0; 72 return 0;
71} 73}
@@ -122,7 +124,23 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
122 return res; 124 return res;
123} 125}
124 126
125static int snapshot_suspend(void) 127static inline int platform_prepare(void)
128{
129 int error = 0;
130
131 if (pm_ops && pm_ops->prepare)
132 error = pm_ops->prepare(PM_SUSPEND_DISK);
133
134 return error;
135}
136
137static inline void platform_finish(void)
138{
139 if (pm_ops && pm_ops->finish)
140 pm_ops->finish(PM_SUSPEND_DISK);
141}
142
143static inline int snapshot_suspend(int platform_suspend)
126{ 144{
127 int error; 145 int error;
128 146
@@ -132,6 +150,11 @@ static int snapshot_suspend(void)
132 if (error) 150 if (error)
133 goto Finish; 151 goto Finish;
134 152
153 if (platform_suspend) {
154 error = platform_prepare();
155 if (error)
156 goto Finish;
157 }
135 suspend_console(); 158 suspend_console();
136 error = device_suspend(PMSG_FREEZE); 159 error = device_suspend(PMSG_FREEZE);
137 if (error) 160 if (error)
@@ -144,6 +167,9 @@ static int snapshot_suspend(void)
144 } 167 }
145 enable_nonboot_cpus(); 168 enable_nonboot_cpus();
146 Resume_devices: 169 Resume_devices:
170 if (platform_suspend)
171 platform_finish();
172
147 device_resume(); 173 device_resume();
148 resume_console(); 174 resume_console();
149 Finish: 175 Finish:
@@ -151,12 +177,17 @@ static int snapshot_suspend(void)
151 return error; 177 return error;
152} 178}
153 179
154static int snapshot_restore(void) 180static inline int snapshot_restore(int platform_suspend)
155{ 181{
156 int error; 182 int error;
157 183
158 mutex_lock(&pm_mutex); 184 mutex_lock(&pm_mutex);
159 pm_prepare_console(); 185 pm_prepare_console();
186 if (platform_suspend) {
187 error = platform_prepare();
188 if (error)
189 goto Finish;
190 }
160 suspend_console(); 191 suspend_console();
161 error = device_suspend(PMSG_PRETHAW); 192 error = device_suspend(PMSG_PRETHAW);
162 if (error) 193 if (error)
@@ -168,8 +199,12 @@ static int snapshot_restore(void)
168 199
169 enable_nonboot_cpus(); 200 enable_nonboot_cpus();
170 Resume_devices: 201 Resume_devices:
202 if (platform_suspend)
203 platform_finish();
204
171 device_resume(); 205 device_resume();
172 resume_console(); 206 resume_console();
207 Finish:
173 pm_restore_console(); 208 pm_restore_console();
174 mutex_unlock(&pm_mutex); 209 mutex_unlock(&pm_mutex);
175 return error; 210 return error;
@@ -221,7 +256,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
221 error = -EPERM; 256 error = -EPERM;
222 break; 257 break;
223 } 258 }
224 error = snapshot_suspend(); 259 error = snapshot_suspend(data->platform_suspend);
225 if (!error) 260 if (!error)
226 error = put_user(in_suspend, (unsigned int __user *)arg); 261 error = put_user(in_suspend, (unsigned int __user *)arg);
227 if (!error) 262 if (!error)
@@ -235,7 +270,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
235 error = -EPERM; 270 error = -EPERM;
236 break; 271 break;
237 } 272 }
238 error = snapshot_restore(); 273 error = snapshot_restore(data->platform_suspend);
239 break; 274 break;
240 275
241 case SNAPSHOT_FREE: 276 case SNAPSHOT_FREE:
@@ -306,6 +341,11 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
306 break; 341 break;
307 342
308 case SNAPSHOT_S2RAM: 343 case SNAPSHOT_S2RAM:
344 if (!pm_ops) {
345 error = -ENOSYS;
346 break;
347 }
348
309 if (!data->frozen) { 349 if (!data->frozen) {
310 error = -EPERM; 350 error = -EPERM;
311 break; 351 break;
@@ -343,28 +383,35 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
343 break; 383 break;
344 384
345 case SNAPSHOT_PMOPS: 385 case SNAPSHOT_PMOPS:
386 error = -EINVAL;
387
346 switch (arg) { 388 switch (arg) {
347 389
348 case PMOPS_PREPARE: 390 case PMOPS_PREPARE:
349 if (pm_ops->prepare) { 391 if (pm_ops && pm_ops->enter) {
350 error = pm_ops->prepare(PM_SUSPEND_DISK); 392 data->platform_suspend = 1;
393 error = 0;
394 } else {
395 error = -ENOSYS;
351 } 396 }
352 break; 397 break;
353 398
354 case PMOPS_ENTER: 399 case PMOPS_ENTER:
355 kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); 400 if (data->platform_suspend) {
356 error = pm_ops->enter(PM_SUSPEND_DISK); 401 kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
402 error = pm_ops->enter(PM_SUSPEND_DISK);
403 error = 0;
404 }
357 break; 405 break;
358 406
359 case PMOPS_FINISH: 407 case PMOPS_FINISH:
360 if (pm_ops && pm_ops->finish) { 408 if (data->platform_suspend)
361 pm_ops->finish(PM_SUSPEND_DISK); 409 error = 0;
362 } 410
363 break; 411 break;
364 412
365 default: 413 default:
366 printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg); 414 printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg);
367 error = -EINVAL;
368 415
369 } 416 }
370 break; 417 break;