diff -Naru linux-2.4.29.orig/arch/ppc/boot/simple/embed_config.c linux-2.4.29/arch/ppc/boot/simple/embed_config.c
--- linux-2.4.29.orig/arch/ppc/boot/simple/embed_config.c	2004-04-14 22:05:27.000000000 +0900
+++ linux-2.4.29/arch/ppc/boot/simple/embed_config.c	2005-02-22 01:36:46.000000000 +0900
@@ -5,6 +5,10 @@
  * under  the terms of  the GNU General  Public License as published by the
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
+ *
+ *	Century <www.centurysys.co.jp>
+ *		- Add the board information structure for Century's board
+ *	2001-12-25 ozawa CONFIG_OBSS
  */
 
 #include <linux/types.h>
@@ -30,6 +34,12 @@
 static	bd_t	bdinfo;
 #endif
 
+#ifdef CONFIG_OBSS
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+#endif  /* CONFIG_OBSS */
+
 /* IIC functions.
  * These are just the basic master read/write operations so we can
  * examine serial EEPROM.
@@ -650,6 +660,51 @@
 }
 #endif /* WILLOW */
 
+#ifdef CONFIG_OBSS
+#ifdef CONFIG_OBSS_SERIAL_BAUD
+#define SERIAL_BAUD     CONFIG_OBSS_SERIAL_BAUD
+#else   /* CONFIG_OBSS_SERIAL_BAUD */
+#define SERIAL_BAUD115200
+#endif  /* CONFIG_OBSS_SERIAL_BAUD */
+extern unsigned long timebase_period_ns;
+extern void (outb)(int port, unsigned char val);
+void
+embed_config(bd_t **bdp)
+{
+	bd_t*bd;
+
+	bd = &bdinfo;
+	*bdp = bd;
+
+	switch (*OBSS_RAM_SIZE) {
+		case 4: case 8: case 16: case 32: case 64: case 128:
+			bd->bi_memsize = *OBSS_RAM_SIZE * 0x00100000; break;
+		default:
+			bd->bi_memsize = 64 * 0x00100000;   /* assume 64MB */
+	}
+	bd->bi_intfreq = 0x0bebc200;            /* 200MHz */
+	bd->bi_busfreq = 0x05f5e100;            /* 100MHz */
+	bd->bi_pci_busfreq = 0x01f78a40;        /*  33MHz */
+	bd->bi_enetaddr[0] = OBSS_ENET_MACADDR[0];
+	bd->bi_enetaddr[1] = OBSS_ENET_MACADDR[1];
+	bd->bi_enetaddr[2] = OBSS_ENET_MACADDR[2];
+	bd->bi_enetaddr[3] = OBSS_ENET_MACADDR[3];
+	bd->bi_enetaddr[4] = OBSS_ENET_MACADDR[4];
+	bd->bi_enetaddr[5] = OBSS_ENET_MACADDR[5];
+
+	/* preinit UART0 */
+	/* Input clock. */
+	(outb)(UART0_IO_BASE+UART_LCR, 0x80);
+	(outb)(UART0_IO_BASE+UART_DLL, (BASE_BAUD / SERIAL_BAUD));
+	(outb)(UART0_IO_BASE+UART_DLM, (BASE_BAUD / SERIAL_BAUD) >> 8);
+	/* 8 data, 1 stop, no parity */
+	(outb)(UART0_IO_BASE+UART_LCR, 0x03);
+	/* RTS/DTR */
+	(outb)(UART0_IO_BASE+UART_MCR, 0x03);
+	timebase_period_ns = 1000000000 / bd->bi_tbfreq;
+}
+#else   /* CONFIG_OBSS */
+
 #ifdef CONFIG_IBM_OPENBIOS
 /* This could possibly work for all treeboot roms.
 */
@@ -713,6 +768,7 @@
 	}
 }
 #endif
+#endif /* CONFIG_OBSS */
 
 #ifdef CONFIG_EP405
 void
diff -Naru linux-2.4.29.orig/arch/ppc/boot/simple/misc-embedded.c linux-2.4.29/arch/ppc/boot/simple/misc-embedded.c
--- linux-2.4.29.orig/arch/ppc/boot/simple/misc-embedded.c	2003-11-29 03:26:19.000000000 +0900
+++ linux-2.4.29/arch/ppc/boot/simple/misc-embedded.c	2005-02-22 01:43:01.000000000 +0900
@@ -10,6 +10,12 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  *
+ *	Century <www.centurysys.co.jp>
+ *		- Set the root file system and board memory size
+ *		- Move command line args higher on memory for
+ *		- larger kernels
+ *	2001-12-25 ozawa CONFIG_OBSS
+ *	2002-03-21 ozawa restructuring for OpenBlockSS
  */
 
 #include <linux/config.h>
@@ -24,6 +30,11 @@
 #include <asm/processor.h>
 #include <asm/residual.h>
 
+#ifdef CONFIG_OBSS
+#include <asm/segled.h>
+#define OPNT ((volatile unsigned char *)(0x40000000))
+#endif /* CONFIG_OBSS */
+
 #include "nonstdio.h"
 #include "zlib.h"
 
@@ -62,7 +73,11 @@
 char compiled_string[] = CONFIG_CMDLINE;
 #endif
 char ramroot_string[] = "root=/dev/ram";
+#ifdef CONFIG_OBSS
+char netroot_string[] = "root=/dev/hda1";
+#else /* CONFIG_OBSS */
 char netroot_string[] = "root=/dev/nfs rw ip=on";
+#endif /* CONFIG_OBSS */
 
 /* Serial port to use. */
 unsigned long com_port;
@@ -78,6 +93,9 @@
 extern void flush_instruction_cache(void);
 extern void gunzip(void *, int, unsigned char *, int *);
 extern void embed_config(bd_t **bp);
+#ifdef CONFIG_OBSS
+extern void _printk(char const *fmt, ...);
+#endif /* CONFIG_OBSS */
 
 /* Weak function for boards which don't need to build the
  * board info struct because they are using PPCBoot/U-Boot.
@@ -105,6 +123,32 @@
 	embed_config(&bp);
 	com_port = serial_init(0, bp);
 
+#ifdef CONFIG_OBSS
+	/* Display a zero */
+	*OPNT = (unsigned char)~(SL_V0);
+	_printk("[decompress_kernel] Ramsize %dMB (0x%08x)\n",
+	bp->bi_memsize/0x00100000, bp->bi_memsize);
+#ifdef CONFIG_CMDLINE_BOOL
+	initrd_size = 0;
+#else   /* CONFIG_CMDLINE_BOOL */
+	switch (*OBSS_BOOT_MODE) {
+		case 0:
+			puts("[decompress_kernel] Entering initrd mode. Root FS: ram disk\n");
+			initrd_size = (unsigned long)(&__ramdisk_end) -
+			(unsigned long)(&__ramdisk_begin);
+			break;
+		case 1:
+			puts("[decompress_kernel] Entering hard disk mode. Root FS: hard disk\n");
+			initrd_size = 0;
+			break;
+		default:
+			puts("[decompress_kernel] Entering recover mode. Root FS: ram disk\n");
+			initrd_size = (unsigned long)(&__ramdisk_end) -
+			(unsigned long)(&__ramdisk_begin);
+	}
+#endif  /* CONFIG_CMDLINE_BOOL */
+#endif  /* CONFIG_OBSS */
+
 	/* copy board data */
 	if (bp)
 		memcpy(hold_residual,bp,sizeof(bd_t));
@@ -142,9 +186,10 @@
 	zimage_start = (char *)(unsigned long)(&__image_begin);
 	zimage_size = (unsigned long)(&__image_end) -
 			(unsigned long)(&__image_begin);
-
+#ifndef CONFIG_OBSS
 	initrd_size = (unsigned long)(&__ramdisk_end) -
 		(unsigned long)(&__ramdisk_begin);
+#endif /* !CONFIG_OBSS */
 
 	/*
 	 * The zImage and initrd will be between start and _end, so they've
@@ -220,6 +265,10 @@
 
 	gunzip(0, 0x400000, zimage_start, &zimage_size);
 	flush_instruction_cache();
+#ifdef CONFIG_OBSS
+	/* Display a one */
+	*OPNT = (unsigned char)~(SL_V1);
+#endif /* CONFIG_OBSS */
 	puts("done.\n");
 	{
 		struct bi_record *rec;
diff -Naru linux-2.4.29.orig/arch/ppc/config.in linux-2.4.29/arch/ppc/config.in
--- linux-2.4.29.orig/arch/ppc/config.in	2004-08-08 08:26:04.000000000 +0900
+++ linux-2.4.29/arch/ppc/config.in	2005-02-22 01:48:31.000000000 +0900
@@ -1,7 +1,8 @@
 #
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
-#
+#   2001-12-25 ozawa CONFIG_OBSS
+
 define_bool CONFIG_UID16 n
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
@@ -76,12 +77,16 @@
 	 Redwood-5	CONFIG_REDWOOD_5 	\
 	 Redwood-6	CONFIG_REDWOOD_6 	\
 	 Oak		CONFIG_OAK		\
+	 OpenBlockSS	CONFIG_OBSS		\
 	 Walnut		CONFIG_WALNUT"		Walnut
 
    if [ "$CONFIG_EP405" = "y" ]; then
       bool 'EP405PC Support' CONFIG_EP405PC
    fi
 fi
+   if [ "$CONFIG_OBSS" = "y" ]; then
+      int '  Serial console baud rate (bps)' CONFIG_OBSS_SERIAL_BAUD 115200
+   fi
 
 if [ "$CONFIG_44x" = "y" ]; then
     choice 'Machine Type'			\
@@ -221,6 +226,10 @@
     define_bool CONFIG_405GP y
   fi
 
+  if [ "$CONFIG_OBSS" = "y" ]; then
+    define_bool CONFIG_405GP y
+  fi
+
   if [ "$CONFIG_EBONY" = "y" ]; then
     define_bool CONFIG_440GP y
   fi
@@ -292,6 +301,10 @@
   if [ "$CONFIG_WALNUT" = "y" -o "$CONFIG_EP405" = "y" ]; then
     define_bool CONFIG_BIOS_FIXUP y
   fi
+  if [ "$CONFIG_OBSS" = "y" ]; then
+    define_bool CONFIG_IBM_OPENBIOS y
+    define_bool CONFIG_BIOS_FIXUP y
+  fi
 
 fi
 
diff -Naru linux-2.4.29.orig/arch/ppc/kernel/Makefile linux-2.4.29/arch/ppc/kernel/Makefile
--- linux-2.4.29.orig/arch/ppc/kernel/Makefile	2004-04-14 22:05:27.000000000 +0900
+++ linux-2.4.29/arch/ppc/kernel/Makefile	2005-02-22 01:49:22.000000000 +0900
@@ -81,6 +81,7 @@
 obj-$(CONFIG_GEMINI)		+= open_pic.o
 obj-$(CONFIG_LOPEC)		+= mpc10x_common.o indirect_pci.o pci_auto.o \
 					open_pic.o i8259.o todc_time.o
+obj-$(CONFIG_OBSS)		+= pushsw.o segled.o
 obj-$(CONFIG_PAL4)		+= indirect_pci.o pci_auto.o todc_time.o
 obj-$(CONFIG_PPLUS)		+= pplus_common.o open_pic.o i8259.o \
 				   indirect_pci.o todc_time.o pci_auto.o
diff -Naru linux-2.4.29.orig/arch/ppc/kernel/pushsw.c linux-2.4.29/arch/ppc/kernel/pushsw.c
--- linux-2.4.29.orig/arch/ppc/kernel/pushsw.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.4.29/arch/ppc/kernel/pushsw.c	2005-02-22 02:34:11.000000000 +0900
@@ -0,0 +1,202 @@
+/*
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *	Century <www.centurysys.co.jp>
+ *		- Century's push button driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/fcntl.h>
+#include <asm/uaccess.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+/* #include <asm/ppc4xx.h> */
+#include <asm/pushsw.h>
+
+#define DBGON(x)        x
+#define DBGOFF(x)
+
+
+#define PSW_VER		"0.01"
+#define PSW_IRQ		25      /* AIC_INT25 */
+#define PD_IRQ		30      /* AIC_INT30 */
+
+/*----------------------------------------------------------------------------
+ *	Prototypes.
+ *----------------------------------------------------------------------------*/
+/* int psw_init(void); */
+static
+void psw_isr(int irq, void *dev_id, struct pt_regs *regs);
+static int psw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int psw_open(struct inode *inode, struct file *file);
+static int psw_release(struct inode *inode, struct file *file);
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static struct file_operations	psw_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		psw_ioctl,
+	open:		psw_open,
+	release:	psw_release,
+};
+static struct miscdevice	psw_miscdev =
+	{ 170, "pushsw", &psw_fops };
+static DECLARE_WAIT_QUEUE_HEAD(psw_wait);
+
+/* used to allow only one process at a time to "own" the push switch */
+static pid_t			psw_wait_pid = 0;
+static unsigned long 		PowerFail = 0;
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static int __init psw_init(void)
+{
+	printk("Push switch driver v%s\n", PSW_VER);
+
+	/* Install the push switch interrupt handler */
+	if (request_irq(PSW_IRQ, psw_isr, SA_INTERRUPT, "push switch", NULL)) {
+		printk("[psw_open] interrupt %u not free\n", PSW_IRQ);
+		return (-EIO);
+	}
+	/* Install the power down interrupt handler */
+	if (request_irq(PD_IRQ, psw_isr, SA_INTERRUPT, "power down", NULL)) {
+		printk("[psw_open] interrupt %u not free\n", PD_IRQ);
+		return (-EIO);
+	}
+	DBGOFF(printk("[psw_init] Push switch installed on interrupt %u\n", PSW_IRQ);)
+	DBGOFF(printk("[psw_init] Power down installed on interrupt %u\n", PD_IRQ);)
+	misc_register(&psw_miscdev);
+	return (0);
+}	/* psw_init() */
+
+static void __exit psw_exit (void)
+{
+	misc_deregister(&psw_miscdev);
+	free_irq (PSW_IRQ, NULL);
+	free_irq (PD_IRQ, NULL);
+}
+
+module_init(psw_init);
+module_exit(psw_exit);
+EXPORT_NO_SYMBOLS;
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static
+void psw_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	DBGOFF(printk(KERN_CRIT "p");)
+	wake_up_interruptible(&psw_wait);
+	if (irq == PD_IRQ)
+	{
+		PowerFail = 1;
+		/* free_irq(PD_IRQ, NULL); */
+		mtdcr(DCRN_UIC_TR(UIC0), (mfdcr(DCRN_UIC_TR(UIC0)) | 0x00000002));
+	}
+}	/* psw_isr() */
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static int psw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	unsigned long	flags;
+
+	if (MINOR(inode->i_rdev) != 170) {
+		return (-ENODEV);
+	}
+
+	switch (cmd) {
+		case PSWIOC_GETWAITPID:
+			return (put_user(psw_wait_pid, (int *) arg));
+		case PSWIOC_WAITPUSH:
+			/* protect psw_wait_pid */
+			save_flags(flags);
+			cli();
+			if (psw_wait_pid == 0) {
+				psw_wait_pid = current->pid;
+				restore_flags(flags);
+				DBGOFF(printk("[psw_ioctl] PSWIOC_WAITPUSH pid %u\n", psw_wait_pid);)
+				/* block until switch pushed */
+				if (!PowerFail)
+					interruptible_sleep_on(&psw_wait);
+				save_flags(flags);
+				cli();
+				psw_wait_pid = 0;
+				restore_flags(flags);
+
+				DBGOFF(printk("[psw_ioctl] unblocked\n");)
+				if (signal_pending(current)) {
+					DBGOFF(printk("[psw_ioctl] sig\n");)
+					return (-ERESTARTSYS);
+				}
+				return (0);
+			}
+			else {
+				restore_flags(flags);
+				return (-EBUSY);
+			}
+		default:
+			break;
+	}
+	return (-ENOIOCTLCMD);
+}	/* psw_ioctl() */
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static int psw_open(struct inode *inode, struct file *file)
+{
+	switch (MINOR(inode->i_rdev)) {
+		case 170:
+			MOD_INC_USE_COUNT;
+			return (0);
+		default:
+			return (-ENODEV);
+	}
+}	/* psw_open() */
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static int psw_release(struct inode *inode, struct file *file)
+{
+	unsigned long	flags;
+
+	DBGOFF(printk("[psw_release] ");)
+	if (MINOR(inode->i_rdev) == 170) {
+		DBGOFF(printk("by pid %u\n", current->pid);)
+		save_flags(flags);
+		cli();
+		if (psw_wait_pid && (psw_wait_pid == current->pid)) {
+			psw_wait_pid = 0;
+			restore_flags(flags);
+			DBGOFF(printk("cleared\n");)
+		}
+		else {
+			restore_flags(flags);
+			DBGOFF(if (psw_wait_pid) printk("psw_wait_pid %u, current->pid %u\n", psw_wait_pid, current->pid);)
+		}
+		MOD_DEC_USE_COUNT;
+	}
+	return (0);
+}	/* psw_release() */
+
+
+#ifdef MODULE
+
+#define psw_init init_module
+
+void cleanup_module(void)
+{
+	misc_deregister(&psw_miscdev);
+	free_irq(PSW_IRQ, NULL);
+	free_irq(PD_IRQ, NULL);
+}	/* cleanup_module() */
+
+#endif
diff -Naru linux-2.4.29.orig/arch/ppc/kernel/segled.c linux-2.4.29/arch/ppc/kernel/segled.c
--- linux-2.4.29.orig/arch/ppc/kernel/segled.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.4.29/arch/ppc/kernel/segled.c	2005-02-22 01:56:43.000000000 +0900
@@ -0,0 +1,443 @@
+/*
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *	Century <www.centurysys.co.jp>
+ *		- Century's 7 segment LED driver
+ *      2002-01-06 ozawa CONFIG_OBSS
+ *              - remove '+' shutdown procedure...
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <asm/uaccess.h>
+/* #include <asm/ppc4xx.h> */
+#include <asm/ibm4xx.h>
+#include <asm/io.h>     /* for ioremap() */
+#include <asm/segled.h>
+
+#define DBGON(x)	x
+#define DBGOFF(x)
+
+
+#define SL_VER		"0.01"
+
+#define SL_MAX_TEST	(3)
+#define SL_TEST_DELAY	(0x00C00000UL)
+#define SL_DELAY(n)	for (delay = 0L; delay < (n); delay++) {}
+#define SL_OPEN_MAX	(0xffffffff)
+
+/*
+#define OPNT ((volatile unsigned char *)(0x40000000))
+*/
+static volatile unsigned char * OPNT;
+#ifndef CONFIG_OBSS
+#define GPIO0_OR ((volatile unsigned long *)(0xef600700))
+#define GPIO0_TCR ((volatile unsigned long *)(0xef600704))
+#define GPIO0_ODR ((volatile unsigned long *)(0xef600718))
+#define GPIO0_IR ((volatile unsigned long *)(0xef60071c))
+#endif  /* !CONFIG_OBSS */
+/*----------------------------------------------------------------------------
+ *	Prototypes.
+ *----------------------------------------------------------------------------*/
+/* int sl_init(void); */
+static ssize_t sl_write(struct file *file, const char *buf, size_t count, loff_t *ppos);
+static int sl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int sl_open(struct inode *inode, struct file *file);
+static int sl_release(struct inode *inode, struct file *file);
+static unsigned long sl_v2p(unsigned int v);
+static void sl_hw_test(void);
+static
+void sl_set(unsigned long val);
+static
+void sl_set_dp(int dp);
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static struct file_operations	sl_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		sl_ioctl,
+	open:		sl_open,
+	release:	sl_release,
+	write:		sl_write,
+};
+
+static struct miscdevice	sl_miscdev =
+	{ 171, "segled", &sl_fops };
+
+static unsigned long	sl_open_count = 0L;
+static pid_t		sl_owner_pid = 0;
+
+static unsigned long	firsttime = 1;
+
+static unsigned long		sl_v2p_table[16] = {
+	SL_V0, SL_V1, SL_V2, SL_V3, SL_V4, SL_V5, SL_V6, SL_V7,
+	SL_V8, SL_V9, SL_VA, SL_VB, SL_VC, SL_VD, SL_VE, SL_VF
+};
+
+/*----------------------------------------------------------------------------
+ *	Driver registration.
+ *----------------------------------------------------------------------------*/
+static int __init sl_init(void)
+{
+	printk("7-segment LED driver v%s\n", SL_VER);
+	OPNT = ioremap(0x40000000, 4096);
+	misc_register(&sl_miscdev);
+
+	return (0);
+}	/* sl_init() */
+
+static void __exit sl_exit (void)
+{
+	misc_deregister(&sl_miscdev);
+}
+
+module_init(sl_init);
+module_exit(sl_exit);
+EXPORT_NO_SYMBOLS;
+
+/*----------------------------------------------------------------------------
+ *	Return the segment pattern value corresponding to the given value.
+ *
+ *	Parameters:
+ *		v:	Value between 0 and 15.
+ *
+ *	Returns:
+ *		0:	Range error.
+ *		else:	The segment pattern to use to represent the value.
+ *			Can be used as the argument to sl_set().
+ *----------------------------------------------------------------------------*/
+static unsigned long sl_v2p(unsigned int v)
+{
+	if (v > 15L) {
+		return (0L);
+	}
+	else {
+		return (sl_v2p_table[v]);
+	}
+}	/* sl_v2p() */
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static ssize_t sl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+	size_t		i;
+	unsigned int	digit;
+
+	if (sl_owner_pid && (sl_owner_pid != current->pid)) {
+		return (-EPERM);
+	}
+
+	DBGOFF(printk("[sl_write] count %d\n", count);)
+	DBGOFF({
+		for (i = 0L; i < count; i++) {
+			printk(" 0x%02x", buf[i]);
+		}
+	})
+
+	/* no seeks allowed on this device */
+	if (ppos != &file->f_pos) {
+		DBGOFF(printk("[sl_write] seek\n");)
+		return (-ESPIPE);
+	}
+
+	for (i = 0; i < count; i++) {
+		digit = 16;
+		if ((buf[i] >= 0x30) && (buf[i] <= 0x39)) {
+			digit = (unsigned int) (buf[i] - 0x30);
+		}
+		else {
+			switch (buf[i]) {
+			case 0x41:
+			case 0x61:
+				digit = 10;
+				break;
+			case 0x42:
+			case 0x62:
+				digit = 11;
+				break;
+			case 0x43:
+			case 0x63:
+				digit = 12;
+				break;
+			case 0x44:
+			case 0x64:
+				digit = 13;
+				break;
+			case 0x45:
+			case 0x65:
+				digit = 14;
+				break;
+			case 0x46:
+			case 0x66:
+				digit = 15;
+				break;
+			case ' ':	/* space => all off */
+				sl_set(SL_NONE);
+				break;
+			case '+':	/* '+' => DP on  */
+				sl_set_dp(1);
+#ifndef CONFIG_OBSS
+				if (firsttime)
+				{
+					printk("EXECUTING POWER SHUTDOWN\n");
+					*GPIO0_ODR &= ~(0x00200000);
+					*GPIO0_OR |= 0x00200000;
+					*GPIO0_TCR |= 0x00200000;
+					mtdcr(DCRN_CHCR0, (mfdcr(DCRN_CHCR0) | 0x04000000));
+					*GPIO0_OR &= ~(0x00200000);
+					firsttime = 0;
+				}
+#endif  /* !CONFIG_OBSS */
+				break;
+			case '-':	/* '-' => DP off  */
+				sl_set_dp(0);
+				break;
+#if 0
+// TODO - for watchdog debug only - REMOVE!!
+case 'w':
+printk("disabling interrupts for watchdog test - REMOVE!!!\n");
+	cli();
+	while (1) {}
+#endif
+			default:
+				break;
+			}
+		}	/* A..F, a..f, etc. */
+
+		if (digit < 16) {
+			sl_set(sl_v2p(digit));
+			DBGOFF(printk("[sl_write] ok\n");)
+		}
+	}
+
+	return (count);
+}	/* sl_write() */
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static int sl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	extern void sys_405dc(unsigned long);
+#if 0
+	unsigned long pn, *tmp, size;
+	int i;
+#endif  /* 0 */
+
+	unsigned long	ptn;
+
+	DBGOFF(printk("!");)
+
+	if (MINOR(inode->i_rdev) != 171) {
+		return (-ENODEV);
+	}
+
+	//printk(" (cmd %x,%x) ", cmd, SLIOC_TEST405);
+	DBGOFF(printk(" cmd %u ", cmd);)
+
+	switch (cmd) {
+	case SLIOC_GET_OWNER_PID:
+		DBGOFF(printk(" SLIOC_GET_OWNER_PID ");)
+		return (put_user(sl_owner_pid, (int *) arg));
+	case SLIOC_RESERVE:
+		DBGOFF(printk(" SLIOC_RESERVE ");)
+		if (!sl_owner_pid || (sl_owner_pid == current->pid)) {
+			sl_owner_pid = current->pid;
+			DBGOFF(printk("led reserved by pid %d\n", sl_owner_pid);)
+			return (0);
+		}
+		return (-EPERM);
+	default:
+		/*
+		 *	Other commands require LED access.
+		 *	Disallow if LED has been reserved
+		 *	by another process.
+		 */
+		if (sl_owner_pid && (sl_owner_pid != current->pid)) {
+			DBGOFF(printk("disallowed (sl_owner_pid %d, current->pid %d)\n", sl_owner_pid, current->pid);)
+			return (-EPERM);
+		}
+		break;
+	}	/* switch on cmd */
+
+	DBGOFF(printk(" cmd check 2 ");)
+
+	switch (cmd) {
+		case SLIOC_SETVAL:
+			DBGOFF(printk(" SLIOC_SETVAL ");)
+			ptn = sl_v2p((unsigned int) arg);
+			if (ptn) {
+				DBGOFF(printk(" led%u ", (unsigned)arg);)
+				sl_set(ptn);
+				return (0);
+			}
+			DBGOFF(else printk(" SLIOC_SETVAL arg 0x%x ignored ",
+							(unsigned)arg);)
+			break;
+		case SLIOC_SETSEG:
+			DBGOFF(printk(" SLIOC_SETSEG ");)
+			DBGOFF(printk("!");)
+			sl_set(arg);
+			return (0);
+		case SLIOC_TEST:
+			DBGOFF(printk(" SLIOC_TEST ");)
+			sl_hw_test();
+			return (0);
+		default:
+			DBGOFF(printk(" unknown cmd %d ", cmd);)
+			break;
+	}
+	return (-ENOIOCTLCMD);
+}	/* sl_ioctl() */
+
+/*----------------------------------------------------------------------------
+ *	Set the given value to the 7-segment LED.
+ *
+ *	Parameters:
+ *		val:	Value indicating which segments should be on.
+ *			Can be built with the macros in segled.h.
+ *----------------------------------------------------------------------------*/
+static
+void sl_set(unsigned long val)
+{
+	*OPNT = 0xFF; 		/* turn off all segments */
+	*OPNT = ~(val);	/* turn on specified segments */
+}	/* sl_set() */
+
+/*----------------------------------------------------------------------------
+ *	Set the DP (dot) segment of the 7-segment LED as specified.
+ *
+ *	Parameters:
+ *		dp:	State of segment DP (dot).
+ *				0:	off
+ *				else:	on
+ *----------------------------------------------------------------------------*/
+static
+void sl_set_dp(int dp)
+{
+	if (dp) {
+		*OPNT = ~SL_DP;	/* turn DP segment on */
+	}
+	else {
+		*OPNT = SL_DP;	/* turn DP segment off */
+	}
+}	/* sl_set_dp() */
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static int sl_open(struct inode *inode, struct file *file)
+{
+#if 1
+	switch (MINOR(inode->i_rdev)) {
+		case 171:
+			if (sl_open_count >= SL_OPEN_MAX) {
+				return (-EBUSY);
+			}
+			sl_open_count++;
+			return (0);
+		default:
+			return (-ENODEV);
+	}
+#else
+	//printk("o");
+	switch (MINOR(inode->i_rdev)) {
+		case 171:
+			sl_open_count++;
+			//printk("k");
+			return (0);
+		default:
+			printk("No");
+			return (-ENODEV);
+	}
+//	extern void PPC4xx_tlb_flush_all(void);
+//	PPC4xx_tlb_flush_all();
+//	//return (0);
+//	return (-ENODEV);
+#endif
+}	/* sl_open() */
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static int sl_release(struct inode *inode, struct file *file)
+{
+	if (MINOR(inode->i_rdev) == 171) {
+		if (sl_owner_pid == current->pid) {
+			DBGOFF(printk("pid %d led reserve released\n",
+								sl_owner_pid);)
+			sl_owner_pid = 0;
+		}
+		if (sl_open_count >= 1L) {
+			DBGOFF(printk("[sl_release]\n");)
+			sl_open_count--;
+		}
+		else printk("[sl_release] not open!\n");
+	}
+	return (0);
+}	/* sl_release() */
+
+/*----------------------------------------------------------------------------
+ *----------------------------------------------------------------------------*/
+static void sl_hw_test(void)
+{
+	unsigned long	delay;
+	unsigned int	test, ptn;
+
+	for (test = 0; test < SL_MAX_TEST; test++) {
+		/* all off */
+		DBGOFF(printk("all off ");)
+		sl_set(SL_NONE);
+		sl_set_dp(0);
+		SL_DELAY(SL_TEST_DELAY)
+
+		/* display 0..F in sequence */
+		for (ptn = 0; ptn <= 15; ptn++) {
+			DBGOFF(printk(" %x ", ptn);)
+			sl_set(sl_v2p_table[ptn]);
+			SL_DELAY(SL_TEST_DELAY)
+		}
+
+		/* all on */
+		DBGOFF(printk("all on ");)
+		sl_set(SL_ALL);
+		SL_DELAY(SL_TEST_DELAY)
+
+		sl_set_dp(0);	/* turn off DP */
+
+		/* turn on each segment individually */
+		DBGOFF(printk(" sA ");)
+		sl_set(SL_A);
+		SL_DELAY(SL_TEST_DELAY)
+		DBGOFF(printk(" sB ");)
+		sl_set(SL_B);
+		SL_DELAY(SL_TEST_DELAY)
+		DBGOFF(printk(" sC ");)
+		sl_set(SL_C);
+		SL_DELAY(SL_TEST_DELAY)
+		DBGOFF(printk(" sD ");)
+		sl_set(SL_D);
+		SL_DELAY(SL_TEST_DELAY)
+		DBGOFF(printk(" sE ");)
+		sl_set(SL_E);
+		SL_DELAY(SL_TEST_DELAY)
+		DBGOFF(printk(" sF ");)
+		sl_set(SL_F);
+		SL_DELAY(SL_TEST_DELAY)
+		DBGOFF(printk(" sG ");)
+		sl_set(SL_G);
+		SL_DELAY(SL_TEST_DELAY)
+		DBGOFF(printk(" sDP ");)
+		sl_set(SL_DP);
+		SL_DELAY(SL_TEST_DELAY)
+
+		DBGOFF(printk("\n");)
+	}	/* for number of times to repeat test */
+}	/* sl_hw_test() */
diff -Naru linux-2.4.29.orig/arch/ppc/platforms/Makefile linux-2.4.29/arch/ppc/platforms/Makefile
--- linux-2.4.29.orig/arch/ppc/platforms/Makefile	2004-08-08 08:26:04.000000000 +0900
+++ linux-2.4.29/arch/ppc/platforms/Makefile	2005-02-22 01:57:44.000000000 +0900
@@ -39,6 +39,7 @@
 obj-$(CONFIG_EBONY)		+= ebony.o
 obj-$(CONFIG_OCOTEA)		+= ocotea.o
 obj-$(CONFIG_WALNUT)		+= walnut.o
+obj-$(CONFIG_OBSS)		+= obss.o
 
 obj-$(CONFIG_APUS)		+= apus_setup.o
 ifeq ($(CONFIG_APUS),y)
diff -Naru linux-2.4.29.orig/arch/ppc/platforms/obss.c linux-2.4.29/arch/ppc/platforms/obss.c
--- linux-2.4.29.orig/arch/ppc/platforms/obss.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.4.29/arch/ppc/platforms/obss.c	2005-02-22 02:35:11.000000000 +0900
@@ -0,0 +1,567 @@
+/*
+ *
+ *    Copyright (c) 2002 OZAWA Takahiro <obss@ozawa.cc>
+ *      derived from walnut.c and ppc4xx_setup.c
+ *
+ *    Copyrigh t(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Copyright 2000-2001 MontaVista Software Inc.
+ *      Completed implementation.
+ *      Author: MontaVista Software, Inc.  <source@mvista.com>
+ *
+ *    Module name: walnut.c
+ *
+ *    Description:
+ *      Architecture- / platform-specific boot-time initialization code for
+ *      IBM PowerPC 4xx based boards. Adapted from original
+ *      code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
+ *      <dan@net4x.com>.
+ *
+ *      History: 11/09/2001 - armin
+ *      added board_init to add in additional instuctions needed during platfrom_init
+ *
+ *      01/22/2002 - Armin
+ *      converted pci to ocp
+ *
+ *	Century <www.centurysys.co.jp>
+ *		- Alter the IRQ mapping to suit Century's board
+ *		- EEPROM support
+ *		- RTC support
+ *		- Century's IDE support
+ *      2002-03-21 - ozawa
+ *      split OpenBlockSS's logic from walnut.c and ppc4xx_setup.c
+ *      2002-06-17 - ozawa
+ *      brush up rtc
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+#include <linux/pci.h>
+#include <linux/rtc.h>
+#include <linux/ide.h>
+#include <linux/delay.h>
+
+#include <asm/system.h>
+#include <asm/pci-bridge.h>
+#include <asm/processor.h>
+#include <asm/machdep.h>
+#include <asm/page.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <platforms/ibm_ocp.h>
+
+#define IIC0_MDBUF	((volatile unsigned char *)(IIC0_BASE + 0x00))
+#define IIC0_SDBUF	((volatile unsigned char *)(IIC0_BASE + 0x02))
+#define IIC0_LMADR	((volatile unsigned char *)(IIC0_BASE + 0x04))
+#define IIC0_HMADR	((volatile unsigned char *)(IIC0_BASE + 0x05))
+#define IIC0_CNTL	((volatile unsigned char *)(IIC0_BASE + 0x06))
+#define IIC0_MDCNTL	((volatile unsigned char *)(IIC0_BASE + 0x07))
+#define IIC0_STS	((volatile unsigned char *)(IIC0_BASE + 0x08))
+#define IIC0_EXTSTS	((volatile unsigned char *)(IIC0_BASE + 0x09))
+#define IIC0_LSADR	((volatile unsigned char *)(IIC0_BASE + 0x0a))
+#define IIC0_HSADR	((volatile unsigned char *)(IIC0_BASE + 0x0b))
+#define IIC0_CLKDIV	((volatile unsigned char *)(IIC0_BASE + 0x0c))
+#define IIC0_INTRMSK	((volatile unsigned char *)(IIC0_BASE + 0x0d))
+#define IIC0_XFRCNT	((volatile unsigned char *)(IIC0_BASE + 0x0e))
+#define IIC0_XTCNTLSS	((volatile unsigned char *)(IIC0_BASE + 0x0f))
+#define IIC0_DIRECTCNTL	((volatile unsigned char *)(IIC0_BASE + 0x10))
+
+#define EEPROMTimeOut 16
+#define EEPROMDeviceCode 0xa0
+#define RTCDeviceCode 0xd0
+
+static void EEPROMInit (void);
+static int EEPROMDone(void);
+static int EEPROMWriteByte(unsigned char DeviceCode, unsigned short address, unsigned char data);
+static int EEPROMReadByte(unsigned char DeviceCode, unsigned short address, unsigned char *data);
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* Some IRQs unique to OpenBlockSS.
+ * Used by the generic 405 PCI setup functions in ppc4xx_pci.c
+ */
+int __init
+ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *      PCI IDSEL/INTPIN->INTLINE
+	 *      A       B       C       D
+	 */
+	{
+                {28, 28, 28, 28},       /* IDSEL 7 - PCI slot 1 */
+                {26, 26, 26, 26},       /* IDSEL 8 - PCI slot 2 */
+                {27, 27, 27, 27},       /* IDSEL 9 - PCI slot 3 */
+        };
+	const long min_idsel = 7, max_idsel = 9, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+};
+
+/* note that board_setup_arch is called from init's start_kernel
+   via ppc4xx_setup_arch */
+void __init
+board_setup_arch(void)
+{
+#ifdef CONFIG_IDE
+#define IDE_INIT_TIMEOUT 100
+        volatile unsigned short *cmdsts = (volatile unsigned short *)OBSS_ATACTRL_ADDR;
+        volatile unsigned short *base = (volatile unsigned short *)OBSS_ATAREG_ADDR;
+        int i;
+        unsigned short stat;
+
+        /* RESET IDE i/f pAsic */
+        printk("[board_setup_arch] Initializing IDE I/F\n");
+        mtdcr(DCRN_CHCR1, (mfdcr(DCRN_CHCR1) | 0x00004000));
+        mdelay(5);
+        *cmdsts = 0x0001;
+        mdelay(5);
+        *cmdsts = 0x0002;
+        mdelay(5);
+        *cmdsts = 0x4000;
+        DBG("[board_setup_arch] Byte swap %x\n", *cmdsts);
+
+        /* map IDE regs & wait  */
+        DBG("[board_setup_arch] Waiting for IDE devices\n");
+        for(i=0; i<IDE_INIT_TIMEOUT; i++)
+        {
+                mdelay(5);
+                mdelay(5);
+                stat = *(base + (IDE_STATUS_OFFSET-IDE_DATA_OFFSET));
+                if( (stat & 0x8000) == 0) break;    /* reset complete */
+        }
+        if(i>= IDE_INIT_TIMEOUT)
+                printk("[board_setup_arch] IDE devices TIMEOUT\n");
+#endif  /* CONFIG_IDE */
+}
+
+
+void __init
+bios_fixup(struct pci_controller *hose, void *pcil0_base)
+{
+
+	unsigned int bar_response, bar;
+	struct pcil0_regs *pcip;
+	/*
+	 * Expected PCI mapping:
+	 *
+	 *  PLB addr             PCI memory addr
+	 *  ---------------------       ---------------------
+	 *  0000'0000 - 7fff'ffff <---  0000'0000 - 7fff'ffff
+	 *  8000'0000 - Bfff'ffff --->  8000'0000 - Bfff'ffff
+	 *
+	 *  PLB addr             PCI io addr
+	 *  ---------------------       ---------------------
+	 *  e800'0000 - e800'ffff --->  0000'0000 - 0001'0000
+	 *
+	 * The following code is simplified by assuming that the bootrom
+	 * has been well behaved in following this mapping.
+	 */
+
+#ifdef DEBUG
+	int i;
+	pcip = (struct pcil0_regs *) pcil0_base;
+
+	printk("ioremap PCLIO_BASE = 0x%x\n", pcip);
+	printk("PCI bridge regs before fixup \n");
+	for (i = 0; i <= 3; i++) {
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
+	}
+	printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
+	printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
+	printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
+	printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
+
+#else
+	pcip = (struct pcil0_regs *) pcil0_base;
+#endif
+
+	/* added for IBM boot rom version 1.15 bios bar changes  -AK */
+
+	/* Disable region first */
+	out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
+	/* PLB starting addr, PCI: 0x80000000 */
+	out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
+	/* PCI start addr, 0x80000000 */
+	out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
+	/* 512MB range of PLB to PCI */
+	out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
+	/* Enable no pre-fetch, enable region */
+	out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
+						(PPC405_PCI_UPPER_MEM -
+						 PPC405_PCI_MEM_BASE)) | 0x01));
+
+	/* Disable region one */
+	out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+	out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
+	out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
+	out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
+	out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+	out_le32((void *) &(pcip->ptm1ms), 0x00000000);
+
+	/* Disable region two */
+	out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+	out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
+	out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
+	out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
+	out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+	out_le32((void *) &(pcip->ptm2ms), 0x00000000);
+
+	/* Zero config bars */
+	for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
+		early_write_config_dword(hose, hose->first_busno,
+					 PCI_FUNC(hose->first_busno), bar,
+					 0x00000000);
+		early_read_config_dword(hose, hose->first_busno,
+					PCI_FUNC(hose->first_busno), bar,
+					&bar_response);
+		DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
+		    hose->first_busno, PCI_SLOT(hose->first_busno),
+		    PCI_FUNC(hose->first_busno), bar, bar_response);
+	}
+	/* end work arround */
+
+#ifdef DEBUG
+	printk("PCI bridge regs after fixup \n");
+	for (i = 0; i <= 3; i++) {
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
+	}
+	printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
+	printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
+	printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
+	printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
+
+#endif
+}
+
+/* note that board_io_mapping is called from MMU_init of mm/init.c
+   via m4xx_map_io */
+void __init
+board_io_mapping(void)
+{
+	DBG("[board_io_mapping] Mapping seg-LED, ATA\n");
+	io_block_mapping(OBSS_SEGLED_ADDR, OBSS_SEGLED_ADDR,
+	  OBSS_SEGLED_SIZE, _PAGE_IO);
+	io_block_mapping(OBSS_ATAREG_ADDR, OBSS_ATAREG_ADDR,
+	  OBSS_ATAREG_SIZE, _PAGE_IO);
+	io_block_mapping(OBSS_ATACTRL_ADDR, OBSS_ATACTRL_ADDR,
+	  OBSS_ATACTRL_SIZE, _PAGE_IO);
+}
+
+#define IRQ25AND31     ((1<<(31-25))|(1<<(31-31)))
+void __init
+board_setup_irq(void)
+{
+        DBG("[board_setup_irq] set irq 25 and 31 are level-sensitive\n");
+        /* irq31(405eth re-link) and irq25(push sw) are leve-sensitive */
+        mtdcr(DCRN_UIC_TR(UIC0), mfdcr(DCRN_UIC_TR(UIC0)) | IRQ25AND31);
+        /* if level-sensitive interrupt, then clear bit in the status register */
+        DBG("[board_setup_irq] clear status register for level-sensitive irqs\n");
+        mtdcr(DCRN_UIC_SR(UIC0), ~(mfdcr(DCRN_UIC_TR(UIC0))));
+}
+
+static void
+EEPROMInit ()
+{
+	writeb(0x00, IIC0_LMADR);	/* clear low master addr */
+	writeb(0x00, IIC0_HMADR);	/* clear high master addr */
+	writeb(0x00, IIC0_LSADR);	/* clear low slave addr */
+	writeb(0x00, IIC0_HSADR);	/* clear high slave addr */
+	writeb(0x0A, IIC0_STS);		/* clear status */
+	writeb(0x8F, IIC0_EXTSTS);	/* clear extended status */
+	writeb(0x04, IIC0_CLKDIV);	/* set clock division */
+	writeb(0x00, IIC0_INTRMSK);	/* disable interrupt */
+	writeb(0x00, IIC0_XFRCNT);	/* clear transfer count */
+	writeb(0xF0, IIC0_EXTSTS);	/* clear extended control and status */
+	writeb(0x43, IIC0_MDCNTL);	/* set mode control */
+	writeb(0x00, IIC0_CNTL);	/* clear control */
+}
+
+static int
+EEPROMWriteByte(unsigned char DeviceCode, unsigned short address, unsigned char data)
+{
+	writeb(0x0A, IIC0_STS);		/* clear status */
+
+	writeb(readb(IIC0_MDCNTL)|0x40, IIC0_MDCNTL);	/* flush master data buffer */
+	writeb(DeviceCode, IIC0_LMADR);		/* transmit device code */
+	writeb(address, IIC0_MDBUF);		/* transmit address */
+	writeb(data, IIC0_MDBUF);			/* transmit datum */
+	writeb(0x11, IIC0_CNTL);	/* start transmission */
+	if (EEPROMDone() != 0) return -1;
+	return 0;
+}
+
+static int
+EEPROMReadByte(unsigned char DeviceCode, unsigned short address, unsigned char *data)
+{
+	writeb(0x0A, IIC0_STS);		/* clear status */
+
+	writeb(readb(IIC0_MDCNTL)|0x40, IIC0_MDCNTL);	/* flush master data buffer */
+	writeb(DeviceCode, IIC0_LMADR);		/* transmit device code */
+	writeb(address, IIC0_MDBUF);		/* transmit address */
+	writeb(0x01, IIC0_CNTL);	/* start transmission */
+	if (EEPROMDone() != 0) return -1;
+
+	writeb(readb(IIC0_MDCNTL)|0x40, IIC0_MDCNTL);	/* flush master data buffer */
+	writeb(DeviceCode|0x01, IIC0_LMADR);	/* transmit device code */
+	writeb(0x03, IIC0_CNTL);	/* start transmission */
+	if (EEPROMDone() != 0) return -1;
+
+	*data = readb(IIC0_MDBUF);
+	return 0;
+}
+
+static int
+EEPROMDone()
+{
+	int i;
+	unsigned char status;
+
+	for (i = EEPROMTimeOut; i > 0; i--)
+	{
+		status = readb(IIC0_STS);
+		if ((status & 0x01) == 0x00)
+		{
+			writeb(0x0A, IIC0_STS);		/* clear status */
+			if (status & 0x04) return -2;	/* error */
+			return(0);
+		}
+		udelay(100);
+	}
+	return(-1);
+}
+
+
+static long
+obss_time_init(void)
+{
+	mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~IBM_CPM_IIC0);
+	EEPROMInit();
+	return 0;
+}
+
+
+static int
+obss_set_rtc_time(unsigned long nowtime)
+{
+	struct rtc_time   tm;
+	unsigned char     tmp;
+	unsigned short	  address = 0x0000;
+	int 		  r_code;
+
+	to_tm(nowtime, &tm);
+
+	tmp = tm.tm_sec ;  tm.tm_sec  = ((tmp / 10) << 4) + (tmp % 10);
+	tmp = tm.tm_min ;  tm.tm_min  = ((tmp / 10) << 4) + (tmp % 10);
+	tmp = tm.tm_hour;  tm.tm_hour = ((tmp / 10) << 4) + (tmp % 10);
+	tmp = tm.tm_wday;  tm.tm_wday = ((tmp / 10) << 4) + (tmp % 10);
+	tmp = tm.tm_mday;  tm.tm_mday = ((tmp / 10) << 4) + (tmp % 10);
+	tmp = tm.tm_mon ;  tm.tm_mon  = ((tmp / 10) << 4) + (tmp % 10);
+	tm.tm_year -= 2000;
+	tmp = tm.tm_year;  tm.tm_year = ((tmp / 10) << 4) + (tmp % 10);
+
+	DBG("[obss_set_rtc_time] Seconds %d %d\n", tm.tm_sec, (tm.tm_sec & 0x7f));
+	r_code = EEPROMWriteByte(RTCDeviceCode, address, (tm.tm_sec & 0x7f));
+	if (r_code != 0)
+	{
+		printk("[obss_set_rtc_time] Error writing RTC %d\n", address);
+		return (r_code);
+	}
+	address++;
+
+	DBG("[obss_set_rtc_time] Minutes %d %d\n", tm.tm_min, (tm.tm_min & 0x7f));
+	r_code = EEPROMWriteByte(RTCDeviceCode, address, (tm.tm_min & 0x7f));
+	if (r_code != 0)
+	{
+		printk("[obss_set_rtc_time] Error writing RTC %d\n", address);
+		return (r_code);
+	}
+	address++;
+
+	DBG("[obss_set_rtc_time] Hours %d %d\n", tm.tm_hour, (tm.tm_hour & 0x7f));
+	r_code = EEPROMWriteByte(RTCDeviceCode, address, (tm.tm_hour & 0x3f));
+	if (r_code != 0)
+	{
+		printk("[obss_set_rtc_time] Error writing RTC %d\n", address);
+		return (r_code);
+	}
+	address++;
+
+	DBG("[obss_set_rtc_time] Wday %d %d\n", tm.tm_wday, (tm.tm_wday & 0x1f));
+	r_code = EEPROMWriteByte(RTCDeviceCode, address, (tm.tm_wday & 0x1f));
+	if (r_code != 0)
+	{
+		printk("[obss_set_rtc_time] Error writing RTC %d\n", address);
+		return (r_code);
+	}
+	address++;
+
+	DBG("[obss_set_rtc_time] Mday %d %d\n", tm.tm_mday, (tm.tm_mday & 0x3f));
+	r_code = EEPROMWriteByte(RTCDeviceCode, address, (tm.tm_mday & 0x3f));
+	if (r_code != 0)
+	{
+		printk("[obss_set_rtc_time] Error writing RTC %d\n", address);
+		return (r_code);
+	}
+	address++;
+
+	DBG("[obss_set_rtc_time] Month %d %d\n", tm.tm_mon, (tm.tm_mon & 0x1f));
+	r_code = EEPROMWriteByte(RTCDeviceCode, address, (tm.tm_mon & 0x1f));
+	if (r_code != 0)
+	{
+		printk("[obss_set_rtc_time] Error writing RTC %d\n", address);
+		return (r_code);
+	}
+	address++;
+
+	DBG("[obss_set_rtc_time] Year %d %d\n", tm.tm_year, tm.tm_year);
+	r_code = EEPROMWriteByte(RTCDeviceCode, address, (tm.tm_year));
+	if (r_code != 0)
+	{
+		printk("[obss_set_rtc_time] Error writing RTC %d\n", address);
+		return (r_code);
+	}
+	return 0;
+}
+
+static unsigned long
+obss_get_rtc_time(void)
+{
+	unsigned char tmp;
+	unsigned int year, mon, mday, day, hour, min, sec;
+	unsigned short address = 0x0000;
+	int r_code;
+
+	r_code = EEPROMReadByte(RTCDeviceCode, address, &tmp);
+	if (r_code != 0)
+	{
+		printk("[obss_get_rtc_time] Error reading RTC %d\n", address);
+		return (r_code);
+	}
+	sec = tmp;
+	address++;
+
+	r_code = EEPROMReadByte(RTCDeviceCode, address, &tmp);
+	if (r_code != 0)
+	{
+		printk("[obss_get_rtc_time] Error reading RTC %d\n", address);
+		return (r_code);
+	}
+	min = tmp;
+	address++;
+
+	r_code = EEPROMReadByte(RTCDeviceCode, address, &tmp);
+	if (r_code != 0)
+	{
+		printk("[obss_get_rtc_time] Error reading RTC %d\n", address);
+		return (r_code);
+	}
+	hour = tmp;
+	address++;
+
+	r_code = EEPROMReadByte(RTCDeviceCode, address, &tmp);
+	if (r_code != 0)
+	{
+		printk("[obss_get_rtc_time] Error reading RTC %d\n", address);
+		return (r_code);
+	}
+	day = tmp;
+	address++;
+
+	r_code = EEPROMReadByte(RTCDeviceCode, address, &tmp);
+	if (r_code != 0)
+	{
+		printk("[obss_get_rtc_time] Error reading RTC %d\n", address);
+		return (r_code);
+	}
+	mday = tmp;
+	address++;
+
+	r_code = EEPROMReadByte(RTCDeviceCode, address, &tmp);
+	if (r_code != 0)
+	{
+		printk("[obss_get_rtc_time] Error reading RTC %d\n", address);
+		return (r_code);
+	}
+	mon = tmp;
+	address++;
+
+	r_code = EEPROMReadByte(RTCDeviceCode, address, &tmp);
+	if (r_code != 0)
+	{
+		printk("[obss_get_rtc_time] Error reading RTC %d\n", address);
+		return (r_code);
+	}
+	year = tmp;
+	sec     = sec & 0x7f;
+	min     = min & 0x7f;
+	hour    = hour & 0x3f;
+	mon     = mon & 0x1f;
+	mday    = mday & 0x3f;
+
+	tmp = sec    ;  sec     = (tmp &0xf) + ((tmp >> 4) * 10);
+	tmp = min    ;  min     = (tmp &0xf) + ((tmp >> 4) * 10);
+	tmp = hour   ;  hour    = (tmp &0xf) + ((tmp >> 4) * 10);
+	tmp = mday   ;  mday    = (tmp &0xf) + ((tmp >> 4) * 10);
+	tmp = mon    ;  mon     = (tmp &0xf) + ((tmp >> 4) * 10);
+	tmp = year   ;  year    = (tmp &0xf) + ((tmp >> 4) * 10);
+	year += 2000;
+
+	DBG("[obss_get_rtc_time] Year %d Month %d Day %d Hour %d Min %d Sec %d %u\n", year, mon, mday, hour, min, sec, mktime(year, mon, mday, hour, min, sec));
+	return mktime(year, mon, mday, hour, min, sec);
+}
+
+static void
+obss_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+{
+        int i;
+        ide_ioreg_t reg, base;
+
+        if (data_port != 0) return;     /* ignore it if the default attribute is defined */
+
+        base = (ide_ioreg_t)ioremap(OBSS_ATAREG_ADDR, OBSS_ATAREG_SIZE);
+        if (base == 0) panic("[obss_ide_init_hwif_ports] ioremap failed\n");
+
+        for (i=IDE_DATA_OFFSET, reg=base; i<=IDE_STATUS_OFFSET; i++, reg+=2)
+        {
+                hw->io_ports[i] = reg;
+                DBG("[obss_ide_init_hwif_ports] FROM DATA OFFSET %d %x\n",
+			i, hw->io_ports[i]);
+        }
+
+        hw->io_ports[IDE_CONTROL_OFFSET] = base + 0x1c;
+        DBG("[obss_ide_init_hwif_ports] IDE CONTROL %x\n", hw->io_ports[IDE_CONTROL_OFFSET]);
+
+        if (irq) *irq = OBSS_ATA0_IRQ;
+}
+
+/* note that board_init is called before the mmu is initialized */
+void __init
+board_init(void)
+{
+#if defined(CONFIG_PPC_RTC) || defined(CONFIG_GEN_RTC)
+        ppc_md.time_init = obss_time_init;
+        ppc_md.set_rtc_time = obss_set_rtc_time;
+        ppc_md.get_rtc_time = obss_get_rtc_time;
+#endif  /* CONFIG_PPC_RTC || CONFIG_GEN_RTC */
+#ifdef CONFIG_IDE
+        ppc_ide_md.ide_init_hwif = obss_ide_init_hwif_ports;
+#endif  /* CONFIG_IDE */
+}
diff -Naru linux-2.4.29.orig/arch/ppc/platforms/obss.h linux-2.4.29/arch/ppc/platforms/obss.h
--- linux-2.4.29.orig/arch/ppc/platforms/obss.h	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.4.29/arch/ppc/platforms/obss.h	2005-02-22 02:03:02.000000000 +0900
@@ -0,0 +1,119 @@
+/*
+ *
+ *    Copyright (c) 2002 OZAWA Takahiro <obss@ozawa.cc>
+ *      derived from walnut.h
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Copyright 2000 MontaVista Software Inc.
+ *	PPC405 modifications
+ * 	Author: MontaVista Software, Inc.
+ *         	frank_rowand@mvista.com or source@mvista.com
+ * 	   	debbie_chu@mvista.com
+ *
+ *    Module name: obss.h
+ *
+ *    Description:
+ *      Macros, definitions, and data structures specific to the IBM PowerPC
+ *      based boards.
+ *
+ *      This includes:
+ *
+ *         Plat'Home "OpenBlockSS" micro server
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_OBSS_H__
+#define __ASM_OBSS_H__
+
+/* We have a 405GP core */
+#include <platforms/ibm405gp.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * Data structure defining board information maintained by the
+ * embed_config() for OpenBlockSS while booting.
+ * ROM on IBM's "Walnut" evaluation board. An effort has been made to
+ * keep the field names consistent with the 8xx 'bd_t' board info
+ * structures.
+ */
+
+typedef struct board_info {
+	unsigned char	 bi_s_version[4];	/* Version of this structure */
+	unsigned char	 bi_r_version[30];	/* Version of the IBM ROM */
+	unsigned int	 bi_memsize;		/* DRAM installed, in bytes */
+	unsigned char	 bi_enetaddr[6];	/* Local Ethernet MAC address */
+	unsigned char	 bi_pci_enetaddr[6];	/* PCI Ethernet MAC address */
+	unsigned int	 bi_intfreq;		/* Processor speed, in Hz */
+	unsigned int	 bi_busfreq;		/* PLB Bus speed, in Hz */
+	unsigned int	 bi_pci_busfreq;	/* PCI Bus speed, in Hz */
+} bd_t;
+
+/* Some 4xx parts use a different timebase frequency from the internal clock.
+*/
+#define bi_tbfreq bi_intfreq
+
+/* OpenBlockSS specific definitions. */
+
+/* irq */
+#define OBSS_PSH_IRQ		25
+#define OBSS_ATA0_IRQ		29
+#define OBSS_PDOWN_IRQ		30
+#define OBSS_ETH_RELINK_IRQ	31
+
+/* ata register manipulation */
+#define HAVE_ARCH_OUT_BYTE
+#define OUT_BYTE(dat,port)	(out_le16((volatile unsigned short *)port, dat & 0xFF))
+#define OUT_WORD(dat,port)	(out_be16((volatile unsigned short *)port, dat & 0xFFFF))
+
+#define HAVE_ARCH_IN_BYTE
+#define IN_BYTE(port)		(in_le16((volatile unsigned short *)port) & 0xFF)
+#define IN_WORD(port)		in_be16((volatile unsigned short *)port)
+
+/* i/o map */
+
+#define _IO_BASE	0
+#define _ISA_MEM_BASE	0
+#define PCI_DRAM_OFFSET	0
+
+/* 0x00100000 (6-byte): 405GP internal ethernet mac address */
+#define OBSS_ENET_MACADDR	((unsigned char *)(0x00100000))
+/* 0x00100006 (8-bit):  Boot mode: 0=ramdisk, 1=hdd, other=recovery(ramdisk) */
+#define OBSS_BOOT_MODE		((unsigned char *)0x00100006)
+/* 0x00100007 (8-bit):  RAM size: 4, 8, 16, 32, 64, 128=nn MB, other=unknown */
+#define OBSS_RAM_SIZE		((unsigned char *)0x00100007)
+/* 0x40000000 (8-bit):  7-segment LED (see segled.h) */
+#define OBSS_SEGLED_ADDR	((uint)0x40000000)
+#define OBSS_SEGLED_SIZE	((uint)4*1024)
+/* 0x60000000 (+0x00..0x0F: ATA registers(even byte aligned), +0x1C: ATA control register) */
+#define OBSS_ATAREG_ADDR	((uint)0x60000000)
+#define OBSS_ATAREG_SIZE	((uint)4*1024)
+/* 0x70000000 (2-byte?: ATA host controller register) */
+#define OBSS_ATACTRL_ADDR	((uint)0x70000000)
+#define OBSS_ATACTRL_SIZE	((uint)4*1024)
+
+/* overwrite default in include/asm-ppc/ide.h */
+#ifdef MAX_HWIFS
+#undef MAX_HWIFS
+#endif
+#define	MAX_HWIFS	1
+
+#define BASE_BAUD		460800
+#define PPC4xx_MACHINE_NAME	"Plat'Home OpenBlockSS"
+
+/* overwrite PM sleeper in arch/ppc/platforms/ibm405gp.h */
+#undef DFLT_IBM4xx_PM
+#define DFLT_IBM4xx_PM		~(IBM_CPM_PCI | IBM_CPM_CPU | IBM_CPM_DMA \
+					| IBM_CPM_OPB | IBM_CPM_EBC \
+					| IBM_CPM_SDRAM0 | IBM_CPM_PLB \
+					| IBM_CPM_UIC | IBM_CPM_TMRCLK \
+					| IBM_CPM_IIC0 | IBM_CPM_UART0 | IBM_CPM_UART1 \
+					| IBM_CPM_EMAC0 | 0x00010000 | 0x00008000) /* enet rm, tm unit */
+
+#define wait_hwif_ready(hwif) 0
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_OBSS_H__ */
+#endif /* __KERNEL__ */
+
diff -Naru linux-2.4.29.orig/drivers/char/serial.c linux-2.4.29/drivers/char/serial.c
--- linux-2.4.29.orig/drivers/char/serial.c	2005-01-19 23:09:50.000000000 +0900
+++ linux-2.4.29/drivers/char/serial.c	2005-02-22 02:05:05.000000000 +0900
@@ -1354,7 +1354,11 @@
 	/*
 	 * Allocate the IRQ if necessary
 	 */
+#ifdef CONFIG_OBSS
+	if ((!IRQ_ports[state->irq] ||
+#else /* CONFIG_OBSS */
 	if (state->irq && (!IRQ_ports[state->irq] ||
+#endif /* CONFIG_OBSS */
 			  !IRQ_ports[state->irq]->next_port)) {
 		if (IRQ_ports[state->irq]) {
 #ifdef CONFIG_SERIAL_SHARE_IRQ
@@ -1520,7 +1524,11 @@
 	/*
 	 * Free the IRQ, if necessary
 	 */
+#ifdef CONFIG_OBSS
+	if ((!IRQ_ports[state->irq] ||
+#else /* CONFIG_OBSS */
 	if (state->irq && (!IRQ_ports[state->irq] ||
+#endif /* CONFIG_OBSS */
 			  !IRQ_ports[state->irq]->next_port)) {
 		if (IRQ_ports[state->irq]) {
 			free_irq(state->irq, &IRQ_ports[state->irq]);
diff -Naru linux-2.4.29.orig/drivers/ide/ide-probe.c linux-2.4.29/drivers/ide/ide-probe.c
--- linux-2.4.29.orig/drivers/ide/ide-probe.c	2004-04-14 22:05:29.000000000 +0900
+++ linux-2.4.29/drivers/ide/ide-probe.c	2005-02-22 02:07:39.000000000 +0900
@@ -29,6 +29,10 @@
  * 			then fall over when they get to 256.	Paul G.
  * Version 1.10		Update set for new IDE. drive->id is now always
  *			valid after probe time even with noprobe
+ *
+ *	Century <www.centurysys.co.jp>
+ *		- Added LED display
+ *	2001-12-25 ozawa CONFIG_OBSS
  */
 
 #undef REALLY_SLOW_IO		/* most systems can safely undef this */
@@ -55,6 +59,10 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#ifdef CONFIG_OBSS
+#include <asm/segled.h>
+#define OPNT ((volatile unsigned char *)(0x40000000))
+#endif /* CONFIG_OBSS */
 
 /**
  *	generic_id		-	add a generic drive id
@@ -326,7 +334,11 @@
 		/* ask drive for ID */
 		hwif->OUTB(cmd, IDE_COMMAND_REG);
 	}
+#ifdef CONFIG_OBSS
+	timeout = ((cmd == WIN_IDENTIFY) ? (WAIT_WORSTCASE/10) : (WAIT_PIDENTIFY/10)) / 2;
+#else /* CONFIG_OBSS */
 	timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
+#endif /* CONFIG_OBSS */
 	timeout += jiffies;
 	do {
 		if (time_after(jiffies, timeout)) {
@@ -355,6 +367,9 @@
 		/* drive refused ID */
 		rc = 2;
 	}
+#ifdef CONFIG_OBSS
+	*OPNT = (unsigned char)~(SL_V3);
+#endif  /* CONFIG_OBSS */
 	return rc;
 }
 
diff -Naru linux-2.4.29.orig/include/asm-ppc/ibm4xx.h linux-2.4.29/include/asm-ppc/ibm4xx.h
--- linux-2.4.29.orig/include/asm-ppc/ibm4xx.h	2004-04-14 22:05:40.000000000 +0900
+++ linux-2.4.29/include/asm-ppc/ibm4xx.h	2005-02-22 02:08:55.000000000 +0900
@@ -82,6 +82,10 @@
 #include <platforms/walnut.h>
 #endif
 
+#if defined(CONFIG_OBSS)
+#include <platforms/obss.h>
+#endif
+
 #ifndef PPC4xx_MACHINE_NAME
 #define PPC4xx_MACHINE_NAME	"Unidentified 4xx class"
 #endif
diff -Naru linux-2.4.29.orig/include/asm-ppc/pgtable.h linux-2.4.29/include/asm-ppc/pgtable.h
--- linux-2.4.29.orig/include/asm-ppc/pgtable.h	2004-02-18 22:36:32.000000000 +0900
+++ linux-2.4.29/include/asm-ppc/pgtable.h	2005-02-22 02:10:02.000000000 +0900
@@ -630,8 +630,14 @@
  * (if used).  -- paulus
  */
 #define SWP_TYPE(entry)			((entry).val & 0x3f)
+#ifdef CONFIG_OBSS
+/* swapoff fix by hirano yositaka */
+#define SWP_OFFSET(entry)		((entry).val >> 10)
+#define SWP_ENTRY(type, offset)		((swp_entry_t) { (type) | ((offset) << 10) })
+#else /* CONFIG_OBSS */
 #define SWP_OFFSET(entry)		((entry).val >> 6)
 #define SWP_ENTRY(type, offset)		((swp_entry_t) { (type) | ((offset) << 6) })
+#endif /* CONFIG_OBSS */
 #define pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) >> 2 })
 #define swp_entry_to_pte(x)		((pte_t) { (x).val << 2 })
 
diff -Naru linux-2.4.29.orig/include/asm-ppc/pushsw.h linux-2.4.29/include/asm-ppc/pushsw.h
--- linux-2.4.29.orig/include/asm-ppc/pushsw.h	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.4.29/include/asm-ppc/pushsw.h	2005-02-22 02:10:41.000000000 +0900
@@ -0,0 +1,20 @@
+/*
+ *	Century <www.centurysys.co.jp>
+ *		- Century's push switch driver header
+ */
+
+#include <linux/ioctl.h>
+#include <linux/major.h>
+/* #include <linux/miscdevice.h> */
+
+#define PUSHSW_MAJOR		(MISC_MAJOR)
+
+#define	PUSHSW_IOCTL_BASE	'P'
+
+#define	PSWIOC_GETSTATUS	_IOR(PUSHSW_IOCTL_BASE, 0, int)
+#define	PSWIOC_WAITPUSH		_IOR(PUSHSW_IOCTL_BASE, 1, int)
+#define	PSWIOC_GETWAITPID	_IOR(PUSHSW_IOCTL_BASE, 2, int)
+
+#define PSWIOF_PUSHED		(1)
+#define PSWIOF_NOTPUSHED	(0)
+
diff -Naru linux-2.4.29.orig/include/asm-ppc/segled.h linux-2.4.29/include/asm-ppc/segled.h
--- linux-2.4.29.orig/include/asm-ppc/segled.h	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.4.29/include/asm-ppc/segled.h	2005-02-22 02:11:36.000000000 +0900
@@ -0,0 +1,63 @@
+/*
+ * 	Century <www.centurysys.co.jp>
+ *		- Header for Century's 7 segment LED driver
+ *
+ */
+
+#include <linux/ioctl.h>
+#include <linux/major.h>
+/* #include <linux/miscdevice.h> */
+
+#define SEGLED_MAJOR		(MISC_MAJOR)
+
+#define	SEGLED_IOCTL_BASE	'S'
+
+#define	SLIOC_TEST		_IOR(SEGLED_IOCTL_BASE, 0, int)
+#define	SLIOC_SETVAL		_IOR(SEGLED_IOCTL_BASE, 1, int)
+#define	SLIOC_SETSEG		_IOR(SEGLED_IOCTL_BASE, 2, int)
+#define SLIOC_GET_OWNER_PID	_IOR(SEGLED_IOCTL_BASE, 3, int)
+#define SLIOC_RESERVE		_IOR(SEGLED_IOCTL_BASE, 4, int)
+#define	SLIOC_TEST405		_IOR(SEGLED_IOCTL_BASE, 5, int)
+
+/* @@ MA 360 boards
+#define SL_A	(0x01)
+#define SL_B	(0x02)
+#define SL_C	(0x80)
+#define SL_D	(0x20)
+#define SL_E	(0x40)
+#define SL_F	(0x04)
+#define SL_G	(0x08)
+#define SL_DP	(0x10)
+#define SL_NONE	(0x00)
+#define SL_ALL	(SL_A | SL_B | SL_C | SL_D | SL_E | SL_F | SL_G | SL_DP)
+*/
+
+/* @@ MA 300 */
+#define SL_A	(0x08)
+#define SL_B	(0x04)
+#define SL_C	(0x01)
+#define SL_D	(0x10)
+#define SL_E	(0x20)
+#define SL_F	(0x02)
+#define SL_G	(0x80)
+#define SL_DP	(0x40)
+#define SL_NONE	(0x00)
+#define SL_ALL	(SL_A | SL_B | SL_C | SL_D | SL_E | SL_F | SL_G | SL_DP)
+
+#define SL_V0	(SL_A | SL_B | SL_C | SL_D | SL_E | SL_F)
+#define SL_V1	(SL_B | SL_C)
+#define SL_V2	(SL_A | SL_B | SL_D | SL_E | SL_G)
+#define SL_V3	(SL_A | SL_B | SL_C | SL_D | SL_G)
+#define SL_V4	(SL_B | SL_C | SL_F | SL_G)
+#define SL_V5	(SL_C | SL_F | SL_A | SL_G | SL_D)
+#define SL_V6	(SL_C | SL_F | SL_A | SL_G | SL_E | SL_D)
+#define SL_V7	(SL_C | SL_F | SL_B | SL_A)
+#define SL_V8	(SL_A | SL_B | SL_C | SL_D | SL_E | SL_F | SL_G)
+#define SL_V9	(SL_A | SL_B | SL_C | SL_D | SL_F | SL_G)
+#define SL_VA	(SL_A | SL_B | SL_C | SL_E | SL_F | SL_G)
+#define SL_VB	(SL_C | SL_F | SL_G | SL_E | SL_D)
+#define SL_VC	(SL_F | SL_A | SL_E | SL_D)
+#define SL_VD	(SL_C | SL_B | SL_G | SL_E | SL_D)
+#define SL_VE	(SL_F | SL_A | SL_G | SL_E | SL_D)
+#define SL_VF	(SL_F | SL_A | SL_G | SL_E)
+
diff -Naru linux-2.4.29.orig/init/do_mounts.c linux-2.4.29/init/do_mounts.c
--- linux-2.4.29.orig/init/do_mounts.c	2003-11-29 03:26:21.000000000 +0900
+++ linux-2.4.29/init/do_mounts.c	2005-02-22 02:13:53.000000000 +0900
@@ -16,6 +16,10 @@
 #include <linux/ext2_fs.h>
 #include <linux/romfs_fs.h>
 #include <linux/cramfs_fs.h>
+#ifdef CONFIG_OBSS
+#include <asm/segled.h>
+#define OPNT ((volatile unsigned char *)(0x40000000))
+#endif /* CONFIG_OBSS */
 
 #define BUILD_CRAMDISK
 
@@ -648,6 +652,10 @@
 		goto done;
 	}
 
+#ifdef CONFIG_OBSS
+	*OPNT = (unsigned char)~(SL_V5);
+#endif  /* CONFIG_OBSS */
+
 	printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%ld disk%s] into ram disk... ", 
 		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
 	for (i=0; i < nblocks; i++) {
@@ -906,6 +914,10 @@
 	do_devfs = 1;
 #endif
 
+#ifdef CONFIG_OBSS
+	*OPNT = (unsigned char)~(SL_V4);
+#endif /* CONFIG_OBSS */
+
 	create_dev("/dev/root", ROOT_DEV, NULL);
 	if (mount_initrd) {
 		if (initrd_load() && ROOT_DEV != MKDEV(RAMDISK_MAJOR, 0)) {
diff -Naru linux-2.4.29.orig/init/main.c linux-2.4.29/init/main.c
--- linux-2.4.29.orig/init/main.c	2004-11-17 20:54:22.000000000 +0900
+++ linux-2.4.29/init/main.c	2005-02-22 02:15:33.000000000 +0900
@@ -7,6 +7,11 @@
  *  Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
  *  Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
  *  Simplified starting of init:  Michael A. Griffith <grif@acm.org> 
+ *
+ *	Century <www.centurysys.co.jp>
+ *		- Added LED display
+ *		- Added recovery mode handling
+ *	2001-12-25 ozawa CONFIG_OBSS
  */
 
 #define __KERNEL_SYSCALLS__
@@ -31,6 +36,10 @@
 
 #include <asm/io.h>
 #include <asm/bugs.h>
+#ifdef CONFIG_OBSS
+#include <asm/segled.h>
+#define OPNT ((volatile unsigned char *)(0x40000000))
+#endif /* CONFIG_OBSS */
 
 #if defined(CONFIG_ARCH_S390)
 #include <asm/s390mach.h>
@@ -471,6 +480,9 @@
  */
 static void __init do_basic_setup(void)
 {
+#ifdef CONFIG_OBSS
+	*OPNT = (unsigned char)~(SL_V2);
+#endif  /* CONFIG_OBSS */
 
 	/*
 	 * Tell the world that we're going to be the grim
@@ -598,6 +610,10 @@
 	 * trying to recover a really broken machine.
 	 */
 
+#ifdef CONFIG_OBSS
+	*OPNT = (unsigned char)~(SL_V6);
+#endif /* CONFIG_OBSS */
+
 	if (execute_command)
 		run_init_process(execute_command);
 
