diff options
Diffstat (limited to 'kernel/power/disk.c')
-rw-r--r-- | kernel/power/disk.c | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 02b6764034dc..664eb0469b6e 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/mount.h> | ||
20 | |||
19 | #include "power.h" | 21 | #include "power.h" |
20 | 22 | ||
21 | 23 | ||
@@ -57,16 +59,13 @@ static void power_down(suspend_disk_method_t mode) | |||
57 | error = pm_ops->enter(PM_SUSPEND_DISK); | 59 | error = pm_ops->enter(PM_SUSPEND_DISK); |
58 | break; | 60 | break; |
59 | case PM_DISK_SHUTDOWN: | 61 | case PM_DISK_SHUTDOWN: |
60 | printk("Powering off system\n"); | 62 | kernel_power_off(); |
61 | device_shutdown(); | ||
62 | machine_power_off(); | ||
63 | break; | 63 | break; |
64 | case PM_DISK_REBOOT: | 64 | case PM_DISK_REBOOT: |
65 | device_shutdown(); | 65 | kernel_restart(NULL); |
66 | machine_restart(NULL); | ||
67 | break; | 66 | break; |
68 | } | 67 | } |
69 | machine_halt(); | 68 | kernel_halt(); |
70 | /* Valid image is on the disk, if we continue we risk serious data corruption | 69 | /* Valid image is on the disk, if we continue we risk serious data corruption |
71 | after resume. */ | 70 | after resume. */ |
72 | printk(KERN_CRIT "Please power me down manually\n"); | 71 | printk(KERN_CRIT "Please power me down manually\n"); |
@@ -117,8 +116,8 @@ static void finish(void) | |||
117 | { | 116 | { |
118 | device_resume(); | 117 | device_resume(); |
119 | platform_finish(); | 118 | platform_finish(); |
120 | enable_nonboot_cpus(); | ||
121 | thaw_processes(); | 119 | thaw_processes(); |
120 | enable_nonboot_cpus(); | ||
122 | pm_restore_console(); | 121 | pm_restore_console(); |
123 | } | 122 | } |
124 | 123 | ||
@@ -131,28 +130,35 @@ static int prepare_processes(void) | |||
131 | 130 | ||
132 | sys_sync(); | 131 | sys_sync(); |
133 | 132 | ||
133 | disable_nonboot_cpus(); | ||
134 | |||
134 | if (freeze_processes()) { | 135 | if (freeze_processes()) { |
135 | error = -EBUSY; | 136 | error = -EBUSY; |
136 | return error; | 137 | goto thaw; |
137 | } | 138 | } |
138 | 139 | ||
139 | if (pm_disk_mode == PM_DISK_PLATFORM) { | 140 | if (pm_disk_mode == PM_DISK_PLATFORM) { |
140 | if (pm_ops && pm_ops->prepare) { | 141 | if (pm_ops && pm_ops->prepare) { |
141 | if ((error = pm_ops->prepare(PM_SUSPEND_DISK))) | 142 | if ((error = pm_ops->prepare(PM_SUSPEND_DISK))) |
142 | return error; | 143 | goto thaw; |
143 | } | 144 | } |
144 | } | 145 | } |
145 | 146 | ||
146 | /* Free memory before shutting down devices. */ | 147 | /* Free memory before shutting down devices. */ |
147 | free_some_memory(); | 148 | free_some_memory(); |
148 | |||
149 | return 0; | 149 | return 0; |
150 | thaw: | ||
151 | thaw_processes(); | ||
152 | enable_nonboot_cpus(); | ||
153 | pm_restore_console(); | ||
154 | return error; | ||
150 | } | 155 | } |
151 | 156 | ||
152 | static void unprepare_processes(void) | 157 | static void unprepare_processes(void) |
153 | { | 158 | { |
154 | enable_nonboot_cpus(); | 159 | platform_finish(); |
155 | thaw_processes(); | 160 | thaw_processes(); |
161 | enable_nonboot_cpus(); | ||
156 | pm_restore_console(); | 162 | pm_restore_console(); |
157 | } | 163 | } |
158 | 164 | ||
@@ -160,15 +166,9 @@ static int prepare_devices(void) | |||
160 | { | 166 | { |
161 | int error; | 167 | int error; |
162 | 168 | ||
163 | disable_nonboot_cpus(); | 169 | if ((error = device_suspend(PMSG_FREEZE))) |
164 | if ((error = device_suspend(PMSG_FREEZE))) { | ||
165 | printk("Some devices failed to suspend\n"); | 170 | printk("Some devices failed to suspend\n"); |
166 | platform_finish(); | 171 | return error; |
167 | enable_nonboot_cpus(); | ||
168 | return error; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | } | 172 | } |
173 | 173 | ||
174 | /** | 174 | /** |
@@ -185,9 +185,9 @@ int pm_suspend_disk(void) | |||
185 | int error; | 185 | int error; |
186 | 186 | ||
187 | error = prepare_processes(); | 187 | error = prepare_processes(); |
188 | if (!error) { | 188 | if (error) |
189 | error = prepare_devices(); | 189 | return error; |
190 | } | 190 | error = prepare_devices(); |
191 | 191 | ||
192 | if (error) { | 192 | if (error) { |
193 | unprepare_processes(); | 193 | unprepare_processes(); |
@@ -233,6 +233,16 @@ static int software_resume(void) | |||
233 | { | 233 | { |
234 | int error; | 234 | int error; |
235 | 235 | ||
236 | if (!swsusp_resume_device) { | ||
237 | if (!strlen(resume_file)) | ||
238 | return -ENOENT; | ||
239 | swsusp_resume_device = name_to_dev_t(resume_file); | ||
240 | pr_debug("swsusp: Resume From Partition %s\n", resume_file); | ||
241 | } else { | ||
242 | pr_debug("swsusp: Resume From Partition %d:%d\n", | ||
243 | MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); | ||
244 | } | ||
245 | |||
236 | if (noresume) { | 246 | if (noresume) { |
237 | /** | 247 | /** |
238 | * FIXME: If noresume is specified, we need to find the partition | 248 | * FIXME: If noresume is specified, we need to find the partition |
@@ -250,7 +260,7 @@ static int software_resume(void) | |||
250 | 260 | ||
251 | if ((error = prepare_processes())) { | 261 | if ((error = prepare_processes())) { |
252 | swsusp_close(); | 262 | swsusp_close(); |
253 | goto Cleanup; | 263 | goto Done; |
254 | } | 264 | } |
255 | 265 | ||
256 | pr_debug("PM: Reading swsusp image.\n"); | 266 | pr_debug("PM: Reading swsusp image.\n"); |