]> err.no Git - linux-2.6/blobdiff - kernel/power/swsusp.c
Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[linux-2.6] / kernel / power / swsusp.c
index c4016cbbd3e05611b7b7dccd9898be340365f31f..f0ee4e7780d66d95cce50199a1c2ebee00cbe9b0 100644 (file)
@@ -62,16 +62,6 @@ 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 int save_highmem(void) { return 0; }
-static int restore_highmem(void) { return 0; }
-static 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.
@@ -175,6 +165,12 @@ void free_all_swap_pages(int swap, struct bitmap_page *bitmap)
  */
 
 #define SHRINK_BITE    10000
+static inline unsigned long __shrink_memory(long tmp)
+{
+       if (tmp > SHRINK_BITE)
+               tmp = SHRINK_BITE;
+       return shrink_all_memory(tmp);
+}
 
 int swsusp_shrink_memory(void)
 {
@@ -186,21 +182,23 @@ int swsusp_shrink_memory(void)
 
        printk("Shrinking memory...  ");
        do {
-               size = 2 * count_highmem_pages();
+               size = 2 * count_special_pages();
                size += size / 50 + count_data_pages();
                size += (size + PBES_PER_PAGE - 1) / PBES_PER_PAGE +
                        PAGES_FOR_IO;
                tmp = size;
                for_each_zone (zone)
-                       if (!is_highmem(zone))
+                       if (!is_highmem(zone) && populated_zone(zone)) {
                                tmp -= zone->free_pages;
+                               tmp += zone->lowmem_reserve[ZONE_NORMAL];
+                       }
                if (tmp > 0) {
-                       tmp = shrink_all_memory(SHRINK_BITE);
+                       tmp = __shrink_memory(tmp);
                        if (!tmp)
                                return -ENOMEM;
                        pages += tmp;
                } else if (size > image_size / PAGE_SIZE) {
-                       tmp = shrink_all_memory(SHRINK_BITE);
+                       tmp = __shrink_memory(size - (image_size / PAGE_SIZE));
                        pages += tmp;
                }
                printk("\b%c", p[i++%4]);
@@ -228,7 +226,7 @@ int swsusp_suspend(void)
                goto Enable_irqs;
        }
 
-       if ((error = save_highmem())) {
+       if ((error = save_special_mem())) {
                printk(KERN_ERR "swsusp: Not enough free pages for highmem\n");
                goto Restore_highmem;
        }
@@ -239,7 +237,7 @@ int swsusp_suspend(void)
        /* Restore control flow magically appears here */
        restore_processor_state();
 Restore_highmem:
-       restore_highmem();
+       restore_special_mem();
        device_power_up();
 Enable_irqs:
        local_irq_enable();
@@ -265,7 +263,7 @@ int swsusp_resume(void)
         */
        swsusp_free();
        restore_processor_state();
-       restore_highmem();
+       restore_special_mem();
        touch_softlockup_watchdog();
        device_power_up();
        local_irq_enable();