3/3 swsusp: enable resume from initrd
Hi! From: [EMAIL PROTECTED] When using a fully modularized kernel it is necessary to activate resume manually as the device node might not be available during kernel init. This patch implements a new sysfs attribute '/sys/power/resume' which allows for manual activation of software resume. When read from it prints the configured resume device in 'major:minor' format. When written to it expects a device in 'major:minor' format. This device is then checked for a suspended image and resume is started if a valid image is found. The original functionality is left in place. It should be used from initramfs, or with care. Please apply, Pavel Signed-off-by: Hannes Reinecke <[EMAIL PROTECTED]> Signed-off-by: Pavel Machek <[EMAIL PROTECTED]> --- linux.middle/include/linux/suspend.h2005-02-14 14:14:21.0 +0100 +++ linux/include/linux/suspend.h 2005-03-03 13:23:17.0 +0100 @@ -35,6 +35,8 @@ #define SUSPEND_PD_PAGES(x) (((x)*sizeof(struct pbe))/PAGE_SIZE+1) + +extern dev_t swsusp_resume_device; /* mm/vmscan.c */ extern int shrink_mem(void); --- linux.middle/init/do_mounts.c 2005-02-03 22:28:15.0 +0100 +++ linux/init/do_mounts.c 2005-03-03 13:23:17.0 +0100 @@ -53,7 +53,7 @@ __setup("ro", readonly); __setup("rw", readwrite); -static dev_t __init try_name(char *name, int part) +static dev_t try_name(char *name, int part) { char path[64]; char buf[32]; @@ -135,7 +135,7 @@ * is mounted on rootfs /sys. */ -dev_t __init name_to_dev_t(char *name) +dev_t name_to_dev_t(char *name) { char s[32]; char *p; --- linux.middle/kernel/power/disk.c2005-03-02 00:22:49.0 +0100 +++ linux/kernel/power/disk.c 2005-03-04 10:15:46.0 +0100 @@ -16,7 +18,6 @@ #include #include #include -#include #include "power.h" @@ -25,13 +26,16 @@ extern int swsusp_suspend(void); extern int swsusp_write(void); +extern int swsusp_check(void); extern int swsusp_read(void); +extern void swsusp_close(void); extern int swsusp_resume(void); extern int swsusp_free(void); static int noresume = 0; char resume_file[256] = CONFIG_PM_STD_PARTITION; +dev_t swsusp_resume_device; /** * power_down - Shut machine down for hibernate. @@ -123,45 +127,54 @@ } -static int prepare(void) +static int prepare_processes(void) { int error; pm_prepare_console(); sys_sync(); + if (freeze_processes()) { error = -EBUSY; - goto Thaw; + return error; } if (pm_disk_mode == PM_DISK_PLATFORM) { if (pm_ops && pm_ops->prepare) { if ((error = pm_ops->prepare(PM_SUSPEND_DISK))) - goto Thaw; + return error; } } /* Free memory before shutting down devices. */ free_some_memory(); + return 0; +} + +static void unprepare_processes(void) +{ + enable_nonboot_cpus(); + thaw_processes(); + pm_restore_console(); +} + +static int prepare_devices(void) +{ + int error; + disable_nonboot_cpus(); if ((error = device_suspend(PMSG_FREEZE))) { printk("Some devices failed to suspend\n"); - goto Finish; + platform_finish(); + enable_nonboot_cpus(); + return error; } return 0; - Finish: - platform_finish(); - Thaw: - enable_nonboot_cpus(); - thaw_processes(); - pm_restore_console(); - return error; } - /** * pm_suspend_disk - The granpappy of power management. * @@ -175,8 +188,15 @@ { int error; - if ((error = prepare())) + error = prepare_processes(); + if (!error) { + error = prepare_devices(); + } + + if (error) { + unprepare_processes(); return error; + } pr_debug("PM: Attempting to suspend to disk.\n"); if (pm_disk_mode == PM_DISK_FIRMWARE) @@ -225,14 +245,26 @@ return 0; } + pr_debug("PM: Checking swsusp image.\n"); + + if ((error = swsusp_check())) + goto Done; + + pr_debug("PM: Preparing processes for restore.\n"); + + if ((error = prepare_processes())) { + swsusp_close(); + goto Cleanup; + } + pr_debug("PM: Reading swsusp image.\n"); if ((error = swsusp_read())) - goto Done; + goto Cleanup; - pr_debug("PM: Preparing system for restore.\n"); + pr_debug("PM: Preparing devices for restore.\n"); - if ((error = prepare())) + if ((error = prepare_devices())) goto Free; barrier(); @@ -244,6 +276,8 @@ finish(); Free: swsusp_free(); +
3/3 swsusp: enable resume from initrd
Hi! From: [EMAIL PROTECTED] When using a fully modularized kernel it is necessary to activate resume manually as the device node might not be available during kernel init. This patch implements a new sysfs attribute '/sys/power/resume' which allows for manual activation of software resume. When read from it prints the configured resume device in 'major:minor' format. When written to it expects a device in 'major:minor' format. This device is then checked for a suspended image and resume is started if a valid image is found. The original functionality is left in place. It should be used from initramfs, or with care. Please apply, Pavel Signed-off-by: Hannes Reinecke [EMAIL PROTECTED] Signed-off-by: Pavel Machek [EMAIL PROTECTED] --- linux.middle/include/linux/suspend.h2005-02-14 14:14:21.0 +0100 +++ linux/include/linux/suspend.h 2005-03-03 13:23:17.0 +0100 @@ -35,6 +35,8 @@ #define SUSPEND_PD_PAGES(x) (((x)*sizeof(struct pbe))/PAGE_SIZE+1) + +extern dev_t swsusp_resume_device; /* mm/vmscan.c */ extern int shrink_mem(void); --- linux.middle/init/do_mounts.c 2005-02-03 22:28:15.0 +0100 +++ linux/init/do_mounts.c 2005-03-03 13:23:17.0 +0100 @@ -53,7 +53,7 @@ __setup(ro, readonly); __setup(rw, readwrite); -static dev_t __init try_name(char *name, int part) +static dev_t try_name(char *name, int part) { char path[64]; char buf[32]; @@ -135,7 +135,7 @@ * is mounted on rootfs /sys. */ -dev_t __init name_to_dev_t(char *name) +dev_t name_to_dev_t(char *name) { char s[32]; char *p; --- linux.middle/kernel/power/disk.c2005-03-02 00:22:49.0 +0100 +++ linux/kernel/power/disk.c 2005-03-04 10:15:46.0 +0100 @@ -16,7 +18,6 @@ #include linux/device.h #include linux/delay.h #include linux/fs.h -#include linux/device.h #include power.h @@ -25,13 +26,16 @@ extern int swsusp_suspend(void); extern int swsusp_write(void); +extern int swsusp_check(void); extern int swsusp_read(void); +extern void swsusp_close(void); extern int swsusp_resume(void); extern int swsusp_free(void); static int noresume = 0; char resume_file[256] = CONFIG_PM_STD_PARTITION; +dev_t swsusp_resume_device; /** * power_down - Shut machine down for hibernate. @@ -123,45 +127,54 @@ } -static int prepare(void) +static int prepare_processes(void) { int error; pm_prepare_console(); sys_sync(); + if (freeze_processes()) { error = -EBUSY; - goto Thaw; + return error; } if (pm_disk_mode == PM_DISK_PLATFORM) { if (pm_ops pm_ops-prepare) { if ((error = pm_ops-prepare(PM_SUSPEND_DISK))) - goto Thaw; + return error; } } /* Free memory before shutting down devices. */ free_some_memory(); + return 0; +} + +static void unprepare_processes(void) +{ + enable_nonboot_cpus(); + thaw_processes(); + pm_restore_console(); +} + +static int prepare_devices(void) +{ + int error; + disable_nonboot_cpus(); if ((error = device_suspend(PMSG_FREEZE))) { printk(Some devices failed to suspend\n); - goto Finish; + platform_finish(); + enable_nonboot_cpus(); + return error; } return 0; - Finish: - platform_finish(); - Thaw: - enable_nonboot_cpus(); - thaw_processes(); - pm_restore_console(); - return error; } - /** * pm_suspend_disk - The granpappy of power management. * @@ -175,8 +188,15 @@ { int error; - if ((error = prepare())) + error = prepare_processes(); + if (!error) { + error = prepare_devices(); + } + + if (error) { + unprepare_processes(); return error; + } pr_debug(PM: Attempting to suspend to disk.\n); if (pm_disk_mode == PM_DISK_FIRMWARE) @@ -225,14 +245,26 @@ return 0; } + pr_debug(PM: Checking swsusp image.\n); + + if ((error = swsusp_check())) + goto Done; + + pr_debug(PM: Preparing processes for restore.\n); + + if ((error = prepare_processes())) { + swsusp_close(); + goto Cleanup; + } + pr_debug(PM: Reading swsusp image.\n); if ((error = swsusp_read())) - goto Done; + goto Cleanup; - pr_debug(PM: Preparing system for restore.\n); + pr_debug(PM: Preparing devices for restore.\n); - if ((error = prepare())) + if ((error = prepare_devices())) goto Free; barrier(); @@ -244,6 +276,8 @@ finish(); Free: