diff -ruNp 822-includes-old/include/asm-i386/suspend.h 822-includes-new/include/asm-i386/suspend.h
--- 822-includes-old/include/asm-i386/suspend.h	2004-12-10 14:26:29.000000000 +1100
+++ 822-includes-new/include/asm-i386/suspend.h	2004-12-14 07:18:24.000000000 +1100
@@ -3,6 +3,7 @@
  * Based on code
  * Copyright 2001 Patrick Mochel <mochel@osdl.org>
  */
+#include <linux/errno.h>
 #include <asm/desc.h>
 #include <asm/i387.h>
 
diff -ruNp 822-includes-old/include/linux/suspend.h 822-includes-new/include/linux/suspend.h
--- 822-includes-old/include/linux/suspend.h	2004-11-03 21:52:41.000000000 +1100
+++ 822-includes-new/include/linux/suspend.h	2004-12-14 07:18:24.000000000 +1100
@@ -4,58 +4,110 @@
 #ifdef CONFIG_X86
 #include <asm/suspend.h>
 #endif
-#include <linux/swap.h>
-#include <linux/notifier.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/pm.h>
-
-#ifdef CONFIG_PM
-/* page backup entry */
-typedef struct pbe {
-	unsigned long address;		/* address of the copy */
-	unsigned long orig_address;	/* original address of page */
-	swp_entry_t swap_address;	
-	swp_entry_t dummy;		/* we need scratch space at 
-					 * end of page (see link, diskpage)
-					 */
-} suspend_pagedir_t;
-
-#define SWAP_FILENAME_MAXLENGTH	32
-
-
-#define SUSPEND_PD_PAGES(x)     (((x)*sizeof(struct pbe))/PAGE_SIZE+1)
-   
-/* mm/vmscan.c */
-extern int shrink_mem(void);
-
-/* mm/page_alloc.c */
-extern void drain_local_pages(void);
-
-/* kernel/power/swsusp.c */
-extern int software_suspend(void);
-
-#else	/* CONFIG_SOFTWARE_SUSPEND */
-static inline int software_suspend(void)
-{
-	printk("Warning: fake suspend called\n");
-	return -EPERM;
-}
-#endif	/* CONFIG_SOFTWARE_SUSPEND */
 
+#include <linux/kernel.h>
+extern char __nosave_begin, __nosave_end;
 
 #ifdef CONFIG_PM
-extern void refrigerator(unsigned long);
-extern int freeze_processes(void);
-extern void thaw_processes(void);
 
-extern int pm_prepare_console(void);
-extern void pm_restore_console(void);
+#include <linux/init.h>
+
+/* For swsusp */
+#include <linux/swap.h>
 
+extern unsigned long suspend_action;
+extern unsigned long suspend_result;
+extern unsigned long suspend_debug_state;
+
+#define TEST_RESULT_STATE(bit) (test_bit(bit, &suspend_result))
+#define SET_RESULT_STATE(bit) (test_and_set_bit(bit, &suspend_result))
+#define CLEAR_RESULT_STATE(bit) (test_and_clear_bit(bit, &suspend_result))
+
+#define TEST_ACTION_STATE(bit) (test_bit(bit, &suspend_action))
+#define SET_ACTION_STATE(bit) (test_and_set_bit(bit, &suspend_action))
+#define CLEAR_ACTION_STATE(bit) (test_and_clear_bit(bit, &suspend_action))
+
+#ifdef CONFIG_SOFTWARE_SUSPEND_DEBUG
+#define TEST_DEBUG_STATE(bit) (test_bit(bit, &suspend_debug_state))
+#define SET_DEBUG_STATE(bit) (test_and_set_bit(bit, &suspend_debug_state))
+#define CLEAR_DEBUG_STATE(bit) (test_and_clear_bit(bit, &suspend_debug_state))
 #else
-static inline void refrigerator(unsigned long flag) {}
-#endif	/* CONFIG_PM */
+#define TEST_DEBUG_STATE(bit) (0)
+#define SET_DEBUG_STATE(bit) (0)
+#define CLEAR_DEBUG_STATE(bit) (0)
+#endif
 
+/* first status register - this is suspend's return code. */
+#define SUSPEND_ABORTED			0
+#define SUSPEND_ABORT_REQUESTED		1
+#define SUSPEND_NOSTORAGE_AVAILABLE	2
+#define SUSPEND_INSUFFICIENT_STORAGE	3
+#define SUSPEND_FREEZING_FAILED		4
+#define SUSPEND_UNEXPECTED_ALLOC	5
+#define SUSPEND_KEPT_IMAGE		6
+#define SUSPEND_WOULD_EAT_MEMORY	7
+#define SUSPEND_UNABLE_TO_FREE_ENOUGH_MEMORY 8
+
+/* second status register */
+#define SUSPEND_REBOOT			0
+#define SUSPEND_PAUSE			2
+#define SUSPEND_SLOW			3
+#define SUSPEND_NOPAGESET2		7
+#define SUSPEND_LOGALL			8
+#define SUSPEND_CAN_CANCEL		11
+#define SUSPEND_KEEP_IMAGE		13
+#define SUSPEND_FREEZER_TEST		14
+#define SUSPEND_FREEZER_TEST_SHOWALL	15
+#define SUSPEND_SINGLESTEP		16
+#define SUSPEND_PAUSE_NEAR_PAGESET_END	17
+#define SUSPEND_USE_ACPI_S4		18
+#define SUSPEND_KEEP_METADATA		19
+#define SUSPEND_TEST_FILTER_SPEED	20
+#define SUSPEND_FREEZE_TIMERS		21
+#define SUSPEND_DISABLE_SYSDEV_SUPPORT	22
+#define SUSPEND_RETRY_RESUME		23
+
+/* debug sections  - if debugging compiled in */
+#define SUSPEND_ANY_SECTION	0
+#define SUSPEND_FREEZER		1
+#define SUSPEND_EAT_MEMORY 	2
+#define SUSPEND_PAGESETS	3
+#define SUSPEND_IO		4
+#define SUSPEND_BMAP		5
+#define SUSPEND_HEADER		6
+#define SUSPEND_WRITER		9
+#define SUSPEND_MEMORY		10
+#define SUSPEND_EXTENTS		11
+#define SUSPEND_SPINLOCKS	12
+#define SUSPEND_MEM_POOL	13
+#define SUSPEND_RANGE_PARANOIA	14
+#define SUSPEND_NOSAVE		15
+#define SUSPEND_INTEGRITY	16
+/* debugging levels. */
+#define SUSPEND_STATUS		0
+#define SUSPEND_ERROR		2
+#define SUSPEND_LOW	 	3
+#define SUSPEND_MEDIUM	 	4
+#define SUSPEND_HIGH	  	5
+#define SUSPEND_VERBOSE		6
+
+extern void __suspend_message(unsigned long section, unsigned long level, int log_normally,
+		const char *fmt, ...);
+
+#ifdef CONFIG_SOFTWARE_SUSPEND_DEBUG
+#define suspend_message(sn, lev, log, fmt, a...) \
+do { \
+	if (TEST_DEBUG_STATE(sn)) \
+		suspend2_core_ops->suspend_message(sn, lev, log, fmt, ##a); \
+} while(0)
+#else /* CONFIG_SOFTWARE_SUSPEND_DEBUG */
+#define suspend_message(sn, lev, log, fmt, a...) \
+do { \
+	if (lev == 0) \
+		suspend2_core_ops->suspend_message(sn, lev, log, fmt, ##a); \
+} while(0)
+#endif /* CONFIG_SOFTWARE_SUSPEND_DEBUG */
+  
 #ifdef CONFIG_SMP
 extern void disable_nonboot_cpus(void);
 extern void enable_nonboot_cpus(void);
@@ -64,10 +116,145 @@ static inline void disable_nonboot_cpus(
 static inline void enable_nonboot_cpus(void) {}
 #endif
 
-void save_processor_state(void);
-void restore_processor_state(void);
-struct saved_context;
-void __save_processor_state(struct saved_context *ctxt);
-void __restore_processor_state(struct saved_context *ctxt);
+extern int software_suspend(void);
+	
+/* Suspend 2 */
+
+#define SUSPEND_DISABLED		0
+#define SUSPEND_RUNNING			1
+#define SUSPEND_RESUME_DEVICE_OK	2
+#define SUSPEND_NORESUME_SPECIFIED	3
+#define SUSPEND_COMMANDLINE_ERROR 	4
+#define SUSPEND_IGNORE_IMAGE		5
+#define SUSPEND_SANITY_CHECK_PROMPT	6
+#define SUSPEND_FREEZER_ON		7
+#define SUSPEND_DISABLE_SYNCING		8
+#define SUSPEND_BLOCK_PAGE_ALLOCATIONS	9
+#define SUSPEND_USE_MEMORY_POOL		10
+#define SUSPEND_STAGE2_CONTINUE		11
+#define SUSPEND_FREEZE_SMP		12
+#define SUSPEND_PAGESET2_NOT_LOADED	13
+#define SUSPEND_CONTINUE_REQ		14
+#define SUSPEND_RESUMED_BEFORE		15
+#define SUSPEND_RUNNING_INITRD		16
+#define SUSPEND_RESUME_NOT_DONE		17
+#define SUSPEND_BOOT_TIME		18
+#define SUSPEND_NOW_RESUMING		19
+#define SUSPEND_SLAB_ALLOC_FALLBACK	20
+#define SUSPEND_IGNORE_LOGLEVEL		21
+#define SUSPEND_TIMER_FREEZER_ON	22
+#define SUSPEND_LRU_FREEZE		23
+
+extern unsigned long software_suspend_state;
+#define test_suspend_state(bit) \
+	(test_bit(bit, &software_suspend_state))
+
+#define clear_suspend_state(bit) \
+	(clear_bit(bit, &software_suspend_state))
+
+#define set_suspend_state(bit) \
+	(set_bit(bit, &software_suspend_state))
+
+#define get_suspend_state() 		(software_suspend_state)
+#define restore_suspend_state(saved_state) \
+	do { software_suspend_state = saved_state; } while(0)
+	
+/* kernel/suspend.c */
+extern int suspend_try_suspend(void);
+extern unsigned int suspend_task;
+
+/* Kernel threads are type 3 */
+#define FREEZER_ALL_THREADS 0
+#define FREEZER_KERNEL_THREADS 3
+
+extern int freeze_processes(int no_progress);
+extern void thaw_processes(int which_threads);
+
+extern int pm_prepare_console(void);
+extern void pm_restore_console(void);
+
+#define SUSPEND_KEY_KEYBOARD 1
+#define SUSPEND_KEY_SERIAL 2
+
+struct page;
+
+struct suspend2_core_ops {
+	/* Entry points for suspending & resuming */
+	void (* do_suspend) (void);
+	int (* do_resume) (void);
+
+	/* Pre and post lowlevel routines */
+	void (* suspend1) (void);
+	void (* suspend2) (void);
+	void (* resume1) (void);
+	void (* resume2) (void);
+	
+	void (* free_pool_pages) (struct page *page, unsigned int order);
+	struct page * (* get_pool_pages) (unsigned int gfp_mask, unsigned int order);
+
+	unsigned long (* get_grabbed_pages) (int order);
+	void (* cleanup_finished_io) (void);
+
+	void (* suspend_message) (unsigned long, unsigned long, int, const char *, ...);
+	unsigned long (* update_status) (unsigned long value, unsigned long maximum,
+		const char *fmt, ...);
+	void (*prepare_status) (int printalways, int clearbar, const char *fmt, ...);
+	void (* schedule_message) (int message_number);
+	void (* early_boot_plugins) (void);
+	int (* keypress) (unsigned int keycode);
+
+	void (* verify_checksums) (void);
+};
+extern volatile struct suspend2_core_ops * suspend2_core_ops;
+#ifdef CONFIG_SOFTWARE_SUSPEND2_BUILTIN
+extern void software_suspend_try_resume(void);
+extern void suspend_handle_keypress(unsigned int keycode, int source);
+#else
+#define software_suspend_try_resume()	do { } while(0)
+#define suspend_handle_keypress(a, b) do { } while(0)
+#endif
+
+#define suspend2_free_pool_pages(page, order)	suspend2_core_ops->free_pool_pages(page, order)
+#define suspend2_get_pool_pages(mask, order)	suspend2_core_ops->get_pool_pages(mask, order)
+#define suspend2_get_grabbed_pages(order)	suspend2_core_ops->get_grabbed_pages(order)
+#define suspend2_cleanup_finished_io()		suspend2_core_ops->cleanup_finished_io()
+#define suspend2_verify_checksums()		suspend2_core_ops->verify_checksums()
+
+#else /* CONFIG_PM off */
+
+static inline int suspend_try_suspend(void)
+{
+	return -EINVAL;
+}
+
+#define suspend_task			(0)
+#define software_suspend_state		(0)
+#define test_suspend_state(bit) 	(0)
+#define clear_suspend_state(bit)	do { } while (0)
+#define set_suspend_state(bit)		do { } while(0)
+#define get_suspend_state() 		(0)
+#define restore_suspend_state(saved_state) do { } while(0)
+#define software_suspend_try_resume()	do { } while(0)
+
+static inline int suspend_bug(void)
+{
+	BUG();
+	return 0;
+}
+
+#define suspend2_free_pool_pages(page, order) suspend_bug()
+#define suspend2_get_pool_pages(mask, order) (struct page *) suspend_bug()
+#define suspend2_get_grabbed_pages(order) (struct page *) suspend_bug()
+#define suspend2_cleanup_finished_io()	do { BUG(); } while(0)
+#define suspend2_verify_checksums() do { BUG(); } while(0)
+
+static inline int software_suspend(void)
+{
+	printk("Warning: fake suspend called\n");
+	return -EPERM;
+}
+#define software_resume()		do { } while(0)
+#define suspend_handle_keypress(a, b) do { } while(0)
+#endif
 
 #endif /* _LINUX_SWSUSP_H */
diff -ruNp 822-includes-old/kernel/power/block_io.h 822-includes-new/kernel/power/block_io.h
--- 822-includes-old/kernel/power/block_io.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/block_io.h	2004-12-14 07:18:24.000000000 +1100
@@ -0,0 +1,52 @@
+/*
+ * block_io.h
+ *
+ * Copyright 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * Distributed under GPLv2.
+ *
+ * This file contains declarations for functions exported from
+ * block_io.c, which contains low level io functions.
+ */
+
+/* 8192 4k pages = 32MB */
+#define MAX_READAHEAD (int) (8192)
+
+/* Forward Declarations */
+
+struct submit_params {
+	swp_entry_t swap_address;
+	struct page * page;
+	struct block_device * dev;
+	long blocks[PAGE_SIZE/512];
+	int blocks_used;
+	int readahead_index;
+	struct submit_params * next;
+};
+
+
+extern int max_async_ios;
+#define REAL_MAX_ASYNC ((max_async_ios ? max_async_ios : 128))
+
+/* 
+ * Our exported interface so the swapwriter and NFS writer don't
+ * need these functions built in.
+ */
+struct suspend_bio_ops {
+	int (*set_block_size) (struct block_device * bdev, int size);
+	int (*get_block_size) (struct block_device * bdev);
+	int (*submit_io) (int rw, 
+		struct submit_params * submit_info, int syncio);
+	int (*bdev_page_io) (int rw, struct block_device * bdev, long pos,
+			struct page * page);
+	void (*wait_on_readahead) (int readahead_index);
+	void (*check_io_stats) (void);
+	void (*reset_io_stats) (void);
+	void (*finish_all_io) (void);
+	int (*prepare_readahead) (int index);
+	void (*cleanup_readahead) (int index);
+	struct page ** readahead_pages;
+	int (*readahead_ready) (int readahead_index);
+};
+
+extern struct suspend_bio_ops suspend_bio_ops;
diff -ruNp 822-includes-old/kernel/power/plugins.h 822-includes-new/kernel/power/plugins.h
--- 822-includes-old/kernel/power/plugins.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/plugins.h	2004-12-17 23:07:27.000000000 +1100
@@ -0,0 +1,204 @@
+/*
+ * kernel/power/plugin.h
+ *
+ * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * It contains declarations for plugins. Plugins are additions to
+ * suspend2 that provide facilities such as image compression or
+ * encryption, backends for storage of the image and user interfaces.
+ *
+ */
+
+/* This is the maximum size we store in the image header for a plugin name */
+#define SUSPEND_MAX_PLUGIN_NAME_LENGTH 30
+
+struct plugin_header {
+	char name[SUSPEND_MAX_PLUGIN_NAME_LENGTH];
+	int disabled;
+	int type;
+	int index;
+	int data_length;
+	unsigned long magic;
+};
+
+extern unsigned long memory_for_plugins(void);
+extern int num_plugins;
+
+#define FILTER_PLUGIN 1
+#define WRITER_PLUGIN 2
+#define UI_PLUGIN 3
+#define MISC_PLUGIN 4 // Block writer, eg.
+#define CHECKSUM_PLUGIN 5
+
+#define SUSPEND_ASYNC 0
+#define SUSPEND_SYNC  1
+
+#define SUSPEND_COMMON_IO_OPS \
+	/* Writing the image proper */ \
+	int (*write_chunk) (struct page * buffer_page); \
+\
+	/* Reading the image proper */ \
+	int (*read_chunk) (struct page * buffer_page, int sync); \
+\
+	/* Reset plugin if image exists but reading aborted */ \
+	void (*noresume_reset) (void);
+
+struct suspend_filter_ops {
+	SUSPEND_COMMON_IO_OPS
+	int (*expected_compression) (void);
+	struct list_head filter_list;
+};
+
+struct suspend_writer_ops {
+	
+	SUSPEND_COMMON_IO_OPS
+
+	/* Calls for allocating storage */
+
+	long (*storage_available) (void); // Maximum size of image we can save
+					  // (incl. space already allocated).
+	
+	unsigned long (*storage_allocated) (void);
+					// Amount of storage already allocated
+	int (*release_storage) (void);
+	
+	/* 
+	 * Header space is allocated separately. Note that allocation
+	 * of space for the header might result in allocated space 
+	 * being stolen from the main pool if there is no unallocated
+	 * space. We have to be able to allocate enough space for
+	 * the header. We can eat memory to ensure there is enough
+	 * for the main pool.
+	 */
+	long (*allocate_header_space) (unsigned long space_requested);
+	int (*allocate_storage) (unsigned long space_requested);
+	
+	/* Read and write the metadata */	
+	int (*write_header_init) (void);
+	int (*write_header_chunk) (char * buffer_start, int buffer_size);
+	int (*write_header_cleanup) (void);
+
+	int (*read_header_init) (void);
+	int (*read_header_chunk) (char * buffer_start, int buffer_size);
+	int (*read_header_cleanup) (void);
+
+	/* Prepare metadata to be saved (relativise/absolutise extents) */
+	int (*prepare_save_extents) (void);
+	int (*post_load_extents) (void);
+	
+	/* Attempt to parse an image location */
+	int (*parse_image_location) (char * buffer, int only_writer);
+
+	/* Determine whether image exists that we can restore */
+	int (*image_exists) (void);
+	
+	/* Mark the image as having tried to resume */
+	void (*mark_resume_attempted) (void);
+
+	/* Destroy image if one exists */
+	int (*invalidate_image) (void);
+	
+	/* Wait on I/O */
+	int (*wait_on_io) (int flush_all);
+
+	struct list_head writer_list;
+};
+
+struct suspend_ui_ops {
+	void (*early_boot_message_prep) (void);
+	void (*prepare) (void);
+	void (*message) (
+		unsigned long type, unsigned long level,
+		int normally_logged,
+		const char *format, va_list args);
+	void (*log_level_change) (void);
+	unsigned long (*update_progress) (
+		unsigned long value, unsigned long maximum,
+		const char *fmt, va_list args);
+	void (*cleanup) (void);
+	int (*keypress) (unsigned int key);
+	void (*post_kernel_restore_redraw) (void);
+
+	struct list_head ui_list;
+};
+
+struct suspend_checksum_ops {
+	void (*calculate_checksums) (void);
+	void (*check_checksums) (void);
+	void (*print_differences) (void);
+	int (*allocate_pages) (void);
+};
+
+struct suspend_plugin_ops {
+	/* Functions common to all plugins */
+	int type;
+	char * name;
+	int disabled;
+	struct list_head plugin_list;
+	unsigned long (*memory_needed) (void);
+	unsigned long (*storage_needed) (void);
+	int (*print_debug_info) (char * buffer, int size);
+	int (*save_config_info) (char * buffer);
+	void (*load_config_info) (char * buffer, int len);
+	
+	/* Initialise & cleanup - general routines called
+	 * at the start and end of a cycle. */
+	int (*initialise) (void);
+	void (*cleanup) (void);
+
+	int (*write_init) (int stream_number); \
+	int (*write_cleanup) (void); \
+
+	int (*read_init) (int stream_number); \
+	int (*read_cleanup) (void); \
+
+	union {
+		struct suspend_filter_ops filter;
+		struct suspend_writer_ops writer;
+		struct suspend_ui_ops ui;
+		struct suspend_checksum_ops checksum;
+	} ops;
+};
+
+extern struct suspend_plugin_ops * active_writer;
+extern struct list_head suspend_filters, suspend_writers, suspend_plugins, suspend_ui;
+extern struct suspend_plugin_ops * checksum_plugin;
+extern void prepare_console_plugins(void);
+extern void cleanup_console_plugins(void);
+extern struct suspend_plugin_ops * find_plugin_given_name(char * name);
+extern struct suspend_plugin_ops * get_next_filter(struct suspend_plugin_ops *);
+extern int suspend_register_plugin(struct suspend_plugin_ops * plugin);
+extern void suspend_move_plugin_tail(struct suspend_plugin_ops * plugin);
+
+extern int initialise_suspend_plugins(void);
+extern void cleanup_suspend_plugins(void);
+extern unsigned long header_storage_for_plugins(void);
+extern unsigned long memory_for_plugins(void);
+extern int print_plugin_debug_info(char * buffer, int buffer_size);
+extern int suspend_register_plugin(struct suspend_plugin_ops * plugin);
+extern void suspend_unregister_plugin(struct suspend_plugin_ops * plugin);
+extern int initialise_suspend_plugins(void);
+extern void cleanup_suspend_plugins(void);
+extern void suspend_post_restore_redraw(void);
+
+static inline void suspend_checksum_calculate_checksums(void)
+{
+	if (checksum_plugin)
+		checksum_plugin->ops.checksum.calculate_checksums();
+}
+
+static inline void suspend_checksum_print_differences(void)
+{
+	if (checksum_plugin)
+		checksum_plugin->ops.checksum.print_differences();
+}
+
+static inline int suspend_allocate_checksum_pages(void)
+{
+	if (checksum_plugin)
+		return checksum_plugin->ops.checksum.allocate_pages();
+	else
+		return 0;
+}
diff -ruNp 822-includes-old/kernel/power/power.h 822-includes-new/kernel/power/power.h
--- 822-includes-old/kernel/power/power.h	2004-12-24 10:38:19.302253856 +1100
+++ 822-includes-new/kernel/power/power.h	2004-12-14 07:18:24.000000000 +1100
@@ -1,6 +1,8 @@
 #include <linux/suspend.h>
 #include <linux/utsname.h>
 
+#include "suspend.h"
+
 /* With SUSPEND_CONSOLE defined, it suspend looks *really* cool, but
    we probably do not take enough locks for switching consoles, etc,
    so bad things might happen.
diff -ruNp 822-includes-old/kernel/power/proc.h 822-includes-new/kernel/power/proc.h
--- 822-includes-old/kernel/power/proc.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/proc.h	2004-12-14 07:18:24.000000000 +1100
@@ -0,0 +1,64 @@
+/*
+ * kernel/power/proc.h
+ *
+ * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * It provides declarations for suspend to use in managing
+ * /proc/software_suspend. When we switch to kobjects,
+ * this will become redundant.
+ *
+ */
+
+struct suspend_proc_data {
+	char * filename;
+	int permissions;
+	int type;
+	union {
+		struct {
+			unsigned long * bit_vector;
+			int bit;
+		} bit;
+		struct {
+			int * variable;
+			int minimum;
+			int maximum;
+		} integer;
+		struct {
+			unsigned long * variable;
+			unsigned long minimum;
+			unsigned long maximum;
+		} ul;
+		struct {
+			char * variable;
+			int max_length;
+		} string;
+		struct {
+			void * read_proc;
+			void * write_proc;
+			void * data;
+		} special;
+	} data;
+	
+	/* Side effects routines. Used, eg, for reparsing the
+	 * resume2 entry when it changes */
+	int (* read_proc) (void);
+	int (* write_proc) (void); 
+	struct list_head proc_data_list;
+};
+
+#define SUSPEND_PROC_DATA_CUSTOM	0
+#define SUSPEND_PROC_DATA_BIT		1
+#define SUSPEND_PROC_DATA_INTEGER	2
+#define SUSPEND_PROC_DATA_UL		3
+#define SUSPEND_PROC_DATA_STRING	4
+
+#define PROC_WRITEONLY 0200
+#define PROC_READONLY 0400
+#define PROC_RW 0600
+
+struct proc_dir_entry * suspend_register_procfile(
+		struct suspend_proc_data * suspend_proc_data);
+void suspend_unregister_procfile(struct suspend_proc_data * suspend_proc_data);
+
diff -ruNp 822-includes-old/kernel/power/smp.c 822-includes-new/kernel/power/smp.c
--- 822-includes-old/kernel/power/smp.c	2004-11-03 21:55:01.000000000 +1100
+++ 822-includes-new/kernel/power/smp.c	2004-12-14 07:18:24.000000000 +1100
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <asm/atomic.h>
 #include <asm/tlbflush.h>
+#include "suspend.h"
 
 static atomic_t cpu_counter, freeze;
 
diff -ruNp 822-includes-old/kernel/power/suspend2_core/debug.h 822-includes-new/kernel/power/suspend2_core/debug.h
--- 822-includes-old/kernel/power/suspend2_core/debug.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/suspend2_core/debug.h	2004-12-14 07:18:24.000000000 +1100
@@ -0,0 +1,66 @@
+/*
+ */
+
+#include "suspend.h" 	/* for real_nr_free_pages() */
+
+#ifdef CONFIG_SOFTWARE_SUSPEND_DEBUG
+
+#define MAX_FREEMEM_SLOTS 26
+enum {
+	SUSPEND_FREE_BASE,
+	SUSPEND_FREE_CONSOLE_ALLOC,
+	SUSPEND_FREE_DRAIN_PCP,
+	SUSPEND_FREE_IN_USE_MAP,
+	SUSPEND_FREE_PS1_MAP,
+	SUSPEND_FREE_PS1COPY_MAP,
+	SUSPEND_FREE_PS2_MAP,
+	SUSPEND_FREE_ALLOCD_PAGES_MAP,
+	SUSPEND_FREE_CHECKSUM_MAP,
+	SUSPEND_FREE_UNMAP_MAP,
+	SUSPEND_FREE_RELOAD_PAGES,
+	SUSPEND_FREE_INIT_PLUGINS,
+	SUSPEND_FREE_FREEZER,
+	SUSPEND_FREE_EAT_MEMORY,
+	SUSPEND_FREE_SYNC,
+	SUSPEND_FREE_GRABBED_MEMORY,
+	SUSPEND_FREE_EXTENT_PAGES,
+	SUSPEND_FREE_EXTRA_PD1,
+	SUSPEND_FREE_WRITER_STORAGE,
+	SUSPEND_FREE_HEADER_STORAGE,
+	SUSPEND_FREE_CHECKSUM_PAGES,
+	SUSPEND_FREE_KSTAT,
+	SUSPEND_FREE_DEBUG_INFO,
+	SUSPEND_FREE_INVALIDATE_IMAGE,
+	SUSPEND_FREE_IO,
+	SUSPEND_FREE_IO_INFO,
+	SUSPEND_FREE_START_ONE
+};
+
+extern void show_pcp_lists(void);
+extern void suspend_store_free_mem(int slot, int side);
+extern void suspend_display_free_mem(void);
+
+#define cond_show_pcp_lists() \
+do { \
+	if (TEST_DEBUG_STATE(SUSPEND_FREEZER)) \
+		show_pcp_lists(); \
+} while(0)
+
+#define MDELAY(a) do { if (TEST_ACTION_STATE(SUSPEND_SLOW)) mdelay(a); } \
+	while (0)
+
+#define PRINTFREEMEM(desn) \
+	suspend_message(SUSPEND_MEMORY, SUSPEND_HIGH, 1, \
+		"Free memory %s: %d.\n", desn, \
+		real_nr_free_pages() + suspend_amount_grabbed);
+
+
+#else	/* ! CONFIG_SOFTWARE_SUSPEND_DEBUG */
+
+#define cond_show_pcp_lists() do { } while(0)
+#define suspend_store_free_mem(slot, side) do { } while (0)
+#define suspend_display_free_mem() do { } while (0)
+#define MDELAY(a) do { } while (0)
+#define PRINTFREEMEM(desn) do { } while(0)
+#endif
+
diff -ruNp 822-includes-old/kernel/power/suspend2_core/driver_model.h 822-includes-new/kernel/power/suspend2_core/driver_model.h
--- 822-includes-old/kernel/power/suspend2_core/driver_model.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/suspend2_core/driver_model.h	2004-12-14 07:18:24.000000000 +1100
@@ -0,0 +1,23 @@
+/*
+ * kernel/power/driver_model.h
+ *
+ * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * Support for the driver model.
+ */
+
+/*	suspend_drivers_resume
+ *	@stage - One of...
+ */
+
+enum {
+	SUSPEND_DRIVERS_IRQS_DISABLED,
+	SUSPEND_DRIVERS_IRQS_ENABLED,
+};
+
+extern int suspend_drivers_init(void);
+extern int suspend_drivers_suspend(int stage);
+extern void suspend_drivers_resume(int stage);
+extern void suspend_drivers_cleanup(void);
diff -ruNp 822-includes-old/kernel/power/suspend2_core/extent.h 822-includes-new/kernel/power/suspend2_core/extent.h
--- 822-includes-old/kernel/power/suspend2_core/extent.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/suspend2_core/extent.h	2004-12-24 09:47:32.980365176 +1100
@@ -0,0 +1,103 @@
+/*
+ * kernel/power/extent.h
+ *
+ * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * It contains declarations related to extents. Extents are
+ * suspend's method of storing some of the metadata for the image.
+ * See extent.c for more info.
+ *
+ */
+
+struct extentchain {
+	struct extent * first;
+	struct extent * last;
+	int size; /* size of the extent ie sum (max-min+1) */
+	int allocs;
+	int frees;
+	int debug;
+	int timesusedoptimisation;
+	char * name;
+	struct extent * lastaccessed, *prevtolastaccessed, *prevtoprev;
+};
+
+/*
+ * We rely on extents not fitting evenly into a page.
+ * The last four bytes are used to store the number
+ * of the page, to make saving & reloading pages simpler.
+ */
+struct extent {
+	unsigned long minimum;
+	unsigned long maximum;
+	struct extent * next;
+};
+
+
+#define EXTENTS_PER_PAGE (PAGE_SIZE / (sizeof(struct extent)))
+#define EXTENTPAGELINK(x) ((unsigned long *) \
+		((((unsigned long) x) & PAGE_MASK) + PAGE_SIZE - \
+		 sizeof(unsigned long)))
+
+#define extent_for_each(extentchain, extentpointer, value) \
+if ((extentchain)->first) \
+	for ((extentpointer) = (extentchain)->first, (value) = \
+			(extentpointer)->minimum; \
+	     ((extentpointer) && ((extentpointer)->next || (value) <= \
+				 (extentpointer)->maximum)); \
+	     (((value) == (extentpointer)->maximum) ? \
+		((extentpointer) = (extentpointer)->next, (value) = \
+		 ((extentpointer) ? (extentpointer)->minimum : 0)) : \
+			(value)++))
+
+/*
+ * When using compression and expected_compression > 0,
+ * we allocate fewer swap entries, so GET_EXTENT_NEXT can
+ * validly run out of data to return.
+ */
+#define GET_EXTENT_NEXT(currentextent, currentval) \
+{ \
+	if (currentextent) { \
+		if ((currentval) == (currentextent)->maximum) { \
+			if ((currentextent)->next) { \
+				(currentextent) = (currentextent)->next; \
+				(currentval) = (currentextent)->minimum; \
+			} else { \
+				(currentextent) = NULL; \
+				(currentval) = 0; \
+			} \
+		} else \
+			currentval++; \
+	} \
+}
+
+extern int max_extents_used;
+extern int num_extent_pages;
+int add_to_extent_chain(struct extentchain * chain, unsigned long value);
+void put_extent_chain(struct extentchain * chain);
+void print_chain(int debuglevel, struct extentchain * chain, int printasswap);
+int free_extents(void);
+int append_to_extent_chain(int chain, unsigned long min, unsigned long max);
+void relativise_extents(void);
+void relativise_chain(struct extentchain * chain);
+void absolutise_extents(void);
+void absolutise_chain(struct extentchain * chain);
+unsigned long * get_extentpages_list_entry(int index);
+int relocate_extentpages(void);
+
+extern struct extent * first_extent_page, * last_extent_page;
+
+#define EXTENT_RELATIVE(x) (struct extent *) ((((unsigned long) x) & \
+			(PAGE_SIZE - 1)) | \
+		((*EXTENTPAGELINK(x) & (PAGE_SIZE - 1)) << PAGE_SHIFT))
+#define EXTENT_ABSOLUTE(entry) (struct extent *) \
+	((((unsigned long) (entry)) & (PAGE_SIZE - 1)) | \
+	 (unsigned long) get_extentpages_list_entry(((unsigned long) (entry)) >> PAGE_SHIFT))
+
+/* swap_entry_to_extent_val & extent_val_to_swap_entry: 
+ * We are putting offset in the low bits so consecutive swap entries
+ * make consecutive extent values */
+#define swap_entry_to_extent_val(swp_entry) (swp_entry.val)
+#define extent_val_to_swap_entry(val) (swp_entry_t) { (val) }
+
diff -ruNp 822-includes-old/kernel/power/suspend2_core/pagedir.h 822-includes-new/kernel/power/suspend2_core/pagedir.h
--- 822-includes-old/kernel/power/suspend2_core/pagedir.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/suspend2_core/pagedir.h	2004-12-14 07:18:24.000000000 +1100
@@ -0,0 +1,67 @@
+/*
+ * kernel/power/suspend2_core/pagedir.h
+ *
+ * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * Declarations for routines for handling pagesets.
+ * Note that pbes aren't actually stored as such. The data is stored in
+ * bitmaps.
+ */
+
+/* Page Backup Entry.
+ *
+ * This is an abstraction which contains the data for one
+ * page of the image. (The data is really stored in extents).
+ */
+
+#ifndef SUSPEND2_CORE_PAGEDIR_H
+#define SUSPEND2_CORE_PAGEDIR_H
+
+struct pbe2 {
+	struct page * origaddress;	/* Original address of page */
+	struct page * address;		/* Address of copy of page */
+	int current_orig_index;
+	int current_dest_index;
+
+	struct pagedir * pagedir;
+};
+
+/* Pagedir
+ *
+ * Contains the metadata for a set of pages saved in the image.
+ */
+struct pagedir {
+	int pagedir_num;
+	int pageset_size;
+	int lastpageset_size;
+};
+
+#define pageset1_size (pagedir1.pageset_size)
+#define pageset2_size (pagedir2.pageset_size)
+
+/* Pagedir_resume is pagedir1, loaded back in at the beginning
+ * of resuming and relocated so we can do our atomic restoration
+ * of the original kernel.
+ * Pagedir1 is the metadata for pageset 1 pages. Ditto for pageset 2.
+ */
+extern struct pagedir pagedir_resume __nosavedata;
+extern struct pagedir pagedir1, pagedir2;
+
+extern void copy_pageset1(void);
+#ifdef CONFIG_DEBUG_PAGEALLOC
+extern void suspend_map_atomic_copy_pages(void);
+extern void suspend_unmap_atomic_copy_pages(void);
+#endif
+extern void free_pagedir_data(void);
+extern int PageInPagedir(struct pagedir * p, struct page * page);
+extern int allocate_extra_pagedir_memory(struct pagedir * p,
+		int pageset_size, int alloc_from);
+extern void mark_pages_for_pageset2(void);
+extern unsigned long get_nonconflicting_page(void);
+extern void release_conflicting_pages(void);
+extern void relocate_page_if_required(void ** page_pointer_addr);
+extern int get_pageset1_load_addresses(void);
+extern void set_chain_names(struct pagedir * p);
+#endif
diff -ruNp 822-includes-old/kernel/power/suspend2_core/pageflags.h 822-includes-new/kernel/power/suspend2_core/pageflags.h
--- 822-includes-old/kernel/power/suspend2_core/pageflags.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/suspend2_core/pageflags.h	2004-12-14 07:18:24.000000000 +1100
@@ -0,0 +1,122 @@
+/*
+ * kernel/power/pageflags.h
+ *
+ * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * Suspend2 needs a few pageflags while working that aren't otherwise
+ * used. To save the struct page pageflags, we dynamically allocate
+ * a bitmap and use that. These are the only non order-0 allocations
+ * we do.
+ *
+ * NOTE!!!
+ * We assume that PAGE_SIZE - sizeof(void *) is a multiple of
+ * sizeof(unsigned long). Is this ever false?
+ */
+
+extern unsigned long ** in_use_map;
+extern unsigned long ** pageset1_map;
+extern unsigned long ** pageset1_copy_map;
+extern unsigned long ** pageset2_map;
+extern unsigned long ** allocd_pages_map;
+extern unsigned long ** checksum_map;
+#ifdef CONFIG_DEBUG_PAGEALLOC
+extern unsigned long ** unmap_map;
+#endif
+
+#define BITNUMBER(page) (page_to_pfn(page))
+
+#define PAGEBIT(page) ((int) ((page_to_pfn(page))%(8 * sizeof(unsigned long))))
+
+#define BITS_PER_PAGE (PAGE_SIZE * 8)
+#define PAGES_PER_BITMAP ((max_mapnr + BITS_PER_PAGE - 1) / BITS_PER_PAGE)
+#define PAGENUMBER(page) (BITNUMBER(page) / BITS_PER_PAGE)
+
+#define PAGEINDEX(page) ((BITNUMBER(page) - (BITS_PER_PAGE * PAGENUMBER(page)))/(8*sizeof(unsigned long)))
+
+#define PAGE_UL_PTR(bitmap, pagenum) ((bitmap[PAGENUMBER(pagenum)])+PAGEINDEX(pagenum))
+
+/* 
+ * freepagesmap is used in two ways: 
+ * - During suspend, to tag pages which are not used (to speed up 
+ *   count_data_pages);
+ * - During resume, to tag pages which are in pagedir1. This does not tag 
+ *   pagedir2 pages, so !== first use.
+ */
+#define PageInUse(page)	\
+	test_bit(PAGEBIT(page), PAGE_UL_PTR(in_use_map, page))
+#define SetPageInUse(page) \
+	set_bit(PAGEBIT(page), PAGE_UL_PTR(in_use_map, page))
+#define ClearPageInUse(page) \
+	clear_bit(PAGEBIT(page), PAGE_UL_PTR(in_use_map, page))
+
+#define PagePageset1(page) \
+	(pageset1_map ? test_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_map, page)): 0)
+#define SetPagePageset1(page) \
+	set_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_map, page))
+#define ClearPagePageset1(page) \
+	clear_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_map, page))
+
+#define PagePageset1Copy(page) \
+	(pageset1_copy_map ? test_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_copy_map, page)): 0)
+#define SetPagePageset1Copy(page) \
+	set_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_copy_map, page))
+#define ClearPagePageset1Copy(page) \
+	clear_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_copy_map, page))
+
+#define PagePageset2(page) \
+	(pageset2_map ? test_bit(PAGEBIT(page), PAGE_UL_PTR(pageset2_map, page)): 0)
+#define SetPagePageset2(page) \
+	set_bit(PAGEBIT(page), PAGE_UL_PTR(pageset2_map, page))
+#define ClearPagePageset2(page) \
+	clear_bit(PAGEBIT(page), PAGE_UL_PTR(pageset2_map, page))
+
+#define PageAllocd(page)	\
+	test_bit(PAGEBIT(page), PAGE_UL_PTR(allocd_pages_map, page))
+#define SetPageAllocd(page) \
+	set_bit(PAGEBIT(page), PAGE_UL_PTR(allocd_pages_map, page))
+#define ClearPageAllocd(page) \
+	clear_bit(PAGEBIT(page), PAGE_UL_PTR(alloc_pages_map, page))
+
+#define PageChecksumIgnore(page) \
+	(checksum_map ? test_bit(PAGEBIT(page), PAGE_UL_PTR(checksum_map, page)) : 0)
+
+#define SetPageChecksumIgnore(page) \
+do { \
+	if (checksum_map) \
+		set_bit(PAGEBIT(page), PAGE_UL_PTR(checksum_map, page)); \
+} while(0)
+
+#define ClearPageChecksumIgnore(page) \
+do { \
+	if (checksum_map) \
+		clear_bit(PAGEBIT(page), PAGE_UL_PTR(checksum_map, page)); \
+} while(0)
+
+
+#define SetPageUnmap(page) \
+	set_bit(PAGEBIT(page), PAGE_UL_PTR(unmap_map, page))
+#define PageUnmap(page) \
+	test_bit(PAGEBIT(page), PAGE_UL_PTR(unmap_map, page))
+
+static inline int __get_next_bit_on(unsigned long ** bitmap, int counter)
+{
+	do {
+		counter++;
+	} while(!test_bit(PAGEBIT(mem_map + counter),
+			PAGE_UL_PTR(bitmap, mem_map + counter)) &&
+			counter < max_mapnr);
+	return counter;
+}
+
+#define BITMAP_FOR_EACH_SET(bitmap, counter) \
+	for (counter = __get_next_bit_on(bitmap, -1); counter < max_mapnr; \
+		counter = __get_next_bit_on(bitmap, counter))
+
+extern void clear_map(unsigned long ** pagemap);
+extern int allocate_local_pageflags(unsigned long *** pagemap);
+extern int free_local_pageflags(unsigned long *** pagemap);
+extern void save_local_pageflags(unsigned long ** pagemap);
+extern void load_local_pageflags(unsigned long ** pagemap);
+void relocate_local_pageflags(unsigned long ***pagemap);
diff -ruNp 822-includes-old/kernel/power/suspend2_core/suspend.h 822-includes-new/kernel/power/suspend2_core/suspend.h
--- 822-includes-old/kernel/power/suspend2_core/suspend.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/suspend2_core/suspend.h	2004-12-14 07:18:24.000000000 +1100
@@ -0,0 +1,162 @@
+/*
+ * kernel/power/suspend2.h
+ *
+ * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * It contains declarations used throughout swsusp and suspend2.
+ *
+ */
+#ifndef KERNEL_POWER_SUSPEND_CORE_H
+#define KERNEL_POWER_SUSPEND_CORE_H
+
+#include <linux/delay.h>
+#include "extent.h"
+#include "pagedir.h"
+
+/* ---------------------------- Suspend2 -------------------------------- */
+
+/* Non-plugin data saved in our image header */
+struct suspend_header {
+	u32 version_code;
+	unsigned long num_physpages;
+	char machine[65];
+	char version[65];
+	int num_cpus;
+	int page_size;
+	unsigned long orig_mem_free;
+	int num_extent_pages;
+	struct extent * unused_extents;
+	int pageset_2_size;
+	int param0;
+	int param1;
+	int param2;
+	int param3;
+	int param4;
+	int progress0;
+	int progress1;
+	int progress2;
+	int progress3;
+	int io_time[2][2];
+	
+	/* Implementation specific variables */
+#ifdef KERNEL_POWER_SWSUSP_C
+	suspend_pagedir_t *suspend_pagedir;
+	unsigned int num_pbes;
+#else
+	struct pagedir pagedir;
+#endif
+};
+
+extern void schedule_suspend_message(int message_number);
+extern int suspend_min_free;
+
+extern void save_avenrun_values(void);
+extern void restore_avenrun_values(void);
+
+#define SWAP_FILENAME_MAXLENGTH	32
+
+extern int suspend_default_console_level;
+extern int max_async_ios;
+extern int image_size_limit;
+
+struct pageset_sizes_result {
+	int size1; /* Can't be unsigned - breaks MAX function */
+	int size1low;
+	int size2;
+	int size2low;
+	int needmorespace;
+};
+
+#define MB(x) ((x) >> (20 - PAGE_SHIFT))
+
+extern int suspend_amount_grabbed;
+extern unsigned long get_max_low_pfn(void);
+
+/*
+ * XXX: We try to keep some more pages free so that I/O operations succeed
+ * without paging. Might this be more?
+ */
+#define MIN_FREE_RAM (get_max_low_pfn() >> 7)
+
+extern void prepare_status(int printalways, int clearbar, const char *fmt, ...);
+extern void abort_suspend(const char *fmt, ...);
+
+extern int suspend_snprintf(char * buffer, int buffer_size,
+		const char *fmt, ...);
+
+/* ------ prepare_image.c ------ */
+extern unsigned long get_grabbed_pages(int order);
+
+/* ------ io.c ------ */
+int suspend_early_boot_message(int can_erase_image, int default_answer, 
+		char *reason, ...);
+
+/* ------ console.c ------ */
+void check_shift_keys(int pause, char * message);
+unsigned long update_status(unsigned long value, unsigned long maximum,
+		const char *fmt, ...);
+
+extern int expected_compression_ratio(void);
+
+#define MAIN_STORAGE_NEEDED(USE_ECR) \
+	((pageset1_size + pageset2_size) * \
+	 (USE_ECR ? expected_compression_ratio() : 100) / 100)
+
+#define HEADER_BYTES_NEEDED \
+	((num_extent_pages << PAGE_SHIFT) + \
+	 sizeof(struct suspend_header) + \
+	 sizeof(struct plugin_header) + \
+	 (int) header_storage_for_plugins() + \
+	 (PAGES_PER_BITMAP << PAGE_SHIFT) + \
+	 num_plugins * \
+	 	(sizeof(struct plugin_header) + sizeof(int)))
+	
+#define HEADER_STORAGE_NEEDED ((HEADER_BYTES_NEEDED + (int) PAGE_SIZE - 1) >> PAGE_SHIFT)
+
+#define STORAGE_NEEDED(USE_ECR) \
+	(MAIN_STORAGE_NEEDED(USE_ECR) + HEADER_STORAGE_NEEDED)
+
+#define RAM_TO_SUSPEND (1 + max((pageset1_size - pageset2_sizelow), 0) + \
+		MIN_FREE_RAM + memory_for_plugins())
+
+extern int expected_compression_ratio(void);
+int print_module_list_to_buffer(char * buffer, int size);
+
+extern unsigned int nr_suspends;
+extern char resume2_file[];
+
+extern int suspend_wait_for_keypress(void);
+
+#ifdef CONFIG_SMP
+extern void smp_suspend(void);
+extern void smp_continue(void);
+#else
+#define smp_suspend() do { } while(0)
+#define smp_continue() do { } while(0)
+#endif
+
+extern struct pm_ops * pm_ops;
+extern dev_t name_to_dev_t(char *line);
+extern char _text[], _etext[], _edata[], __bss_start[], _end[];
+extern void signal_wake_up(struct task_struct *t, int resume);
+
+extern struct partial_device_tree * suspend_device_tree;
+
+/* Returns whether it was already in the requested state */
+extern int suspend_map_kernel_page(struct page * page, int enable);
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+extern void suspend_map_atomic_copy_pages(void);
+extern void suspend_unmap_atomic_copy_pages(void);
+#else
+#define suspend_map_atomic_copy_pages() do { } while(0)
+#define suspend_unmap_atomic_copy_pages() do { } while(0)
+#endif
+
+extern unsigned long suspend_powerdown_method;
+extern int attempt_to_parse_resume_device(void);
+
+extern int real_nr_free_pages(void);
+#endif
diff -ruNp 822-includes-old/kernel/power/suspend2_core/version.h 822-includes-new/kernel/power/suspend2_core/version.h
--- 822-includes-old/kernel/power/suspend2_core/version.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/suspend2_core/version.h	2004-12-24 10:02:50.500880856 +1100
@@ -0,0 +1,5 @@
+#define SUSPEND_CORE_VERSION "2.1.5.10"
+#ifndef KERNEL_POWER_SWSUSP_C
+#define name_suspend "Software Suspend " SUSPEND_CORE_VERSION ": "
+#endif
+
diff -ruNp 822-includes-old/kernel/power/suspend.h 822-includes-new/kernel/power/suspend.h
--- 822-includes-old/kernel/power/suspend.h	1970-01-01 10:00:00.000000000 +1000
+++ 822-includes-new/kernel/power/suspend.h	2004-12-14 07:18:24.000000000 +1100
@@ -0,0 +1,37 @@
+/*
+ * kernel/power/suspend.h
+ *
+ * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * It contains declarations used throughout swsusp.
+ *
+ */
+
+#ifndef KERNEL_POWER_SUSPEND_H
+#define KERNEL_POWER_SUSPEND_H
+
+typedef struct pbe {
+	unsigned long address;		/* address of the copy */
+	unsigned long orig_address;	/* original address of page */
+	swp_entry_t swap_address;	
+	swp_entry_t dummy;		/* we need scratch space at 
+					 * end of page (see link, diskpage)
+					 */
+} suspend_pagedir_t;
+
+#define SUSPEND_PD_PAGES(x)     (((x)*sizeof(struct pbe))/PAGE_SIZE+1)
+   
+/* mm/page_alloc.c */
+extern void drain_local_pages(void);
+
+void save_processor_state(void);
+void restore_processor_state(void);
+struct saved_context;
+void __save_processor_state(struct saved_context *ctxt);
+void __restore_processor_state(struct saved_context *ctxt);
+
+extern suspend_pagedir_t *pagedir_nosave __nosavedata;
+
+#endif
diff -ruNp 822-includes-old/kernel/power/swsusp.c 822-includes-new/kernel/power/swsusp.c
--- 822-includes-old/kernel/power/swsusp.c	2004-12-24 10:38:19.101284408 +1100
+++ 822-includes-new/kernel/power/swsusp.c	2004-12-14 07:18:24.000000000 +1100
@@ -36,6 +36,8 @@
  * For TODOs,FIXMEs also look in Documentation/power/swsusp.txt
  */
 
+#define KERNEL_POWER_SWSUSP_C
+
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/suspend.h>
@@ -51,9 +53,7 @@
 #include <linux/keyboard.h>
 #include <linux/spinlock.h>
 #include <linux/genhd.h>
-#include <linux/kernel.h>
 #include <linux/major.h>
-#include <linux/swap.h>
 #include <linux/pm.h>
 #include <linux/device.h>
 #include <linux/buffer_head.h>
@@ -70,9 +70,7 @@
 #include <asm/io.h>
 
 #include "power.h"
-
-/* References to section boundaries */
-extern char __nosave_begin, __nosave_end;
+#include "suspend.h"
 
 extern int is_head_of_free_region(struct page *);
 
