aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/user.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/user.c')
-rw-r--r--kernel/power/user.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 4ed81e74f86f..957f06164ad1 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -39,6 +39,7 @@ static struct snapshot_data {
39 char frozen; 39 char frozen;
40 char ready; 40 char ready;
41 char platform_support; 41 char platform_support;
42 bool free_bitmaps;
42} snapshot_state; 43} snapshot_state;
43 44
44atomic_t snapshot_device_available = ATOMIC_INIT(1); 45atomic_t snapshot_device_available = ATOMIC_INIT(1);
@@ -60,11 +61,6 @@ static int snapshot_open(struct inode *inode, struct file *filp)
60 error = -ENOSYS; 61 error = -ENOSYS;
61 goto Unlock; 62 goto Unlock;
62 } 63 }
63 if(create_basic_memory_bitmaps()) {
64 atomic_inc(&snapshot_device_available);
65 error = -ENOMEM;
66 goto Unlock;
67 }
68 nonseekable_open(inode, filp); 64 nonseekable_open(inode, filp);
69 data = &snapshot_state; 65 data = &snapshot_state;
70 filp->private_data = data; 66 filp->private_data = data;
@@ -87,13 +83,16 @@ static int snapshot_open(struct inode *inode, struct file *filp)
87 data->swap = -1; 83 data->swap = -1;
88 data->mode = O_WRONLY; 84 data->mode = O_WRONLY;
89 error = pm_notifier_call_chain(PM_RESTORE_PREPARE); 85 error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
86 if (!error) {
87 error = create_basic_memory_bitmaps();
88 data->free_bitmaps = !error;
89 }
90 if (error) 90 if (error)
91 pm_notifier_call_chain(PM_POST_RESTORE); 91 pm_notifier_call_chain(PM_POST_RESTORE);
92 } 92 }
93 if (error) { 93 if (error)
94 free_basic_memory_bitmaps();
95 atomic_inc(&snapshot_device_available); 94 atomic_inc(&snapshot_device_available);
96 } 95
97 data->frozen = 0; 96 data->frozen = 0;
98 data->ready = 0; 97 data->ready = 0;
99 data->platform_support = 0; 98 data->platform_support = 0;
@@ -111,12 +110,14 @@ static int snapshot_release(struct inode *inode, struct file *filp)
111 lock_system_sleep(); 110 lock_system_sleep();
112 111
113 swsusp_free(); 112 swsusp_free();
114 free_basic_memory_bitmaps();
115 data = filp->private_data; 113 data = filp->private_data;
116 free_all_swap_pages(data->swap); 114 free_all_swap_pages(data->swap);
117 if (data->frozen) { 115 if (data->frozen) {
118 pm_restore_gfp_mask(); 116 pm_restore_gfp_mask();
117 free_basic_memory_bitmaps();
119 thaw_processes(); 118 thaw_processes();
119 } else if (data->free_bitmaps) {
120 free_basic_memory_bitmaps();
120 } 121 }
121 pm_notifier_call_chain(data->mode == O_RDONLY ? 122 pm_notifier_call_chain(data->mode == O_RDONLY ?
122 PM_POST_HIBERNATION : PM_POST_RESTORE); 123 PM_POST_HIBERNATION : PM_POST_RESTORE);
@@ -207,6 +208,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
207 if (!mutex_trylock(&pm_mutex)) 208 if (!mutex_trylock(&pm_mutex))
208 return -EBUSY; 209 return -EBUSY;
209 210
211 lock_device_hotplug();
210 data = filp->private_data; 212 data = filp->private_data;
211 213
212 switch (cmd) { 214 switch (cmd) {
@@ -220,14 +222,23 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
220 printk("done.\n"); 222 printk("done.\n");
221 223
222 error = freeze_processes(); 224 error = freeze_processes();
223 if (!error) 225 if (error)
226 break;
227
228 error = create_basic_memory_bitmaps();
229 if (error)
230 thaw_processes();
231 else
224 data->frozen = 1; 232 data->frozen = 1;
233
225 break; 234 break;
226 235
227 case SNAPSHOT_UNFREEZE: 236 case SNAPSHOT_UNFREEZE:
228 if (!data->frozen || data->ready) 237 if (!data->frozen || data->ready)
229 break; 238 break;
230 pm_restore_gfp_mask(); 239 pm_restore_gfp_mask();
240 free_basic_memory_bitmaps();
241 data->free_bitmaps = false;
231 thaw_processes(); 242 thaw_processes();
232 data->frozen = 0; 243 data->frozen = 0;
233 break; 244 break;
@@ -371,6 +382,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
371 382
372 } 383 }
373 384
385 unlock_device_hotplug();
374 mutex_unlock(&pm_mutex); 386 mutex_unlock(&pm_mutex);
375 387
376 return error; 388 return error;