diff options
Diffstat (limited to 'kernel/power/user.c')
-rw-r--r-- | kernel/power/user.c | 120 |
1 files changed, 18 insertions, 102 deletions
diff --git a/kernel/power/user.c b/kernel/power/user.c index 6d8f535c2b88..78bdb4404aab 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -30,28 +30,6 @@ | |||
30 | 30 | ||
31 | #include "power.h" | 31 | #include "power.h" |
32 | 32 | ||
33 | /* | ||
34 | * NOTE: The SNAPSHOT_SET_SWAP_FILE and SNAPSHOT_PMOPS ioctls are obsolete and | ||
35 | * will be removed in the future. They are only preserved here for | ||
36 | * compatibility with existing userland utilities. | ||
37 | */ | ||
38 | #define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int) | ||
39 | #define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) | ||
40 | |||
41 | #define PMOPS_PREPARE 1 | ||
42 | #define PMOPS_ENTER 2 | ||
43 | #define PMOPS_FINISH 3 | ||
44 | |||
45 | /* | ||
46 | * NOTE: The following ioctl definitions are wrong and have been replaced with | ||
47 | * correct ones. They are only preserved here for compatibility with existing | ||
48 | * userland utilities and will be removed in the future. | ||
49 | */ | ||
50 | #define SNAPSHOT_ATOMIC_SNAPSHOT _IOW(SNAPSHOT_IOC_MAGIC, 3, void *) | ||
51 | #define SNAPSHOT_SET_IMAGE_SIZE _IOW(SNAPSHOT_IOC_MAGIC, 6, unsigned long) | ||
52 | #define SNAPSHOT_AVAIL_SWAP _IOR(SNAPSHOT_IOC_MAGIC, 7, void *) | ||
53 | #define SNAPSHOT_GET_SWAP_PAGE _IOR(SNAPSHOT_IOC_MAGIC, 8, void *) | ||
54 | |||
55 | 33 | ||
56 | #define SNAPSHOT_MINOR 231 | 34 | #define SNAPSHOT_MINOR 231 |
57 | 35 | ||
@@ -71,7 +49,7 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
71 | struct snapshot_data *data; | 49 | struct snapshot_data *data; |
72 | int error; | 50 | int error; |
73 | 51 | ||
74 | mutex_lock(&pm_mutex); | 52 | lock_system_sleep(); |
75 | 53 | ||
76 | if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { | 54 | if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { |
77 | error = -EBUSY; | 55 | error = -EBUSY; |
@@ -123,7 +101,7 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
123 | data->platform_support = 0; | 101 | data->platform_support = 0; |
124 | 102 | ||
125 | Unlock: | 103 | Unlock: |
126 | mutex_unlock(&pm_mutex); | 104 | unlock_system_sleep(); |
127 | 105 | ||
128 | return error; | 106 | return error; |
129 | } | 107 | } |
@@ -132,7 +110,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
132 | { | 110 | { |
133 | struct snapshot_data *data; | 111 | struct snapshot_data *data; |
134 | 112 | ||
135 | mutex_lock(&pm_mutex); | 113 | lock_system_sleep(); |
136 | 114 | ||
137 | swsusp_free(); | 115 | swsusp_free(); |
138 | free_basic_memory_bitmaps(); | 116 | free_basic_memory_bitmaps(); |
@@ -146,7 +124,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
146 | PM_POST_HIBERNATION : PM_POST_RESTORE); | 124 | PM_POST_HIBERNATION : PM_POST_RESTORE); |
147 | atomic_inc(&snapshot_device_available); | 125 | atomic_inc(&snapshot_device_available); |
148 | 126 | ||
149 | mutex_unlock(&pm_mutex); | 127 | unlock_system_sleep(); |
150 | 128 | ||
151 | return 0; | 129 | return 0; |
152 | } | 130 | } |
@@ -158,7 +136,7 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, | |||
158 | ssize_t res; | 136 | ssize_t res; |
159 | loff_t pg_offp = *offp & ~PAGE_MASK; | 137 | loff_t pg_offp = *offp & ~PAGE_MASK; |
160 | 138 | ||
161 | mutex_lock(&pm_mutex); | 139 | lock_system_sleep(); |
162 | 140 | ||
163 | data = filp->private_data; | 141 | data = filp->private_data; |
164 | if (!data->ready) { | 142 | if (!data->ready) { |
@@ -179,7 +157,7 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, | |||
179 | *offp += res; | 157 | *offp += res; |
180 | 158 | ||
181 | Unlock: | 159 | Unlock: |
182 | mutex_unlock(&pm_mutex); | 160 | unlock_system_sleep(); |
183 | 161 | ||
184 | return res; | 162 | return res; |
185 | } | 163 | } |
@@ -191,7 +169,7 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, | |||
191 | ssize_t res; | 169 | ssize_t res; |
192 | loff_t pg_offp = *offp & ~PAGE_MASK; | 170 | loff_t pg_offp = *offp & ~PAGE_MASK; |
193 | 171 | ||
194 | mutex_lock(&pm_mutex); | 172 | lock_system_sleep(); |
195 | 173 | ||
196 | data = filp->private_data; | 174 | data = filp->private_data; |
197 | 175 | ||
@@ -208,20 +186,11 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, | |||
208 | if (res > 0) | 186 | if (res > 0) |
209 | *offp += res; | 187 | *offp += res; |
210 | unlock: | 188 | unlock: |
211 | mutex_unlock(&pm_mutex); | 189 | unlock_system_sleep(); |
212 | 190 | ||
213 | return res; | 191 | return res; |
214 | } | 192 | } |
215 | 193 | ||
216 | static void snapshot_deprecated_ioctl(unsigned int cmd) | ||
217 | { | ||
218 | if (printk_ratelimit()) | ||
219 | printk(KERN_NOTICE "%pf: ioctl '%.8x' is deprecated and will " | ||
220 | "be removed soon, update your suspend-to-disk " | ||
221 | "utilities\n", | ||
222 | __builtin_return_address(0), cmd); | ||
223 | } | ||
224 | |||
225 | static long snapshot_ioctl(struct file *filp, unsigned int cmd, | 194 | static long snapshot_ioctl(struct file *filp, unsigned int cmd, |
226 | unsigned long arg) | 195 | unsigned long arg) |
227 | { | 196 | { |
@@ -257,11 +226,9 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
257 | break; | 226 | break; |
258 | 227 | ||
259 | error = freeze_processes(); | 228 | error = freeze_processes(); |
260 | if (error) { | 229 | if (error) |
261 | thaw_processes(); | ||
262 | usermodehelper_enable(); | 230 | usermodehelper_enable(); |
263 | } | 231 | else |
264 | if (!error) | ||
265 | data->frozen = 1; | 232 | data->frozen = 1; |
266 | break; | 233 | break; |
267 | 234 | ||
@@ -274,8 +241,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
274 | data->frozen = 0; | 241 | data->frozen = 0; |
275 | break; | 242 | break; |
276 | 243 | ||
277 | case SNAPSHOT_ATOMIC_SNAPSHOT: | ||
278 | snapshot_deprecated_ioctl(cmd); | ||
279 | case SNAPSHOT_CREATE_IMAGE: | 244 | case SNAPSHOT_CREATE_IMAGE: |
280 | if (data->mode != O_RDONLY || !data->frozen || data->ready) { | 245 | if (data->mode != O_RDONLY || !data->frozen || data->ready) { |
281 | error = -EPERM; | 246 | error = -EPERM; |
@@ -283,10 +248,15 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
283 | } | 248 | } |
284 | pm_restore_gfp_mask(); | 249 | pm_restore_gfp_mask(); |
285 | error = hibernation_snapshot(data->platform_support); | 250 | error = hibernation_snapshot(data->platform_support); |
286 | if (!error) | 251 | if (!error) { |
287 | error = put_user(in_suspend, (int __user *)arg); | 252 | error = put_user(in_suspend, (int __user *)arg); |
288 | if (!error) | 253 | if (!error && !freezer_test_done) |
289 | data->ready = 1; | 254 | data->ready = 1; |
255 | if (freezer_test_done) { | ||
256 | freezer_test_done = false; | ||
257 | thaw_processes(); | ||
258 | } | ||
259 | } | ||
290 | break; | 260 | break; |
291 | 261 | ||
292 | case SNAPSHOT_ATOMIC_RESTORE: | 262 | case SNAPSHOT_ATOMIC_RESTORE: |
@@ -305,8 +275,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
305 | data->ready = 0; | 275 | data->ready = 0; |
306 | break; | 276 | break; |
307 | 277 | ||
308 | case SNAPSHOT_SET_IMAGE_SIZE: | ||
309 | snapshot_deprecated_ioctl(cmd); | ||
310 | case SNAPSHOT_PREF_IMAGE_SIZE: | 278 | case SNAPSHOT_PREF_IMAGE_SIZE: |
311 | image_size = arg; | 279 | image_size = arg; |
312 | break; | 280 | break; |
@@ -321,16 +289,12 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
321 | error = put_user(size, (loff_t __user *)arg); | 289 | error = put_user(size, (loff_t __user *)arg); |
322 | break; | 290 | break; |
323 | 291 | ||
324 | case SNAPSHOT_AVAIL_SWAP: | ||
325 | snapshot_deprecated_ioctl(cmd); | ||
326 | case SNAPSHOT_AVAIL_SWAP_SIZE: | 292 | case SNAPSHOT_AVAIL_SWAP_SIZE: |
327 | size = count_swap_pages(data->swap, 1); | 293 | size = count_swap_pages(data->swap, 1); |
328 | size <<= PAGE_SHIFT; | 294 | size <<= PAGE_SHIFT; |
329 | error = put_user(size, (loff_t __user *)arg); | 295 | error = put_user(size, (loff_t __user *)arg); |
330 | break; | 296 | break; |
331 | 297 | ||
332 | case SNAPSHOT_GET_SWAP_PAGE: | ||
333 | snapshot_deprecated_ioctl(cmd); | ||
334 | case SNAPSHOT_ALLOC_SWAP_PAGE: | 298 | case SNAPSHOT_ALLOC_SWAP_PAGE: |
335 | if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { | 299 | if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { |
336 | error = -ENODEV; | 300 | error = -ENODEV; |
@@ -353,27 +317,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
353 | free_all_swap_pages(data->swap); | 317 | free_all_swap_pages(data->swap); |
354 | break; | 318 | break; |
355 | 319 | ||
356 | case SNAPSHOT_SET_SWAP_FILE: /* This ioctl is deprecated */ | ||
357 | snapshot_deprecated_ioctl(cmd); | ||
358 | if (!swsusp_swap_in_use()) { | ||
359 | /* | ||
360 | * User space encodes device types as two-byte values, | ||
361 | * so we need to recode them | ||
362 | */ | ||
363 | if (old_decode_dev(arg)) { | ||
364 | data->swap = swap_type_of(old_decode_dev(arg), | ||
365 | 0, NULL); | ||
366 | if (data->swap < 0) | ||
367 | error = -ENODEV; | ||
368 | } else { | ||
369 | data->swap = -1; | ||
370 | error = -EINVAL; | ||
371 | } | ||
372 | } else { | ||
373 | error = -EPERM; | ||
374 | } | ||
375 | break; | ||
376 | |||
377 | case SNAPSHOT_S2RAM: | 320 | case SNAPSHOT_S2RAM: |
378 | if (!data->frozen) { | 321 | if (!data->frozen) { |
379 | error = -EPERM; | 322 | error = -EPERM; |
@@ -396,33 +339,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
396 | error = hibernation_platform_enter(); | 339 | error = hibernation_platform_enter(); |
397 | break; | 340 | break; |
398 | 341 | ||
399 | case SNAPSHOT_PMOPS: /* This ioctl is deprecated */ | ||
400 | snapshot_deprecated_ioctl(cmd); | ||
401 | error = -EINVAL; | ||
402 | |||
403 | switch (arg) { | ||
404 | |||
405 | case PMOPS_PREPARE: | ||
406 | data->platform_support = 1; | ||
407 | error = 0; | ||
408 | break; | ||
409 | |||
410 | case PMOPS_ENTER: | ||
411 | if (data->platform_support) | ||
412 | error = hibernation_platform_enter(); | ||
413 | break; | ||
414 | |||
415 | case PMOPS_FINISH: | ||
416 | if (data->platform_support) | ||
417 | error = 0; | ||
418 | break; | ||
419 | |||
420 | default: | ||
421 | printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg); | ||
422 | |||
423 | } | ||
424 | break; | ||
425 | |||
426 | case SNAPSHOT_SET_SWAP_AREA: | 342 | case SNAPSHOT_SET_SWAP_AREA: |
427 | if (swsusp_swap_in_use()) { | 343 | if (swsusp_swap_in_use()) { |
428 | error = -EPERM; | 344 | error = -EPERM; |