Merge tag 'arm-soc-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[platform/kernel/linux-rpi.git] / kernel / power / user.c
index 7959449..d5eedc2 100644 (file)
@@ -35,9 +35,13 @@ static struct snapshot_data {
        bool ready;
        bool platform_support;
        bool free_bitmaps;
+       struct inode *bd_inode;
 } snapshot_state;
 
-atomic_t snapshot_device_available = ATOMIC_INIT(1);
+int is_hibernate_resume_dev(const struct inode *bd_inode)
+{
+       return hibernation_available() && snapshot_state.bd_inode == bd_inode;
+}
 
 static int snapshot_open(struct inode *inode, struct file *filp)
 {
@@ -49,13 +53,13 @@ static int snapshot_open(struct inode *inode, struct file *filp)
 
        lock_system_sleep();
 
-       if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
+       if (!hibernate_acquire()) {
                error = -EBUSY;
                goto Unlock;
        }
 
        if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
-               atomic_inc(&snapshot_device_available);
+               hibernate_release();
                error = -ENOSYS;
                goto Unlock;
        }
@@ -92,11 +96,12 @@ static int snapshot_open(struct inode *inode, struct file *filp)
                        __pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL);
        }
        if (error)
-               atomic_inc(&snapshot_device_available);
+               hibernate_release();
 
        data->frozen = false;
        data->ready = false;
        data->platform_support = false;
+       data->bd_inode = NULL;
 
  Unlock:
        unlock_system_sleep();
@@ -112,6 +117,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
 
        swsusp_free();
        data = filp->private_data;
+       data->bd_inode = NULL;
        free_all_swap_pages(data->swap);
        if (data->frozen) {
                pm_restore_gfp_mask();
@@ -122,7 +128,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
        }
        pm_notifier_call_chain(data->mode == O_RDONLY ?
                        PM_POST_HIBERNATION : PM_POST_RESTORE);
-       atomic_inc(&snapshot_device_available);
+       hibernate_release();
 
        unlock_system_sleep();
 
@@ -204,6 +210,7 @@ struct compat_resume_swap_area {
 static int snapshot_set_swap_area(struct snapshot_data *data,
                void __user *argp)
 {
+       struct block_device *bdev;
        sector_t offset;
        dev_t swdev;
 
@@ -234,9 +241,12 @@ static int snapshot_set_swap_area(struct snapshot_data *data,
                data->swap = -1;
                return -EINVAL;
        }
-       data->swap = swap_type_of(swdev, offset, NULL);
+       data->swap = swap_type_of(swdev, offset, &bdev);
        if (data->swap < 0)
                return -ENODEV;
+
+       data->bd_inode = bdev->bd_inode;
+       bdput(bdev);
        return 0;
 }