isdn: guard against a potential NULL pointer dereference in old_capi_manufacturer()
[cascardo/linux.git] / kernel / power / user.c
index d65305b..bd0723a 100644 (file)
@@ -128,92 +128,6 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
        return res;
 }
 
-static inline int platform_prepare(void)
-{
-       int error = 0;
-
-       if (hibernation_ops)
-               error = hibernation_ops->prepare();
-
-       return error;
-}
-
-static inline void platform_finish(void)
-{
-       if (hibernation_ops)
-               hibernation_ops->finish();
-}
-
-static inline int snapshot_suspend(int platform_suspend)
-{
-       int error;
-
-       mutex_lock(&pm_mutex);
-       /* Free memory before shutting down devices. */
-       error = swsusp_shrink_memory();
-       if (error)
-               goto Finish;
-
-       if (platform_suspend) {
-               error = platform_prepare();
-               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:
-       if (platform_suspend)
-               platform_finish();
-
-       device_resume();
-       resume_console();
- Finish:
-       mutex_unlock(&pm_mutex);
-       return error;
-}
-
-static inline int snapshot_restore(int platform_suspend)
-{
-       int error;
-
-       mutex_lock(&pm_mutex);
-       pm_prepare_console();
-       if (platform_suspend) {
-               error = platform_prepare();
-               if (error)
-                       goto Finish;
-       }
-       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:
-       if (platform_suspend)
-               platform_finish();
-
-       device_resume();
-       resume_console();
- Finish:
-       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)
 {
@@ -237,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;
@@ -251,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;
@@ -260,7 +179,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                        error = -EPERM;
                        break;
                }
-               error = snapshot_suspend(data->platform_suspend);
+               error = hibernation_snapshot(data->platform_suspend);
                if (!error)
                        error = put_user(in_suspend, (unsigned int __user *)arg);
                if (!error)
@@ -274,7 +193,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                        error = -EPERM;
                        break;
                }
-               error = snapshot_restore(data->platform_suspend);
+               error = hibernation_restore(data->platform_suspend);
                break;
 
        case SNAPSHOT_FREE:
@@ -336,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;
 
@@ -386,19 +277,14 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                switch (arg) {
 
                case PMOPS_PREPARE:
-                       if (hibernation_ops) {
-                               data->platform_suspend = 1;
-                               error = 0;
-                       } else {
-                               error = -ENOSYS;
-                       }
+                       data->platform_suspend = 1;
+                       error = 0;
                        break;
 
                case PMOPS_ENTER:
-                       if (data->platform_suspend) {
-                               kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
-                               error = hibernation_ops->enter();
-                       }
+                       if (data->platform_suspend)
+                               error = hibernation_platform_enter();
+
                        break;
 
                case PMOPS_FINISH: