diff -ruNp 851-suspend-bootsplash-old/kernel/power/suspend_bootsplash.c 851-suspend-bootsplash-new/kernel/power/suspend_bootsplash.c
--- 851-suspend-bootsplash-old/kernel/power/suspend_bootsplash.c	1970-01-01 10:00:00.000000000 +1000
+++ 851-suspend-bootsplash-new/kernel/power/suspend_bootsplash.c	2004-12-03 21:27:44.000000000 +1100
@@ -0,0 +1,317 @@
+/*
+ * kernel/power/suspend2_bootsplash.c
+ *
+ * Copyright (C) 2004 Nigel Cunningham <ncunningham@linuxmail.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ * This file implements bootsplash support for suspend2.
+ */
+#define SUSPEND_CONSOLE_C
+
+#define __KERNEL_SYSCALLS__
+
+#include <linux/suspend.h>
+#include <linux/console.h>
+#include <linux/proc_fs.h>
+#include <linux/hardirq.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include "../../../drivers/video/console/fbcon.h"
+
+#include <asm/hardirq.h>
+
+#include "plugins.h"
+#include "proc.h"
+#include "suspend.h"
+
+static int barwidth = 100, barposn = -1, newbarposn = 0;
+static int lastloglevel = -1;
+
+/* Your bootsplash progress bar may have a width of (eg) 1024 pixels. That
+ * doesn't necessarily mean you want the bar updated 1024 times when writing
+ * the image */
+static int bar_granularity_limit = 0;
+
+/* ------------------  Splash screen defines  -------------------------- */
+
+extern struct display fb_display[MAX_NR_CONSOLES];
+
+static inline struct splash_data * get_splash_data(int consolenr)
+{
+	BUG_ON(consolenr >= MAX_NR_CONSOLES);
+
+	if (vc_cons[consolenr].d)
+		return vc_cons[consolenr].d->vc_splash_data;
+	
+	return NULL;
+}
+/* splash_is_on
+ * 
+ * Description: Determine whether a VT has a splash screen on.
+ * Arguments:	int consolenr. The VT number of a console to check.
+ * Returns:	Boolean indicating whether the splash screen for
+ *		that console is on right now.
+ */
+static int splash_is_on(int consolenr)
+{
+	struct splash_data *info = get_splash_data(consolenr);
+
+	if (info)
+		return ((info->splash_state & 1) == 1);
+	return 0;
+}
+
+/* splash_write_proc.
+ *
+ * Write to Bootsplash's proc entry. We need this to work when /proc
+ * hasn't been mounted yet and / can't be mounted. In addition, we
+ * want it to work despite the fact that bootsplash (under 2.4 at least)
+ * removes its proc entry when it shouldn't.  We therefore use
+ * our proc.c find_proc_dir_entry routine to get the location of the
+ * write routine once (boot time & at start of each resume), and keep it.
+ */
+
+extern struct proc_dir_entry * find_proc_dir_entry(const char *name,
+	struct proc_dir_entry *parent);
+
+static void splash_write_proc(const char *buffer, unsigned long count)
+{
+	static write_proc_t * write_routine;
+	struct proc_dir_entry * proc_entry;
+
+	if (in_interrupt())
+		return;
+
+	if (unlikely(!write_routine)) {
+		proc_entry = find_proc_dir_entry("splash", &proc_root);
+		if (proc_entry)
+			write_routine = proc_entry->write_proc;
+	}
+        
+	if (write_routine)
+                write_routine(NULL, buffer, count, NULL);
+}
+
+/* fb_splash-set_progress
+ *
+ * Description:	Set the progress bar position for a splash screen.
+ * Arguments:	int consolenr. The VT number of a console to use.
+ * 		unsigned long value, unsigned long maximum:
+ * 		The proportion (value/maximum) of the bar to fill.
+ */
+
+static int fb_splash_set_progress(int consolenr, unsigned long value,
+	unsigned long maximum)
+{
+	char procstring[15];
+	int length, bitshift = generic_fls(maximum) - 16;
+	static unsigned long lastvalue = 0;
+	unsigned long thisvalue;
+
+	BUG_ON(consolenr >= MAX_NR_CONSOLES);
+	
+	if (in_interrupt())
+		return 0;
+
+	if (value > maximum)
+		value = maximum;
+
+	/* Avoid math problems - we can't do 64 bit math here
+	 * (and don't need it - anyone got screen resolution
+	 * of 65536 pixels or more?) */
+	if (bitshift > 0) {
+		maximum = maximum >> bitshift;
+		value = value >> bitshift;
+	}
+
+	thisvalue = value * 65534 / maximum;
+
+	length = sprintf(procstring, "show %lu", thisvalue);
+
+	splash_write_proc(procstring, length);
+	
+	lastvalue = thisvalue;
+	
+	return 0;
+}
+
+/* bootsplash_loglevel_change
+ *
+ * Description:	Update the display when the user changes the log level.
+ */
+
+static void bootsplash_loglevel_change(void)
+{
+	/* Calculate progress bar width. Note that whether the
+	 * splash screen is on might have changed (this might be
+	 * the first call in a new cycle), so we can't take it
+	 * for granted that the width should be the same as
+	 * last time we came in here */
+	if (!splash_is_on(fg_console))
+		return;
+	
+	/* proc interface ensures bar_granularity_limit >= 0 */
+	if (bar_granularity_limit)
+		barwidth = bar_granularity_limit;
+	else
+		barwidth = 100;
+
+	/* Only reset the display if we're switching between nice display
+	 * and displaying debugging output */
+	if (console_loglevel > 1) {
+		if (lastloglevel < 2)
+			splash_write_proc("verbose\n", 9);
+	} else if (lastloglevel > 1)
+			splash_write_proc("silent\n", 8);
+	
+	lastloglevel = console_loglevel;
+}
+
+static void bootsplash_prepare(void)
+{
+	if (!splash_is_on(fg_console))
+		return;
+
+	if (console_loglevel < 2)
+		splash_write_proc("silent\n", 8);
+	else
+		splash_write_proc("verbose\n", 9);
+}
+
+/* bootsplash_update_progress
+ *
+ * Description: Update the progress bar and (if on) in-bar message.
+ * Arguments:	UL value, maximum: Current progress percentage (value/max).
+ * 		const char *fmt, ...: Message to be displayed in the middle
+ * 		of the progress bar.
+ * 		Note that a NULL message does not mean that any previous
+ * 		message is erased! For that, you need message with
+ * 		clearbar on.
+ * Returns:	Unsigned long: The next value where status needs to be updated.
+ * 		This is to reduce unnecessary calls to update_progress.
+ *
+ * Note that for Bootsplash, we ignore the in-bar message
+ */
+static unsigned long bootsplash_update_progress(
+		unsigned long value, unsigned long maximum,
+		const char *fmt, va_list args)
+{
+	unsigned long next_update = 0;
+	int bitshift = generic_fls(maximum) - 16;
+
+	if ((!maximum) || (!barwidth))
+		return maximum;
+
+	if (value < 0)
+		value = 0;
+
+	if (value > maximum)
+		value = maximum;
+
+	/* Try to avoid math problems - we can't do 64 bit math here
+	 * (and shouldn't need it - anyone got screen resolution
+	 * of 65536 pixels or more?) */
+	if (bitshift > 0) {
+		unsigned long temp_maximum = maximum >> bitshift;
+		unsigned long temp_value = value >> bitshift;
+		newbarposn = (int) (temp_value * barwidth / temp_maximum);
+	} else
+		newbarposn = (int) (value * barwidth / maximum);
+	
+	if (newbarposn < barposn)
+		barposn = 0;
+
+	next_update = ((newbarposn + 1) * maximum / barwidth) + 1;
+
+	if ((splash_is_on(fg_console)) &&
+			(newbarposn != barposn)) {
+		fb_splash_set_progress(fg_console, value, maximum);
+		barposn = newbarposn;
+	}
+	return next_update;
+}
+
+/*
+ * User interface specific /proc/suspend entries.
+ */
+static struct suspend_plugin_ops bootsplash_ops;
+
+static struct suspend_proc_data proc_params[] = {
+	{ .filename			= "bootsplash_granularity_limit",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_INTEGER,
+	  .data = {
+		  .integer = {
+			  .variable	= &bar_granularity_limit,
+			  .minimum	= 1,
+			  .maximum	= 2000,
+		  }
+	  }
+	},
+
+	{ .filename			= "disable_bootsplash_support",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_INTEGER,
+	  .data = {
+		.integer = {
+			.variable	= &bootsplash_ops.disabled,
+			.minimum	= 0,
+			.maximum	= 1,
+		}
+	  }
+	}
+};
+
+static struct suspend_plugin_ops bootsplash_ops = {
+	.type					= UI_PLUGIN,
+	.name					= "Bootsplash Support",
+	.ops = {
+		.ui = {
+			.prepare		= bootsplash_prepare,
+			.log_level_change	= bootsplash_loglevel_change,
+			.update_progress	= bootsplash_update_progress,
+			.post_kernel_restore_redraw =
+				bootsplash_prepare,
+		}
+	}
+};
+
+/* ---- Registration ---- */
+
+static __init int bootsplash_load(void)
+{
+	int i, numfiles = sizeof(proc_params) / sizeof(struct suspend_proc_data);
+	int result;
+
+	if (!(result = suspend_register_plugin(&bootsplash_ops))) {
+		printk("Software Suspend Bootsplash Support loaded.\n");
+		for (i=0; i< numfiles; i++)
+			suspend_register_procfile(&proc_params[i]);
+	}
+	return result;
+}
+
+#ifdef MODULE
+static __exit void bootsplash_unload(void)
+{
+	int i, numfiles = sizeof(proc_params) / sizeof(struct suspend_proc_data);
+
+	printk("Software Suspend Bootsplash support unloading.\n");
+
+	for (i=0; i< numfiles; i++)
+		suspend_unregister_procfile(&proc_params[i]);
+	
+	suspend_unregister_plugin(&bootsplash_ops);
+}
+
+module_init(bootsplash_load);
+module_exit(bootsplash_unload);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nigel Cunningham");
+MODULE_DESCRIPTION("Suspend2 Bootsplash support");
+#else
+late_initcall(bootsplash_load);
+#endif
