]> git.neil.brown.name Git - history.git/commitdiff
[power] Further swsusp cleanups.
authorPatrick Mochel <mochel@osdl.org>
Tue, 19 Aug 2003 15:39:03 +0000 (08:39 -0700)
committerPatrick Mochel <mochel@osdl.org>
Tue, 19 Aug 2003 15:39:03 +0000 (08:39 -0700)
- Remove drivers_resume() and call from do_magic_resume2(). Handled by core.
- When bringing devices back to life, call device_pm_resume()
- Make sure we report the error from write_suspend_image()
- Remove suspend_power_down() and call to it. Handled by PM core.
- Move swap file resetting and freeing of pagedir to swsusp_free()
- Remove extraneous in_atomic() checks.
- Mark all resume functions __init.
- Move resume_suspend_image() inside swsusp_read() and cleanup.
- Make do_magic() report error.

include/asm-i386/suspend.h
include/linux/suspend.h
kernel/power/console.c
kernel/power/swsusp.c

index f1114b6b5275d0764eb673bd4402278e77d546c2..0d22ec30019b5ba11d3c229729238d75f356aa97 100644 (file)
@@ -38,7 +38,7 @@ struct saved_context {
 extern void save_processor_state(void);
 extern void restore_processor_state(void);
 
-extern void do_magic(int resume);
+extern int do_magic(int resume);
 
 #ifdef CONFIG_ACPI_SLEEP
 extern unsigned long saved_eip;
index da171766c8c8128ed3b06ca86aed90d9d89e4658..132db86c961abfb6329af0da4878e46082af956c 100644 (file)
@@ -48,13 +48,6 @@ extern void drain_local_pages(void);
 extern unsigned int nr_copy_pages __nosavedata;
 extern suspend_pagedir_t *pagedir_nosave __nosavedata;
 
-/* Communication between kernel/suspend.c and arch/i386/suspend.c */
-
-extern void do_magic_resume_1(void);
-extern void do_magic_resume_2(void);
-extern void do_magic_suspend_1(void);
-extern void do_magic_suspend_2(void);
-
 /* Communication between acpi and arch/i386/suspend.c */
 
 extern void do_suspend_lowlevel(int resume);
index c05d0e43675f964ab99940706eb009c67fca8f6d..35b1f50d97de8c58d1e7af5e6c2e484294ec5ae5 100644 (file)
@@ -41,6 +41,11 @@ void pm_restore_console(void)
        console_loglevel = orig_loglevel;
 #ifdef SUSPEND_CONSOLE
        set_console(orig_fgconsole);
+
+       /* FIXME: 
+        * This following part is left over from swsusp. Is it really needed?
+        */
+       update_screen(fg_console);
 #endif
        return;
 }
index 5c70937437d4daad1c447972a2b34a8a318373c0..4ce75e5c23bb2a162475cb5f99d14db406c0c495 100644 (file)
@@ -88,8 +88,6 @@ static dev_t resume_device;
 /* Local variables that should not be affected by save */
 unsigned int nr_copy_pages __nosavedata = 0;
 
-static int pm_suspend_state;
-
 /* Suspend pagedir is allocated before final copy, therefore it
    must be freed after resume 
 
@@ -438,36 +436,6 @@ static suspend_pagedir_t *create_suspend_pagedir(int nr_copy_pages)
 }
 
 
-/* Make disk drivers accept operations, again */
-static void drivers_unsuspend(void)
-{
-       device_resume(RESUME_RESTORE_STATE);
-       device_resume(RESUME_ENABLE);
-}
-
-#define RESUME_PHASE1 1 /* Called from interrupts disabled */
-#define RESUME_PHASE2 2 /* Called with interrupts enabled */
-#define RESUME_ALL_PHASES (RESUME_PHASE1 | RESUME_PHASE2)
-static void drivers_resume(int flags)
-{
-       if (flags & RESUME_PHASE1) {
-               device_resume(RESUME_RESTORE_STATE);
-               device_resume(RESUME_ENABLE);
-       }
-       if (flags & RESUME_PHASE2) {
-               if (pm_suspend_state) {
-                       if(pm_send_all(PM_RESUME,(void *)0))
-                               printk(KERN_WARNING "Problem while sending resume event\n");
-                       pm_suspend_state=0;
-               } else
-                       printk(KERN_WARNING "PM suspend state wasn't raised\n");
-
-#ifdef SUSPEND_CONSOLE
-               update_screen(fg_console);      /* Hmm, is this the problem? */
-#endif
-       }
-}
-
 static int suspend_prepare_image(void)
 {
        struct sysinfo i;
@@ -520,12 +488,14 @@ static int suspend_prepare_image(void)
        return 0;
 }
 
-static void suspend_save_image(void)
+static int suspend_save_image(void)
 {
-       drivers_unsuspend();
+       int error;
+
+       device_pm_resume();
 
        lock_swapdevices();
-       write_suspend_image();
+       error = write_suspend_image();
        lock_swapdevices();     /* This will unlock ignored swap devices since writing is finished */
 
        /* It is important _NOT_ to umount filesystems at this point. We want
@@ -533,29 +503,7 @@ static void suspend_save_image(void)
         * filesystem clean: it is not. (And it does not matter, if we resume
         * correctly, we'll mark system clean, anyway.)
         */
-}
-
-static void suspend_power_down(void)
-{
-       extern int C_A_D;
-       C_A_D = 0;
-       printk(KERN_EMERG "%s%s Trying to power down.\n", name_suspend, TEST_SWSUSP ? "Disable TEST_SWSUSP. NOT ": "");
-#ifdef CONFIG_VT
-       PRINTK(KERN_EMERG "shift_state: %04x\n", shift_state);
-       mdelay(1000);
-       if (TEST_SWSUSP ^ (!!(shift_state & (1 << KG_CTRL))))
-               machine_restart(NULL);
-       else
-#endif
-       {
-               device_shutdown();
-               machine_power_off();
-       }
-
-       printk(KERN_EMERG "%sProbably not capable for powerdown. System halted.\n", name_suspend);
-       machine_halt();
-       while (1);
-       /* NOTREACHED */
+       return error;
 }
 
 /*
@@ -567,32 +515,21 @@ void do_magic_resume_1(void)
        barrier();
        mb();
        spin_lock_irq(&suspend_pagedir_lock);   /* Done to disable interrupts */ 
-
        PRINTK( "Waiting for DMAs to settle down...\n");
-       mdelay(1000);   /* We do not want some readahead with DMA to corrupt our memory, right?
-                          Do it with disabled interrupts for best effect. That way, if some
-                          driver scheduled DMA, we have good chance for DMA to finish ;-). */
+       /* We do not want some readahead with DMA to corrupt our memory, right?
+          Do it with disabled interrupts for best effect. That way, if some
+          driver scheduled DMA, we have good chance for DMA to finish ;-). */
+       mdelay(1000);
 }
 
 void do_magic_resume_2(void)
 {
        BUG_ON (nr_copy_pages_check != nr_copy_pages);
        BUG_ON (pagedir_order_check != pagedir_order);
-
-       __flush_tlb_global();           /* Even mappings of "global" things (vmalloc) need to be fixed */
-
-       PRINTK( "Freeing prev allocated pagedir\n" );
-       free_suspend_pagedir((unsigned long) pagedir_save);
+       
+       /* Even mappings of "global" things (vmalloc) need to be fixed */
+       __flush_tlb_global();
        spin_unlock_irq(&suspend_pagedir_lock);
-       drivers_resume(RESUME_ALL_PHASES);
-
-       PRINTK( "Fixing swap signatures... " );
-       mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
-       PRINTK( "ok\n" );
-
-#ifdef SUSPEND_CONSOLE
-       update_screen(fg_console);      /* Hmm, is this the problem? */
-#endif
 }
 
 /* do_magic() is implemented in arch/?/kernel/suspend_asm.S, and basically does:
@@ -617,40 +554,28 @@ void do_magic_suspend_1(void)
 {
        mb();
        barrier();
-       BUG_ON(in_atomic());
        spin_lock_irq(&suspend_pagedir_lock);
 }
 
-void do_magic_suspend_2(void)
+int do_magic_suspend_2(void)
 {
        int is_problem;
        read_swapfiles();
        is_problem = suspend_prepare_image();
        spin_unlock_irq(&suspend_pagedir_lock);
-       if (!is_problem) {
-               kernel_fpu_end();       /* save_processor_state() does kernel_fpu_begin, and we need to revert it in order to pass in_atomic() checks */
-               BUG_ON(in_atomic());
-               suspend_save_image();
-               suspend_power_down();   /* FIXME: if suspend_power_down is commented out, console is lost after few suspends ?! */
-       }
-
+       if (!is_problem)
+               return suspend_save_image();
        printk(KERN_EMERG "%sSuspend failed, trying to recover...\n", name_suspend);
-       MDELAY(1000); /* So user can wait and report us messages if armageddon comes :-) */
-
        barrier();
        mb();
-       spin_lock_irq(&suspend_pagedir_lock);   /* Done to disable interrupts */ 
        mdelay(1000);
-
-       free_pages((unsigned long) pagedir_nosave, pagedir_order);
-       spin_unlock_irq(&suspend_pagedir_lock);
-       mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
+       return -EFAULT;
 }
 
 /* More restore stuff */
 
 /* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
-static void copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
+static void __init copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
 {
        int i;
        char *topointer=(char *)to, *frompointer=(char *)from;
@@ -667,8 +592,8 @@ static void copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
 /*
  * Returns true if given address/order collides with any orig_address 
  */
-static int does_collide_order(suspend_pagedir_t *pagedir, unsigned long addr,
-               int order)
+static int __init does_collide_order(suspend_pagedir_t *pagedir, 
+                                    unsigned long addr, int order)
 {
        int i;
        unsigned long addre = addr + (PAGE_SIZE<<order);
@@ -685,7 +610,7 @@ static int does_collide_order(suspend_pagedir_t *pagedir, unsigned long addr,
  * We check here that pagedir & pages it points to won't collide with pages
  * where we're going to restore from the loaded pages later
  */
-static int check_pagedir(void)
+static int __init check_pagedir(void)
 {
        int i;
 
@@ -703,7 +628,7 @@ static int check_pagedir(void)
        return 0;
 }
 
-static int relocate_pagedir(void)
+static int __init relocate_pagedir(void)
 {
        /*
         * We have to avoid recursion (not to overflow kernel stack),
@@ -753,13 +678,13 @@ static int relocate_pagedir(void)
  * I really don't think that it's foolproof but more than nothing..
  */
 
-static int sanity_check_failed(char *reason)
+static int __init sanity_check_failed(char *reason)
 {
        printk(KERN_ERR "%s%s\n",name_resume,reason);
        return -EPERM;
 }
 
-static int sanity_check(struct suspend_header *sh)
+static int __init sanity_check(struct suspend_header *sh)
 {
        if(sh->version_code != LINUX_VERSION_CODE)
                return sanity_check_failed("Incorrect kernel version");
@@ -776,7 +701,8 @@ static int sanity_check(struct suspend_header *sh)
        return 0;
 }
 
-static int bdev_read_page(struct block_device *bdev, long pos, void *buf)
+static int __init bdev_read_page(struct block_device *bdev, 
+                                long pos, void *buf)
 {
        struct buffer_head *bh;
        BUG_ON (pos%PAGE_SIZE);
@@ -792,7 +718,8 @@ static int bdev_read_page(struct block_device *bdev, long pos, void *buf)
 
 extern dev_t __init name_to_dev_t(const char *line);
 
-static int __read_suspend_image(struct block_device *bdev, union diskpage *cur)
+static int __init read_suspend_image(struct block_device *bdev, 
+                                    union diskpage *cur)
 {
        swp_entry_t next;
        int i, nr_pgdir_pages;
@@ -869,54 +796,6 @@ static int __read_suspend_image(struct block_device *bdev, union diskpage *cur)
        return 0;
 }
 
-static int read_suspend_image(const char * specialfile)
-{
-       union diskpage *cur;
-       unsigned long scratch_page = 0;
-       int error;
-       char b[BDEVNAME_SIZE];
-
-       resume_device = name_to_dev_t(specialfile);
-       scratch_page = get_zeroed_page(GFP_ATOMIC);
-       cur = (void *) scratch_page;
-       if (cur) {
-               struct block_device *bdev;
-               printk("Resuming from device %s\n",
-                               __bdevname(resume_device, b));
-               bdev = open_by_devnum(resume_device, FMODE_READ, BDEV_RAW);
-               if (IS_ERR(bdev)) {
-                       error = PTR_ERR(bdev);
-               } else {
-                       set_blocksize(bdev, PAGE_SIZE);
-                       error = __read_suspend_image(bdev, cur);
-                       blkdev_put(bdev, BDEV_RAW);
-               }
-       } else error = -ENOMEM;
-
-       if (scratch_page)
-               free_page(scratch_page);
-       switch (error) {
-               case 0:
-                       PRINTK("Reading resume file was successful\n");
-                       break;
-               case -EINVAL:
-                       break;
-               case -EIO:
-                       printk( "%sI/O error\n", name_resume);
-                       break;
-               case -ENOENT:
-                       printk( "%s%s: No such file or directory\n", name_resume, specialfile);
-                       break;
-               case -ENOMEM:
-                       printk( "%sNot enough memory\n", name_resume);
-                       break;
-               default:
-                       printk( "%sError %d resuming\n", name_resume, error );
-       }
-       MDELAY(1000);
-       return error;
-}
-
 /**
  *     swsusp_save - Snapshot memory
  */
@@ -944,9 +823,7 @@ int swsusp_save(void)
 int swsusp_write(void)
 {
        arch_prepare_suspend();
-       do_magic(0);
-       MDELAY(1000);
-       return 0;
+       return do_magic(0);
 }
 
 
@@ -954,13 +831,39 @@ int swsusp_write(void)
  *     swsusp_read - Read saved image from swap.
  */
 
-int swsusp_read(void)
+int __init swsusp_read(void)
 {
+       union diskpage *cur;
+       int error;
+       char b[BDEVNAME_SIZE];
+
        if (!strlen(resume_file))
                return -ENOENT;
-       printk("swsusp: %s\n", name_resume );
+
+       resume_device = name_to_dev_t(resume_file);
+       printk("swsusp: Resume From Partition: %s, Device: %s\n", 
+              resume_file, __bdevname(resume_device, b));
+
+       cur = (union diskpage *)get_zeroed_page(GFP_ATOMIC);
+       if (cur) {
+               struct block_device *bdev;
+               bdev = open_by_devnum(resume_device, FMODE_READ, BDEV_RAW);
+               if (!IS_ERR(bdev)) {
+                       set_blocksize(bdev, PAGE_SIZE);
+                       error = read_suspend_image(bdev, cur);
+                       blkdev_put(bdev, BDEV_RAW);
+               } else
+                       error = PTR_ERR(bdev);
+               free_page((unsigned long)cur);
+       } else
+               error = -ENOMEM;
+
+       if (!error)
+               PRINTK("Reading resume file was successful\n");
+       else
+               printk( "%sError %d resuming\n", name_resume, error );
        MDELAY(1000);
-       return read_suspend_image(resume_file);
+       return error;
 }
 
 
@@ -968,10 +871,9 @@ int swsusp_read(void)
  *     swsusp_restore - Replace running kernel with saved image.
  */
 
-int swsusp_restore(void)
+int __init swsusp_restore(void)
 {
-       do_magic(1);
-       return 0;
+       return do_magic(1);
 }
 
 
@@ -981,6 +883,12 @@ int swsusp_restore(void)
 
 int swsusp_free(void)
 {
+       PRINTK( "Freeing prev allocated pagedir\n" );
+       free_suspend_pagedir((unsigned long) pagedir_save);
+
+       PRINTK( "Fixing swap signatures... " );
+       mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
+       PRINTK( "ok\n" );
        return 0;
 }