isdn: guard against a potential NULL pointer dereference in old_capi_manufacturer()
[cascardo/linux.git] / kernel / power / user.c
index bfed3b9..bd0723a 100644 (file)
@@ -151,10 +151,14 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                if (data->frozen)
                        break;
                mutex_lock(&pm_mutex);
-               if (freeze_processes()) {
-                       thaw_processes();
-                       error = -EBUSY;
+               error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
+               if (!error) {
+                       error = freeze_processes();
+                       if (error)
+                               thaw_processes();
                }
+               if (error)
+                       pm_notifier_call_chain(PM_POST_HIBERNATION);
                mutex_unlock(&pm_mutex);
                if (!error)
                        data->frozen = 1;
@@ -165,6 +169,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                        break;
                mutex_lock(&pm_mutex);
                thaw_processes();
+               pm_notifier_call_chain(PM_POST_HIBERNATION);
                mutex_unlock(&pm_mutex);
                data->frozen = 0;
                break;
@@ -188,7 +193,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                        error = -EPERM;
                        break;
                }
-               error = hibernation_restore();
+               error = hibernation_restore(data->platform_suspend);
                break;
 
        case SNAPSHOT_FREE:
@@ -250,47 +255,19 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                break;
 
        case SNAPSHOT_S2RAM:
-               if (!pm_ops) {
-                       error = -ENOSYS;
-                       break;
-               }
-
                if (!data->frozen) {
                        error = -EPERM;
                        break;
                }
-
                if (!mutex_trylock(&pm_mutex)) {
                        error = -EBUSY;
                        break;
                }
-
-               if (pm_ops->prepare) {
-                       error = pm_ops->prepare(PM_SUSPEND_MEM);
-                       if (error)
-                               goto OutS3;
-               }
-
-               /* Put devices to sleep */
-               suspend_console();
-               error = device_suspend(PMSG_SUSPEND);
-               if (error) {
-                       printk(KERN_ERR "Failed to suspend some devices.\n");
-               } else {
-                       error = disable_nonboot_cpus();
-                       if (!error) {
-                               /* Enter S3, system is already frozen */
-                               suspend_enter(PM_SUSPEND_MEM);
-                               enable_nonboot_cpus();
-                       }
-                       /* Wake up devices */
-                       device_resume();
-               }
-               resume_console();
-               if (pm_ops->finish)
-                       pm_ops->finish(PM_SUSPEND_MEM);
-
- OutS3:
+               /*
+                * Tasks are frozen and the notifiers have been called with
+                * PM_HIBERNATION_PREPARE
+                */
+               error = suspend_devices_and_enter(PM_SUSPEND_MEM);
                mutex_unlock(&pm_mutex);
                break;