diff options
| author | Rafael J. Wysocki <rjw@sisk.pl> | 2007-02-10 04:43:32 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-11 13:51:19 -0500 |
| commit | ed746e3b18f4df18afa3763155972c5835f284c5 (patch) | |
| tree | 322a5420ae8ca653839669035fde9f208d03a566 /kernel | |
| parent | e3c7db621bed4afb8e231cb005057f2feb5db557 (diff) | |
[PATCH] swsusp: Change code ordering in disk.c
Change the ordering of code in kernel/power/disk.c so that device_suspend() is
called before disable_nonboot_cpus() and platform_finish() is called after
enable_nonboot_cpus() and before device_resume(), as indicated by the recent
discussion on Linux-PM (cf.
http://lists.osdl.org/pipermail/linux-pm/2006-November/004164.html).
The changes here only affect the built-in swsusp.
[alexey.y.starikovskiy@linux.intel.com: fix LED blinking during image load]
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Cc: Greg KH <greg@kroah.com>
Cc: Nigel Cunningham <nigel@suspend2.net>
Cc: Patrick Mochel <mochel@digitalimplant.org>
Cc: Alexey Starikovskiy <alexey.y.starikovskiy@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cpu.c | 2 | ||||
| -rw-r--r-- | kernel/power/disk.c | 115 |
2 files changed, 60 insertions, 57 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 7406fe6966f9..3d4206ada5c9 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -309,6 +309,8 @@ void enable_nonboot_cpus(void) | |||
| 309 | mutex_lock(&cpu_add_remove_lock); | 309 | mutex_lock(&cpu_add_remove_lock); |
| 310 | cpu_hotplug_disabled = 0; | 310 | cpu_hotplug_disabled = 0; |
| 311 | mutex_unlock(&cpu_add_remove_lock); | 311 | mutex_unlock(&cpu_add_remove_lock); |
| 312 | if (cpus_empty(frozen_cpus)) | ||
| 313 | return; | ||
| 312 | 314 | ||
| 313 | printk("Enabling non-boot CPUs ...\n"); | 315 | printk("Enabling non-boot CPUs ...\n"); |
| 314 | for_each_cpu_mask(cpu, frozen_cpus) { | 316 | for_each_cpu_mask(cpu, frozen_cpus) { |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 88fc5d7ac737..406b20adb27a 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
| @@ -87,52 +87,24 @@ static inline void platform_finish(void) | |||
| 87 | } | 87 | } |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static void unprepare_processes(void) | ||
| 91 | { | ||
| 92 | thaw_processes(); | ||
| 93 | pm_restore_console(); | ||
| 94 | } | ||
| 95 | |||
| 90 | static int prepare_processes(void) | 96 | static int prepare_processes(void) |
| 91 | { | 97 | { |
| 92 | int error = 0; | 98 | int error = 0; |
| 93 | 99 | ||
| 94 | pm_prepare_console(); | 100 | pm_prepare_console(); |
| 95 | |||
| 96 | error = disable_nonboot_cpus(); | ||
| 97 | if (error) | ||
| 98 | goto enable_cpus; | ||
| 99 | |||
| 100 | if (freeze_processes()) { | 101 | if (freeze_processes()) { |
| 101 | error = -EBUSY; | 102 | error = -EBUSY; |
| 102 | goto thaw; | 103 | unprepare_processes(); |
| 103 | } | 104 | } |
| 104 | |||
| 105 | if (pm_disk_mode == PM_DISK_TESTPROC) { | ||
| 106 | printk("swsusp debug: Waiting for 5 seconds.\n"); | ||
| 107 | mdelay(5000); | ||
| 108 | goto thaw; | ||
| 109 | } | ||
| 110 | |||
| 111 | error = platform_prepare(); | ||
| 112 | if (error) | ||
| 113 | goto thaw; | ||
| 114 | |||
| 115 | /* Free memory before shutting down devices. */ | ||
| 116 | if (!(error = swsusp_shrink_memory())) | ||
| 117 | return 0; | ||
| 118 | |||
| 119 | platform_finish(); | ||
| 120 | thaw: | ||
| 121 | thaw_processes(); | ||
| 122 | enable_cpus: | ||
| 123 | enable_nonboot_cpus(); | ||
| 124 | pm_restore_console(); | ||
| 125 | return error; | 105 | return error; |
| 126 | } | 106 | } |
| 127 | 107 | ||
| 128 | static void unprepare_processes(void) | ||
| 129 | { | ||
| 130 | platform_finish(); | ||
| 131 | thaw_processes(); | ||
| 132 | enable_nonboot_cpus(); | ||
| 133 | pm_restore_console(); | ||
| 134 | } | ||
| 135 | |||
| 136 | /** | 108 | /** |
| 137 | * pm_suspend_disk - The granpappy of hibernation power management. | 109 | * pm_suspend_disk - The granpappy of hibernation power management. |
| 138 | * | 110 | * |
| @@ -150,29 +122,45 @@ int pm_suspend_disk(void) | |||
| 150 | if (error) | 122 | if (error) |
| 151 | return error; | 123 | return error; |
| 152 | 124 | ||
| 153 | if (pm_disk_mode == PM_DISK_TESTPROC) | 125 | if (pm_disk_mode == PM_DISK_TESTPROC) { |
| 154 | return 0; | 126 | printk("swsusp debug: Waiting for 5 seconds.\n"); |
| 127 | mdelay(5000); | ||
| 128 | goto Thaw; | ||
| 129 | } | ||
| 130 | /* Free memory before shutting down devices. */ | ||
| 131 | error = swsusp_shrink_memory(); | ||
| 132 | if (error) | ||
| 133 | goto Thaw; | ||
| 134 | |||
| 135 | error = platform_prepare(); | ||
| 136 | if (error) | ||
| 137 | goto Thaw; | ||
| 155 | 138 | ||
| 156 | suspend_console(); | 139 | suspend_console(); |
| 157 | error = device_suspend(PMSG_FREEZE); | 140 | error = device_suspend(PMSG_FREEZE); |
| 158 | if (error) { | 141 | if (error) { |
| 159 | resume_console(); | 142 | printk(KERN_ERR "PM: Some devices failed to suspend\n"); |
| 160 | printk("Some devices failed to suspend\n"); | 143 | goto Resume_devices; |
| 161 | goto Thaw; | ||
| 162 | } | 144 | } |
| 145 | error = disable_nonboot_cpus(); | ||
| 146 | if (error) | ||
| 147 | goto Enable_cpus; | ||
| 163 | 148 | ||
| 164 | if (pm_disk_mode == PM_DISK_TEST) { | 149 | if (pm_disk_mode == PM_DISK_TEST) { |
| 165 | printk("swsusp debug: Waiting for 5 seconds.\n"); | 150 | printk("swsusp debug: Waiting for 5 seconds.\n"); |
| 166 | mdelay(5000); | 151 | mdelay(5000); |
| 167 | goto Done; | 152 | goto Enable_cpus; |
| 168 | } | 153 | } |
| 169 | 154 | ||
| 170 | pr_debug("PM: snapshotting memory.\n"); | 155 | pr_debug("PM: snapshotting memory.\n"); |
| 171 | in_suspend = 1; | 156 | in_suspend = 1; |
| 172 | if ((error = swsusp_suspend())) | 157 | error = swsusp_suspend(); |
| 173 | goto Done; | 158 | if (error) |
| 159 | goto Enable_cpus; | ||
| 174 | 160 | ||
| 175 | if (in_suspend) { | 161 | if (in_suspend) { |
| 162 | enable_nonboot_cpus(); | ||
| 163 | platform_finish(); | ||
| 176 | device_resume(); | 164 | device_resume(); |
| 177 | resume_console(); | 165 | resume_console(); |
| 178 | pr_debug("PM: writing image.\n"); | 166 | pr_debug("PM: writing image.\n"); |
| @@ -188,7 +176,10 @@ int pm_suspend_disk(void) | |||
| 188 | } | 176 | } |
| 189 | 177 | ||
| 190 | swsusp_free(); | 178 | swsusp_free(); |
| 191 | Done: | 179 | Enable_cpus: |
| 180 | enable_nonboot_cpus(); | ||
| 181 | Resume_devices: | ||
| 182 | platform_finish(); | ||
| 192 | device_resume(); | 183 | device_resume(); |
| 193 | resume_console(); | 184 | resume_console(); |
| 194 | Thaw: | 185 | Thaw: |
| @@ -237,19 +228,28 @@ static int software_resume(void) | |||
| 237 | 228 | ||
| 238 | pr_debug("PM: Checking swsusp image.\n"); | 229 | pr_debug("PM: Checking swsusp image.\n"); |
| 239 | 230 | ||
| 240 | if ((error = swsusp_check())) | 231 | error = swsusp_check(); |
| 232 | if (error) | ||
| 241 | goto Done; | 233 | goto Done; |
| 242 | 234 | ||
| 243 | pr_debug("PM: Preparing processes for restore.\n"); | 235 | pr_debug("PM: Preparing processes for restore.\n"); |
| 244 | 236 | ||
| 245 | if ((error = prepare_processes())) { | 237 | error = prepare_processes(); |
| 238 | if (error) { | ||
| 246 | swsusp_close(); | 239 | swsusp_close(); |
| 247 | goto Done; | 240 | goto Done; |
| 248 | } | 241 | } |
| 249 | 242 | ||
| 243 | error = platform_prepare(); | ||
| 244 | if (error) { | ||
| 245 | swsusp_free(); | ||
| 246 | goto Thaw; | ||
| 247 | } | ||
| 248 | |||
| 250 | pr_debug("PM: Reading swsusp image.\n"); | 249 | pr_debug("PM: Reading swsusp image.\n"); |
| 251 | 250 | ||
| 252 | if ((error = swsusp_read())) { | 251 | error = swsusp_read(); |
| 252 | if (error) { | ||
| 253 | swsusp_free(); | 253 | swsusp_free(); |
| 254 | goto Thaw; | 254 | goto Thaw; |
| 255 | } | 255 | } |
| @@ -257,21 +257,22 @@ static int software_resume(void) | |||
| 257 | pr_debug("PM: Preparing devices for restore.\n"); | 257 | pr_debug("PM: Preparing devices for restore.\n"); |
| 258 | 258 | ||
| 259 | suspend_console(); | 259 | suspend_console(); |
| 260 | if ((error = device_suspend(PMSG_PRETHAW))) { | 260 | error = device_suspend(PMSG_PRETHAW); |
| 261 | resume_console(); | 261 | if (error) |
| 262 | printk("Some devices failed to suspend\n"); | 262 | goto Free; |
| 263 | swsusp_free(); | ||
| 264 | goto Thaw; | ||
| 265 | } | ||
| 266 | 263 | ||
| 267 | mb(); | 264 | error = disable_nonboot_cpus(); |
| 265 | if (!error) | ||
| 266 | swsusp_resume(); | ||
| 268 | 267 | ||
| 269 | pr_debug("PM: Restoring saved image.\n"); | 268 | enable_nonboot_cpus(); |
| 270 | swsusp_resume(); | 269 | Free: |
| 271 | pr_debug("PM: Restore failed, recovering.n"); | 270 | swsusp_free(); |
| 271 | platform_finish(); | ||
| 272 | device_resume(); | 272 | device_resume(); |
| 273 | resume_console(); | 273 | resume_console(); |
| 274 | Thaw: | 274 | Thaw: |
| 275 | printk(KERN_ERR "PM: Restore failed, recovering.\n"); | ||
| 275 | unprepare_processes(); | 276 | unprepare_processes(); |
| 276 | Done: | 277 | Done: |
| 277 | /* For success case, the suspend path will release the lock */ | 278 | /* For success case, the suspend path will release the lock */ |
