Messages in this thread Patch in this message | ![/](/images/icornerl.gif) | | Date | Thu, 23 Oct 2003 01:31:27 +0200 | From | Pavel Machek <> | Subject | [pm] fix device suspend/resume handling |
| |
Hi!
swsusp was completely wrong at device handling. Wrong calls with interrupts disabled, where they should be enabled etc. And it forgot to suspend devices before copying memory snapshot back [please check your pmdisk code, you are likely to do the same mistake].
Pavel
[Oops, this one:
- if(drivers_suspend()==0) + if ((res = device_suspend(4))==0)
probably will reject. Sorry about that, should be easy to fix up].
--- tmp/linux/kernel/power/swsusp.c 2003-10-23 01:09:52.000000000 +0200 +++ linux/kernel/power/swsusp.c 2003-10-23 00:59:17.000000000 +0200 @@ -491,33 +491,6 @@ printk("|\n"); } -/* Make disk drivers accept operations, again */ -static void drivers_unsuspend(void) -{ - device_resume(); -} - -/* Called from process context */ -static int drivers_suspend(void) -{ - return device_suspend(4); -} - -#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(); - } - if (flags & RESUME_PHASE2) { -#ifdef SUSPEND_CONSOLE - update_screen(fg_console); /* Hmm, is this the problem? */ -#endif - } -} - static int suspend_prepare_image(void) { struct sysinfo i; @@ -572,7 +545,7 @@ static void suspend_save_image(void) { - drivers_unsuspend(); + device_resume(); lock_swapdevices(); write_suspend_image(); @@ -618,6 +591,7 @@ mb(); spin_lock_irq(&suspend_pagedir_lock); /* Done to disable interrupts */ + device_power_down(4); 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 @@ -633,8 +607,10 @@ PRINTK( "Freeing prev allocated pagedir\n" ); free_suspend_pagedir((unsigned long) pagedir_save); + device_power_up(); spin_unlock_irq(&suspend_pagedir_lock); - drivers_resume(RESUME_ALL_PHASES); + device_resume(); + update_screen(fg_console); /* Hmm, is this the problem? */ PRINTK( "Fixing swap signatures... " ); mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME); @@ -675,7 +651,9 @@ { int is_problem; read_swapfiles(); + device_power_down(4); is_problem = suspend_prepare_image(); + device_power_up(); 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 */ @@ -719,7 +708,7 @@ blk_run_queues(); /* Save state of all device drivers, and stop them. */ - if(drivers_suspend()==0) + if ((res = device_suspend(4))==0) /* If stopping device drivers worked, we proceed basically into * suspend_save_image. * @@ -1094,6 +1071,7 @@ printk( "resuming from %s\n", resume_file); if (read_suspend_image(resume_file, 0)) goto read_failure; + device_suspend(4); do_magic(1); panic("This never returns"); Pavel -- When do you have a heart between your knees? [Johanka's followup: and *two* hearts?] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| ![\](/images/icornerr.gif) |