|
@@ -122,6 +122,59 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
+static inline int snapshot_suspend(void)
|
|
|
+{
|
|
|
+ int error;
|
|
|
+
|
|
|
+ mutex_lock(&pm_mutex);
|
|
|
+ /* Free memory before shutting down devices. */
|
|
|
+ error = swsusp_shrink_memory();
|
|
|
+ if (error)
|
|
|
+ goto Finish;
|
|
|
+
|
|
|
+ suspend_console();
|
|
|
+ error = device_suspend(PMSG_FREEZE);
|
|
|
+ if (error)
|
|
|
+ goto Resume_devices;
|
|
|
+
|
|
|
+ error = disable_nonboot_cpus();
|
|
|
+ if (!error) {
|
|
|
+ in_suspend = 1;
|
|
|
+ error = swsusp_suspend();
|
|
|
+ }
|
|
|
+ enable_nonboot_cpus();
|
|
|
+ Resume_devices:
|
|
|
+ device_resume();
|
|
|
+ resume_console();
|
|
|
+ Finish:
|
|
|
+ mutex_unlock(&pm_mutex);
|
|
|
+ return error;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int snapshot_restore(void)
|
|
|
+{
|
|
|
+ int error;
|
|
|
+
|
|
|
+ mutex_lock(&pm_mutex);
|
|
|
+ pm_prepare_console();
|
|
|
+ suspend_console();
|
|
|
+ error = device_suspend(PMSG_PRETHAW);
|
|
|
+ if (error)
|
|
|
+ goto Resume_devices;
|
|
|
+
|
|
|
+ error = disable_nonboot_cpus();
|
|
|
+ if (!error)
|
|
|
+ error = swsusp_resume();
|
|
|
+
|
|
|
+ enable_nonboot_cpus();
|
|
|
+ Resume_devices:
|
|
|
+ device_resume();
|
|
|
+ resume_console();
|
|
|
+ pm_restore_console();
|
|
|
+ mutex_unlock(&pm_mutex);
|
|
|
+ return error;
|
|
|
+}
|
|
|
+
|
|
|
static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
|
|
unsigned int cmd, unsigned long arg)
|
|
|
{
|
|
@@ -145,14 +198,9 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
|
|
if (data->frozen)
|
|
|
break;
|
|
|
mutex_lock(&pm_mutex);
|
|
|
- error = disable_nonboot_cpus();
|
|
|
- if (!error) {
|
|
|
- error = freeze_processes();
|
|
|
- if (error) {
|
|
|
- thaw_processes();
|
|
|
- enable_nonboot_cpus();
|
|
|
- error = -EBUSY;
|
|
|
- }
|
|
|
+ if (freeze_processes()) {
|
|
|
+ thaw_processes();
|
|
|
+ error = -EBUSY;
|
|
|
}
|
|
|
mutex_unlock(&pm_mutex);
|
|
|
if (!error)
|
|
@@ -164,7 +212,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
|
|
break;
|
|
|
mutex_lock(&pm_mutex);
|
|
|
thaw_processes();
|
|
|
- enable_nonboot_cpus();
|
|
|
mutex_unlock(&pm_mutex);
|
|
|
data->frozen = 0;
|
|
|
break;
|
|
@@ -174,20 +221,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
|
|
error = -EPERM;
|
|
|
break;
|
|
|
}
|
|
|
- mutex_lock(&pm_mutex);
|
|
|
- /* Free memory before shutting down devices. */
|
|
|
- error = swsusp_shrink_memory();
|
|
|
- if (!error) {
|
|
|
- suspend_console();
|
|
|
- error = device_suspend(PMSG_FREEZE);
|
|
|
- if (!error) {
|
|
|
- in_suspend = 1;
|
|
|
- error = swsusp_suspend();
|
|
|
- device_resume();
|
|
|
- }
|
|
|
- resume_console();
|
|
|
- }
|
|
|
- mutex_unlock(&pm_mutex);
|
|
|
+ error = snapshot_suspend();
|
|
|
if (!error)
|
|
|
error = put_user(in_suspend, (unsigned int __user *)arg);
|
|
|
if (!error)
|
|
@@ -201,17 +235,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
|
|
error = -EPERM;
|
|
|
break;
|
|
|
}
|
|
|
- mutex_lock(&pm_mutex);
|
|
|
- pm_prepare_console();
|
|
|
- suspend_console();
|
|
|
- error = device_suspend(PMSG_PRETHAW);
|
|
|
- if (!error) {
|
|
|
- error = swsusp_resume();
|
|
|
- device_resume();
|
|
|
- }
|
|
|
- resume_console();
|
|
|
- pm_restore_console();
|
|
|
- mutex_unlock(&pm_mutex);
|
|
|
+ error = snapshot_restore();
|
|
|
break;
|
|
|
|
|
|
case SNAPSHOT_FREE:
|