X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fpower%2Fswsusp.c;h=0b66659dc516f13eed980412dc196781ffa6892e;hb=2dc20a51dc1e2da6eae1182cfe4c4835fca26017;hp=f0ee4e7780d66d95cce50199a1c2ebee00cbe9b0;hpb=c0897856553d45aee1780bed455b7c2e888dd64b;p=linux-2.6 diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index f0ee4e7780..0b66659dc5 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c @@ -62,6 +62,16 @@ unsigned long image_size = 500 * 1024 * 1024; int in_suspend __nosavedata = 0; +#ifdef CONFIG_HIGHMEM +unsigned int count_highmem_pages(void); +int save_highmem(void); +int restore_highmem(void); +#else +static inline int save_highmem(void) { return 0; } +static inline int restore_highmem(void) { return 0; } +static inline unsigned int count_highmem_pages(void) { return 0; } +#endif + /** * The following functions are used for tracing the allocated * swap pages, so that they can be freed in case of an error. @@ -182,15 +192,14 @@ int swsusp_shrink_memory(void) printk("Shrinking memory... "); do { - size = 2 * count_special_pages(); - size += size / 50 + count_data_pages(); - size += (size + PBES_PER_PAGE - 1) / PBES_PER_PAGE + - PAGES_FOR_IO; + size = 2 * count_highmem_pages(); + size += size / 50 + count_data_pages() + PAGES_FOR_IO; tmp = size; for_each_zone (zone) if (!is_highmem(zone) && populated_zone(zone)) { tmp -= zone->free_pages; tmp += zone->lowmem_reserve[ZONE_NORMAL]; + tmp += snapshot_additional_pages(zone); } if (tmp > 0) { tmp = __shrink_memory(tmp); @@ -226,7 +235,7 @@ int swsusp_suspend(void) goto Enable_irqs; } - if ((error = save_special_mem())) { + if ((error = save_highmem())) { printk(KERN_ERR "swsusp: Not enough free pages for highmem\n"); goto Restore_highmem; } @@ -237,7 +246,10 @@ int swsusp_suspend(void) /* Restore control flow magically appears here */ restore_processor_state(); Restore_highmem: - restore_special_mem(); + restore_highmem(); + /* NOTE: device_power_up() is just a resume() for devices + * that suspended with irqs off ... no overall powerup. + */ device_power_up(); Enable_irqs: local_irq_enable(); @@ -247,8 +259,12 @@ Enable_irqs: int swsusp_resume(void) { int error; + local_irq_disable(); - if (device_power_down(PMSG_FREEZE)) + /* NOTE: device_power_down() is just a suspend() with irqs off; + * it has no special "power things down" semantics + */ + if (device_power_down(PMSG_PRETHAW)) printk(KERN_ERR "Some devices failed to power down, very bad\n"); /* We'll ignore saved state, but this gets preempt count (etc) right */ save_processor_state(); @@ -263,7 +279,7 @@ int swsusp_resume(void) */ swsusp_free(); restore_processor_state(); - restore_special_mem(); + restore_highmem(); touch_softlockup_watchdog(); device_power_up(); local_irq_enable();