diff options
Diffstat (limited to 'kernel/power/swsusp.c')
| -rw-r--r-- | kernel/power/swsusp.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index f0ee4e7780d6..0b66659dc516 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c | |||
| @@ -62,6 +62,16 @@ unsigned long image_size = 500 * 1024 * 1024; | |||
| 62 | 62 | ||
| 63 | int in_suspend __nosavedata = 0; | 63 | int in_suspend __nosavedata = 0; |
| 64 | 64 | ||
| 65 | #ifdef CONFIG_HIGHMEM | ||
| 66 | unsigned int count_highmem_pages(void); | ||
| 67 | int save_highmem(void); | ||
| 68 | int restore_highmem(void); | ||
| 69 | #else | ||
| 70 | static inline int save_highmem(void) { return 0; } | ||
| 71 | static inline int restore_highmem(void) { return 0; } | ||
| 72 | static inline unsigned int count_highmem_pages(void) { return 0; } | ||
| 73 | #endif | ||
| 74 | |||
| 65 | /** | 75 | /** |
| 66 | * The following functions are used for tracing the allocated | 76 | * The following functions are used for tracing the allocated |
| 67 | * swap pages, so that they can be freed in case of an error. | 77 | * swap pages, so that they can be freed in case of an error. |
| @@ -182,15 +192,14 @@ int swsusp_shrink_memory(void) | |||
| 182 | 192 | ||
| 183 | printk("Shrinking memory... "); | 193 | printk("Shrinking memory... "); |
| 184 | do { | 194 | do { |
| 185 | size = 2 * count_special_pages(); | 195 | size = 2 * count_highmem_pages(); |
| 186 | size += size / 50 + count_data_pages(); | 196 | size += size / 50 + count_data_pages() + PAGES_FOR_IO; |
| 187 | size += (size + PBES_PER_PAGE - 1) / PBES_PER_PAGE + | ||
| 188 | PAGES_FOR_IO; | ||
| 189 | tmp = size; | 197 | tmp = size; |
| 190 | for_each_zone (zone) | 198 | for_each_zone (zone) |
| 191 | if (!is_highmem(zone) && populated_zone(zone)) { | 199 | if (!is_highmem(zone) && populated_zone(zone)) { |
| 192 | tmp -= zone->free_pages; | 200 | tmp -= zone->free_pages; |
| 193 | tmp += zone->lowmem_reserve[ZONE_NORMAL]; | 201 | tmp += zone->lowmem_reserve[ZONE_NORMAL]; |
| 202 | tmp += snapshot_additional_pages(zone); | ||
| 194 | } | 203 | } |
| 195 | if (tmp > 0) { | 204 | if (tmp > 0) { |
| 196 | tmp = __shrink_memory(tmp); | 205 | tmp = __shrink_memory(tmp); |
| @@ -226,7 +235,7 @@ int swsusp_suspend(void) | |||
| 226 | goto Enable_irqs; | 235 | goto Enable_irqs; |
| 227 | } | 236 | } |
| 228 | 237 | ||
| 229 | if ((error = save_special_mem())) { | 238 | if ((error = save_highmem())) { |
| 230 | printk(KERN_ERR "swsusp: Not enough free pages for highmem\n"); | 239 | printk(KERN_ERR "swsusp: Not enough free pages for highmem\n"); |
| 231 | goto Restore_highmem; | 240 | goto Restore_highmem; |
| 232 | } | 241 | } |
| @@ -237,7 +246,10 @@ int swsusp_suspend(void) | |||
| 237 | /* Restore control flow magically appears here */ | 246 | /* Restore control flow magically appears here */ |
| 238 | restore_processor_state(); | 247 | restore_processor_state(); |
| 239 | Restore_highmem: | 248 | Restore_highmem: |
| 240 | restore_special_mem(); | 249 | restore_highmem(); |
| 250 | /* NOTE: device_power_up() is just a resume() for devices | ||
| 251 | * that suspended with irqs off ... no overall powerup. | ||
| 252 | */ | ||
| 241 | device_power_up(); | 253 | device_power_up(); |
| 242 | Enable_irqs: | 254 | Enable_irqs: |
| 243 | local_irq_enable(); | 255 | local_irq_enable(); |
| @@ -247,8 +259,12 @@ Enable_irqs: | |||
| 247 | int swsusp_resume(void) | 259 | int swsusp_resume(void) |
| 248 | { | 260 | { |
| 249 | int error; | 261 | int error; |
| 262 | |||
| 250 | local_irq_disable(); | 263 | local_irq_disable(); |
| 251 | if (device_power_down(PMSG_FREEZE)) | 264 | /* NOTE: device_power_down() is just a suspend() with irqs off; |
| 265 | * it has no special "power things down" semantics | ||
| 266 | */ | ||
| 267 | if (device_power_down(PMSG_PRETHAW)) | ||
| 252 | printk(KERN_ERR "Some devices failed to power down, very bad\n"); | 268 | printk(KERN_ERR "Some devices failed to power down, very bad\n"); |
| 253 | /* We'll ignore saved state, but this gets preempt count (etc) right */ | 269 | /* We'll ignore saved state, but this gets preempt count (etc) right */ |
| 254 | save_processor_state(); | 270 | save_processor_state(); |
| @@ -263,7 +279,7 @@ int swsusp_resume(void) | |||
| 263 | */ | 279 | */ |
| 264 | swsusp_free(); | 280 | swsusp_free(); |
| 265 | restore_processor_state(); | 281 | restore_processor_state(); |
| 266 | restore_special_mem(); | 282 | restore_highmem(); |
| 267 | touch_softlockup_watchdog(); | 283 | touch_softlockup_watchdog(); |
| 268 | device_power_up(); | 284 | device_power_up(); |
| 269 | local_irq_enable(); | 285 | local_irq_enable(); |
