X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=kernel%2Fpower%2Fswsusp.c;h=081b65103abd3205a885499a01659701744732d4;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=752f6cdb4382968d7798a4dcb94b0135998c9820;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 752f6cdb4..081b65103 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c @@ -317,7 +317,8 @@ static int write_suspend_image(void) for (i=0; i PAGE_SIZE-sizeof(swp_entry_t)); BUG_ON (sizeof(union diskpage) != PAGE_SIZE); BUG_ON (sizeof(struct link) != PAGE_SIZE); - if (!(entry = get_swap_page()).val) + entry = get_swap_page(); + if (!entry.val) panic( "\nNot enough swapspace when writing header" ); if (swapfile_used[swp_type(entry)] != SWAPFILE_SUSPEND) panic("\nNot enough swapspace for header on suspend device" ); @@ -503,6 +506,9 @@ static int count_and_copy_zone(struct zone *zone, struct pbe **pagedir_p) if (!pbe) continue; pbe->orig_address = (long) page_address(page); + /* Copy page is dangerous: it likes to mess with + preempt count on specific cpus. Wrong preempt count is then copied, + oops. */ copy_page((void *)pbe->address, (void *)pbe->orig_address); pbe++; } @@ -693,6 +699,7 @@ static void suspend_power_down(void) else #endif { + device_suspend(3); device_shutdown(); machine_power_off(); } @@ -713,7 +720,7 @@ asmlinkage void do_magic_resume_1(void) mb(); spin_lock_irq(&suspend_pagedir_lock); /* Done to disable interrupts */ - device_power_down(4); + device_power_down(3); 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 @@ -782,7 +789,7 @@ asmlinkage void do_magic_suspend_2(void) { int is_problem; read_swapfiles(); - device_power_down(4); + device_power_down(3); is_problem = suspend_prepare_image(); device_power_up(); spin_unlock_irq(&suspend_pagedir_lock); @@ -799,7 +806,6 @@ asmlinkage void do_magic_suspend_2(void) 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); @@ -836,9 +842,10 @@ int software_suspend(void) need half of memory free. */ free_some_memory(); - - /* Save state of all device drivers, and stop them. */ - if ((res = device_suspend(4))==0) + disable_nonboot_cpus(); + /* Save state of all device drivers, and stop them. */ + printk("Suspending devices... "); + if ((res = device_suspend(3))==0) { /* If stopping device drivers worked, we proceed basically into * suspend_save_image. * @@ -849,7 +856,9 @@ int software_suspend(void) * using normal kernel mechanism. */ do_magic(0); + } thaw_processes(); + enable_nonboot_cpus(); } else res = -EBUSY; software_suspend_enabled = 1; @@ -860,19 +869,6 @@ int software_suspend(void) /* More restore stuff */ -/* FIXME: Why not memcpy(to, from, 1<