3/3 swsusp: enable resume from initrd

2005-03-09 Thread Pavel Machek
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

2005-03-09 Thread Pavel Machek
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: