2 * linux/kernel/power/user.c
4 * This file provides the user space interface for software suspend/resume.
6 * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
8 * This file is released under the GPLv2.
12 #include <linux/suspend.h>
13 #include <linux/syscalls.h>
14 #include <linux/string.h>
15 #include <linux/device.h>
16 #include <linux/miscdevice.h>
18 #include <linux/swap.h>
19 #include <linux/swapops.h>
22 #include <linux/console.h>
23 #include <linux/cpu.h>
25 #include <asm/uaccess.h>
29 #define SNAPSHOT_MINOR 231
31 static struct snapshot_data
{
32 struct snapshot_handle handle
;
34 struct bitmap_page
*bitmap
;
40 static atomic_t device_available
= ATOMIC_INIT(1);
42 static int snapshot_open(struct inode
*inode
, struct file
*filp
)
44 struct snapshot_data
*data
;
46 if (!atomic_add_unless(&device_available
, -1, 0))
49 if ((filp
->f_flags
& O_ACCMODE
) == O_RDWR
)
52 nonseekable_open(inode
, filp
);
53 data
= &snapshot_state
;
54 filp
->private_data
= data
;
55 memset(&data
->handle
, 0, sizeof(struct snapshot_handle
));
56 if ((filp
->f_flags
& O_ACCMODE
) == O_RDONLY
) {
57 data
->swap
= swsusp_resume_device
? swap_type_of(swsusp_resume_device
) : -1;
58 data
->mode
= O_RDONLY
;
61 data
->mode
= O_WRONLY
;
70 static int snapshot_release(struct inode
*inode
, struct file
*filp
)
72 struct snapshot_data
*data
;
75 data
= filp
->private_data
;
76 free_all_swap_pages(data
->swap
, data
->bitmap
);
77 free_bitmap(data
->bitmap
);
81 enable_nonboot_cpus();
84 atomic_inc(&device_available
);
88 static ssize_t
snapshot_read(struct file
*filp
, char __user
*buf
,
89 size_t count
, loff_t
*offp
)
91 struct snapshot_data
*data
;
94 data
= filp
->private_data
;
95 res
= snapshot_read_next(&data
->handle
, count
);
97 if (copy_to_user(buf
, data_of(data
->handle
), res
))
100 *offp
= data
->handle
.offset
;
105 static ssize_t
snapshot_write(struct file
*filp
, const char __user
*buf
,
106 size_t count
, loff_t
*offp
)
108 struct snapshot_data
*data
;
111 data
= filp
->private_data
;
112 res
= snapshot_write_next(&data
->handle
, count
);
114 if (copy_from_user(data_of(data
->handle
), buf
, res
))
117 *offp
= data
->handle
.offset
;
122 static int snapshot_ioctl(struct inode
*inode
, struct file
*filp
,
123 unsigned int cmd
, unsigned long arg
)
126 struct snapshot_data
*data
;
127 loff_t offset
, avail
;
129 if (_IOC_TYPE(cmd
) != SNAPSHOT_IOC_MAGIC
)
131 if (_IOC_NR(cmd
) > SNAPSHOT_IOC_MAXNR
)
133 if (!capable(CAP_SYS_ADMIN
))
136 data
= filp
->private_data
;
140 case SNAPSHOT_FREEZE
:
144 error
= disable_nonboot_cpus();
146 error
= freeze_processes();
149 enable_nonboot_cpus();
158 case SNAPSHOT_UNFREEZE
:
163 enable_nonboot_cpus();
168 case SNAPSHOT_ATOMIC_SNAPSHOT
:
169 if (data
->mode
!= O_RDONLY
|| !data
->frozen
|| data
->ready
) {
174 /* Free memory before shutting down devices. */
175 error
= swsusp_shrink_memory();
178 error
= device_suspend(PMSG_FREEZE
);
181 error
= swsusp_suspend();
188 error
= put_user(in_suspend
, (unsigned int __user
*)arg
);
193 case SNAPSHOT_ATOMIC_RESTORE
:
194 if (data
->mode
!= O_WRONLY
|| !data
->frozen
||
195 !snapshot_image_loaded(&data
->handle
)) {
199 snapshot_free_unused_memory(&data
->handle
);
201 pm_prepare_console();
203 error
= device_suspend(PMSG_PRETHAW
);
205 error
= swsusp_resume();
209 pm_restore_console();
215 memset(&data
->handle
, 0, sizeof(struct snapshot_handle
));
219 case SNAPSHOT_SET_IMAGE_SIZE
:
223 case SNAPSHOT_AVAIL_SWAP
:
224 avail
= count_swap_pages(data
->swap
, 1);
225 avail
<<= PAGE_SHIFT
;
226 error
= put_user(avail
, (loff_t __user
*)arg
);
229 case SNAPSHOT_GET_SWAP_PAGE
:
230 if (data
->swap
< 0 || data
->swap
>= MAX_SWAPFILES
) {
235 data
->bitmap
= alloc_bitmap(count_swap_pages(data
->swap
, 0));
241 offset
= alloc_swap_page(data
->swap
, data
->bitmap
);
243 offset
<<= PAGE_SHIFT
;
244 error
= put_user(offset
, (loff_t __user
*)arg
);
250 case SNAPSHOT_FREE_SWAP_PAGES
:
251 if (data
->swap
< 0 || data
->swap
>= MAX_SWAPFILES
) {
255 free_all_swap_pages(data
->swap
, data
->bitmap
);
256 free_bitmap(data
->bitmap
);
260 case SNAPSHOT_SET_SWAP_FILE
:
263 * User space encodes device types as two-byte values,
264 * so we need to recode them
266 if (old_decode_dev(arg
)) {
267 data
->swap
= swap_type_of(old_decode_dev(arg
));
285 if (down_trylock(&pm_sem
)) {
290 if (pm_ops
->prepare
) {
291 error
= pm_ops
->prepare(PM_SUSPEND_MEM
);
296 /* Put devices to sleep */
298 error
= device_suspend(PMSG_SUSPEND
);
300 printk(KERN_ERR
"Failed to suspend some devices.\n");
302 /* Enter S3, system is already frozen */
303 suspend_enter(PM_SUSPEND_MEM
);
305 /* Wake up devices */
310 pm_ops
->finish(PM_SUSPEND_MEM
);
324 static struct file_operations snapshot_fops
= {
325 .open
= snapshot_open
,
326 .release
= snapshot_release
,
327 .read
= snapshot_read
,
328 .write
= snapshot_write
,
330 .ioctl
= snapshot_ioctl
,
333 static struct miscdevice snapshot_device
= {
334 .minor
= SNAPSHOT_MINOR
,
336 .fops
= &snapshot_fops
,
339 static int __init
snapshot_device_init(void)
341 return misc_register(&snapshot_device
);
344 device_initcall(snapshot_device_init
);