Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile
new file mode 100644
index 0000000..b21bc68
--- /dev/null
+++ b/arch/mips/mips-boards/generic/Makefile
@@ -0,0 +1,26 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Makefile for the MIPS boards generic routines under Linux.
+#
+
+obj-y				:= mipsIRQ.o reset.o display.o init.o memory.o \
+				   printf.o cmdline.o time.o
+obj-$(CONFIG_PCI)		+= pci.o
+obj-$(CONFIG_KGDB)		+= gdb_hook.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mips-boards/generic/cmdline.c
new file mode 100644
index 0000000..1871c30
--- /dev/null
+++ b/arch/mips/mips-boards/generic/cmdline.c
@@ -0,0 +1,59 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Kernel command line creation using the prom monitor (YAMON) argc/argv.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+extern int prom_argc;
+extern int *_prom_argv;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(long)_prom_argv[(index)])
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv(actr));
+		cp += strlen(prom_argv(actr));
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) {
+		/* get rid of trailing space */
+		--cp;
+		*cp = '\0';
+	}
+}
diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c
new file mode 100644
index 0000000..f653946
--- /dev/null
+++ b/arch/mips/mips-boards/generic/display.c
@@ -0,0 +1,39 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Display routines for display messages in MIPS boards ascii display.
+ */
+
+#include <linux/compiler.h>
+#include <asm/io.h>
+#include <asm/mips-boards/generic.h>
+
+void mips_display_message(const char *str)
+{
+	static volatile unsigned int *display = NULL;
+	int i;
+
+	if (unlikely(display == NULL))
+		display = (volatile unsigned int *)ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int));
+
+	for (i = 0; i <= 14; i=i+2) {
+	         if (*str)
+		         display[i] = *str++;
+		 else
+		         display[i] = ' ';
+	}
+}
diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c
new file mode 100644
index 0000000..91a2ccb
--- /dev/null
+++ b/arch/mips/mips-boards/generic/gdb_hook.c
@@ -0,0 +1,133 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * This is the interface to the remote debugger stub.
+ */
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#include <asm/serial.h>
+#include <asm/io.h>
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+
+static struct async_struct kdb_port_info = {0};
+
+int (*generic_putDebugChar)(char);
+char (*generic_getDebugChar)(void);
+
+static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
+{
+	return inb(info->port + offset);
+}
+
+static __inline__ void serial_out(struct async_struct *info, int offset,
+				int value)
+{
+	outb(value, info->port+offset);
+}
+
+int rs_kgdb_hook(int tty_no, int speed) {
+	int t;
+	struct serial_state *ser = &rs_table[tty_no];
+
+	kdb_port_info.state = ser;
+	kdb_port_info.magic = SERIAL_MAGIC;
+	kdb_port_info.port = ser->port;
+	kdb_port_info.flags = ser->flags;
+
+	/*
+	 * Clear all interrupts
+	 */
+	serial_in(&kdb_port_info, UART_LSR);
+	serial_in(&kdb_port_info, UART_RX);
+	serial_in(&kdb_port_info, UART_IIR);
+	serial_in(&kdb_port_info, UART_MSR);
+
+	/*
+	 * Now, initialize the UART
+	 */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
+	if (kdb_port_info.flags & ASYNC_FOURPORT) {
+		kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
+		t = UART_MCR_DTR | UART_MCR_OUT1;
+	} else {
+		kdb_port_info.MCR
+			= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
+		t = UART_MCR_DTR | UART_MCR_RTS;
+	}
+
+	kdb_port_info.MCR = t;		/* no interrupts, please */
+	serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
+
+	/*
+	 * and set the speed of the serial port
+	 */
+	if (speed == 0)
+		speed = 9600;
+
+	t = kdb_port_info.state->baud_base / speed;
+	/* set DLAB */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
+	serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
+	serial_out(&kdb_port_info, UART_DLM, t >> 8);  /* MS of divisor */
+	/* reset DLAB */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
+
+	return speed;
+}
+
+int putDebugChar(char c)
+{
+	return generic_putDebugChar(c);
+}
+
+char getDebugChar(void)
+{
+	return generic_getDebugChar();
+}
+
+int rs_putDebugChar(char c)
+{
+
+	if (!kdb_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
+		;
+
+	serial_out(&kdb_port_info, UART_TX, c);
+
+	return 1;
+}
+
+char rs_getDebugChar(void)
+{
+	if (!kdb_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
+		;
+
+	return serial_in(&kdb_port_info, UART_RX);
+}
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
new file mode 100644
index 0000000..31caf06
--- /dev/null
+++ b/arch/mips/mips-boards/generic/init.c
@@ -0,0 +1,343 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * PROM library initialisation code.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/generic.h>
+#ifdef CONFIG_MIPS_GT64120
+#include <asm/gt64120.h>
+#endif
+#include <asm/mips-boards/msc01_pci.h>
+#include <asm/mips-boards/bonito64.h>
+#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/malta.h>
+#endif
+
+#ifdef CONFIG_KGDB
+extern int rs_kgdb_hook(int, int);
+extern int rs_putDebugChar(char);
+extern char rs_getDebugChar(void);
+extern int saa9730_kgdb_hook(int);
+extern int saa9730_putDebugChar(char);
+extern char saa9730_getDebugChar(void);
+#endif
+
+int prom_argc;
+int *_prom_argv, *_prom_envp;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension, if running in 64-bit mode.
+ */
+#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
+
+int init_debug = 0;
+
+unsigned int mips_revision_corid;
+
+/* Bonito64 system controller register base. */
+unsigned long _pcictrl_bonito;
+unsigned long _pcictrl_bonito_pcicfg;
+
+/* GT64120 system controller register base */
+unsigned long _pcictrl_gt64120;
+
+/* MIPS System controller register base */
+unsigned long _pcictrl_msc;
+
+char *prom_getenv(char *envname)
+{
+	/*
+	 * Return a pointer to the given environment variable.
+	 * In 64-bit mode: we're using 64-bit pointers, but all pointers
+	 * in the PROM structures are only 32-bit, so we need some
+	 * workarounds, if we are running in 64-bit mode.
+	 */
+	int i, index=0;
+
+	i = strlen(envname);
+
+	while (prom_envp(index)) {
+		if(strncmp(envname, prom_envp(index), i) == 0) {
+			return(prom_envp(index+1));
+		}
+		index += 2;
+	}
+
+	return NULL;
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	return 0; /* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if((*str == '.') || (*str == ':'))
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+        char *ethaddr_str;
+
+        ethaddr_str = prom_getenv("ethaddr");
+	if (!ethaddr_str) {
+	        printk("ethaddr not set in boot prom\n");
+		return -1;
+	}
+	str2eaddr(ethernet_addr, ethaddr_str);
+
+	if (init_debug > 1) {
+	        int i;
+		printk("get_ethernet_addr: ");
+	        for (i=0; i<5; i++)
+		        printk("%02x:", (unsigned char)*(ethernet_addr+i));
+		printk("%02x\n", *(ethernet_addr+i));
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static void __init console_config(void)
+{
+	char console_string[40];
+	int baud = 0;
+	char parity = '\0', bits = '\0', flow = '\0';
+	char *s;
+
+	if ((strstr(prom_getcmdline(), "console=ttyS")) == NULL) {
+		s = prom_getenv("modetty0");
+		if (s) {
+			while (*s >= '0' && *s <= '9')
+				baud = baud*10 + *s++ - '0';
+			if (*s == ',') s++;
+			if (*s) parity = *s++;
+			if (*s == ',') s++;
+			if (*s) bits = *s++;
+			if (*s == ',') s++;
+			if (*s == 'h') flow = 'r';
+		}
+		if (baud == 0)
+			baud = 38400;
+		if (parity != 'n' && parity != 'o' && parity != 'e')
+			parity = 'n';
+		if (bits != '7' && bits != '8')
+			bits = '8';
+		if (flow == '\0')
+			flow = 'r';
+		sprintf (console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow);
+		strcat (prom_getcmdline(), console_string);
+		prom_printf("Config serial console:%s\n", console_string);
+	}
+}
+#endif
+
+#ifdef CONFIG_KGDB
+void __init kgdb_config (void)
+{
+	extern int (*generic_putDebugChar)(char);
+	extern char (*generic_getDebugChar)(void);
+	char *argptr;
+	int line, speed;
+
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
+		argptr += strlen("kgdb=ttyS");
+		if (*argptr != '0' && *argptr != '1')
+			printk("KGDB: Unknown serial line /dev/ttyS%c, "
+			       "falling back to /dev/ttyS1\n", *argptr);
+		line = *argptr == '0' ? 0 : 1;
+		printk("KGDB: Using serial line /dev/ttyS%d for session\n", line);
+
+		speed = 0;
+		if (*++argptr == ',')
+		{
+			int c;
+			while ((c = *++argptr) && ('0' <= c && c <= '9'))
+				speed = speed * 10 + c - '0';
+		}
+#ifdef CONFIG_MIPS_ATLAS
+		if (line == 1) {
+			speed = saa9730_kgdb_hook(speed);
+			generic_putDebugChar = saa9730_putDebugChar;
+			generic_getDebugChar = saa9730_getDebugChar;
+		}
+		else 
+#endif
+		{
+			speed = rs_kgdb_hook(line, speed);
+			generic_putDebugChar = rs_putDebugChar;
+			generic_getDebugChar = rs_getDebugChar;
+		}
+
+		prom_printf("KGDB: Using serial line /dev/ttyS%d at %d for session, "
+			    "please connect your debugger\n", line ? 1 : 0, speed);
+
+		{
+			char *s;
+			for (s = "Please connect GDB to this port\r\n"; *s; )
+				generic_putDebugChar (*s++);
+		}
+
+		kgdb_enabled = 1;
+		/* Breakpoint is invoked after interrupts are initialised */
+	}
+}
+#endif
+
+void __init prom_init(void)
+{
+	prom_argc = fw_arg0;
+	_prom_argv = (int *) fw_arg1;
+	_prom_envp = (int *) fw_arg2;
+
+	mips_display_message("LINUX");
+
+#ifdef CONFIG_MIPS_SEAD
+	set_io_port_base(KSEG1);
+#else
+	/*
+	 * early setup of _pcictrl_bonito so that we can determine
+	 * the system controller on a CORE_EMUL board
+	 */
+	_pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE);
+
+	mips_revision_corid = MIPS_REVISION_CORID;
+
+	if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) {
+		if (BONITO_PCIDID == 0x0001df53 || 
+		    BONITO_PCIDID == 0x0003df53)
+			mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON;
+		else
+			mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC;
+	}
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	case MIPS_REVISION_CORID_CORE_FPGAR2:
+		/*
+		 * Setup the North bridge to do Master byte-lane swapping
+		 * when running in bigendian.
+		 */
+		_pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000);
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+		GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
+			 GT_PCI0_CMD_SBYTESWAP_BIT);
+#else
+		GT_WRITE(GT_PCI0_CMD_OFS, 0);
+#endif
+
+#ifdef CONFIG_MIPS_MALTA
+		set_io_port_base(MALTA_GT_PORT_BASE);
+#else
+		set_io_port_base((unsigned long)ioremap(0, 0x20000000));
+#endif
+		break;
+
+	case MIPS_REVISION_CORID_CORE_EMUL_BON:
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+		_pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE);
+
+		/*
+		 * Disable Bonito IOBC.
+		 */
+		BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
+			~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
+			  BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
+
+		/*
+		 * Setup the North bridge to do Master byte-lane swapping
+		 * when running in bigendian.
+		 */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+		BONITO_BONGENCFG = BONITO_BONGENCFG &
+			~(BONITO_BONGENCFG_MSTRBYTESWAP |
+			  BONITO_BONGENCFG_BYTESWAP);
+#else
+		BONITO_BONGENCFG = BONITO_BONGENCFG |
+			BONITO_BONGENCFG_MSTRBYTESWAP |
+			BONITO_BONGENCFG_BYTESWAP;
+#endif
+
+#ifdef CONFIG_MIPS_MALTA
+		set_io_port_base(MALTA_BONITO_PORT_BASE);
+#else
+		set_io_port_base((unsigned long)ioremap(0, 0x20000000));
+#endif
+		break;
+
+	case MIPS_REVISION_CORID_CORE_MSC:
+	case MIPS_REVISION_CORID_CORE_FPGA2:
+	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+		_pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); 
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+		MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
+#else
+		MSC_WRITE(MSC01_PCI_SWAP,
+			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
+			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
+			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
+#endif
+
+#ifdef CONFIG_MIPS_MALTA
+		set_io_port_base(MALTA_MSC_PORT_BASE);
+#else
+		set_io_port_base((unsigned long)ioremap(0, 0x20000000));
+#endif
+		break;
+
+	default:
+		/* Unknown Core card */
+		mips_display_message("CC Error");
+		while(1);   /* We die here... */
+	}
+#endif
+	prom_printf("\nLINUX started...\n");
+	prom_init_cmdline();
+	prom_meminit();
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	console_config();
+#endif
+}
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
new file mode 100644
index 0000000..5ae2b43
--- /dev/null
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -0,0 +1,173 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * PROM library functions for acquiring/using memory descriptors given to
+ * us from the YAMON.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+
+#include <asm/mips-boards/prom.h>
+
+/*#define DEBUG*/
+
+enum yamon_memtypes {
+	yamon_dontuse,
+	yamon_prom,
+	yamon_free,
+};
+struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+#ifdef DEBUG
+static char *mtypes[3] = {
+	"Dont use memory",
+	"YAMON PROM memory",
+	"Free memmory",
+};
+#endif
+
+/* References to section boundaries */
+extern char _end;
+
+#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+
+struct prom_pmemblock * __init prom_getmdesc(void)
+{
+	char *memsize_str;
+	unsigned int memsize;
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
+		memsize = 0x02000000;
+	} else {
+#ifdef DEBUG
+		prom_printf("prom_memsize = %s\n", memsize_str);
+#endif
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+
+	memset(mdesc, 0, sizeof(mdesc));
+
+	mdesc[0].type = yamon_dontuse;
+	mdesc[0].base = 0x00000000;
+	mdesc[0].size = 0x00001000;
+
+	mdesc[1].type = yamon_prom;
+	mdesc[1].base = 0x00001000;
+	mdesc[1].size = 0x000ef000;
+
+#ifdef CONFIG_MIPS_MALTA
+	/*
+	 * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
+	 * south bridge and PCI access always forwarded to the ISA Bus and
+	 * BIOSCS# is always generated.
+	 * This mean that this area can't be used as DMA memory for PCI
+	 * devices.
+	 */
+	mdesc[2].type = yamon_dontuse;
+	mdesc[2].base = 0x000f0000;
+	mdesc[2].size = 0x00010000;
+#else
+	mdesc[2].type = yamon_prom;
+	mdesc[2].base = 0x000f0000;
+	mdesc[2].size = 0x00010000;
+#endif
+
+	mdesc[3].type = yamon_dontuse;
+	mdesc[3].base = 0x00100000;
+	mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base;
+
+	mdesc[4].type = yamon_free;
+	mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
+	mdesc[4].size = memsize - mdesc[4].base;
+
+	return &mdesc[0];
+}
+
+static int __init prom_memtype_classify (unsigned int type)
+{
+	switch (type) {
+	case yamon_free:
+		return BOOT_MEM_RAM;
+	case yamon_prom:
+		return BOOT_MEM_ROM_DATA;
+	default:
+		return BOOT_MEM_RESERVED;
+	}
+}
+
+void __init prom_meminit(void)
+{
+	struct prom_pmemblock *p;
+
+#ifdef DEBUG
+	prom_printf("YAMON MEMORY DESCRIPTOR dump:\n");
+	p = prom_getmdesc();
+	while (p->size) {
+		int i = 0;
+		prom_printf("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n",
+			    i, p, p->base, p->size, mtypes[p->type]);
+		p++;
+		i++;
+	}
+#endif
+	p = prom_getmdesc();
+
+	while (p->size) {
+		long type;
+		unsigned long base, size;
+
+		type = prom_memtype_classify (p->type);
+		base = p->base;
+		size = p->size;
+
+		add_memory_region(base, size, type);
+                p++;
+	}
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	unsigned long freed = 0;
+	unsigned long addr;
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+			continue;
+
+		addr = boot_mem_map.map[i].addr;
+		while (addr < boot_mem_map.map[i].addr
+			      + boot_mem_map.map[i].size) {
+			ClearPageReserved(virt_to_page(__va(addr)));
+			set_page_count(virt_to_page(__va(addr)), 1);
+			free_page((unsigned long)__va(addr));
+			addr += PAGE_SIZE;
+			freed += PAGE_SIZE;
+		}
+	}
+	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+
+	return freed;
+}
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S
new file mode 100644
index 0000000..131f49b
--- /dev/null
+++ b/arch/mips/mips-boards/generic/mipsIRQ.S
@@ -0,0 +1,153 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Interrupt exception dispatch code.
+ *
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ *    common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ *    would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ *    between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the MIPS board look basically (barring software
+ * IRQs which we don't use at all and all external interrupt sources are
+ * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Combined hardware interrupt (hw0)
+ *             3        Hardware (ignored)
+ *             4        Hardware (ignored)
+ *             5        Hardware (ignored)
+ *             6        Hardware (ignored)
+ *             7        R4k timer (what we use)
+ *
+ * Note: On the SEAD board thing are a little bit different.
+ *       Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
+ *       wired to UART1.
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ * Lowest  ----     Combined hardware interrupt
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(mipsIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+
+	mfc0	s0, CP0_CAUSE		# get irq bits
+	mfc0	s1, CP0_STATUS		# get irq mask
+	and	s0, s1
+
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP2	# delay slot, check hw0 interrupt
+
+	/* Wheee, a timer interrupt. */
+	move	a0, sp
+	jal	mips_timer_interrupt
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+#if defined(CONFIG_MIPS_SEAD)
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP3	# delay slot, check hw1 interrupt
+#else
+	beq	a0, zero, 1f		# delay slot, check hw3 interrupt
+ 	 andi	a0, s0, CAUSEF_IP5
+#endif
+
+	/* Wheee, combined hardware level zero interrupt. */
+#if defined(CONFIG_MIPS_ATLAS)
+	jal	atlas_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_MALTA)
+	jal	malta_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_SEAD)
+	jal	sead_hw0_irqdispatch
+#else
+#error "MIPS board not supported\n"
+#endif
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+#if defined(CONFIG_MIPS_SEAD)
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP5	# delay slot, check hw3 interrupt
+	jal	sead_hw1_irqdispatch
+	 move	a0, sp			# delay slot
+	j	ret_from_irq
+	 nop				# delay slot
+1:
+#endif
+#if defined(CONFIG_MIPS_MALTA)
+	beq	a0, zero, 1f            # check hw3 (coreHI) interrupt
+	 nop
+	jal	corehi_irqdispatch
+	 move	a0, sp
+	j	ret_from_irq
+	 nop
+1:
+#endif
+	/*
+	 * Here by mistake?  This is possible, what can happen is that by the
+	 * time we take the exception the IRQ pin goes low, so just leave if
+	 * this is the case.
+	 */
+	move	a1,s0
+	PRINT("Got interrupt: c0_cause = %08x\n")
+	mfc0	a1, CP0_EPC
+	PRINT("c0_epc = %08x\n")
+
+	j	ret_from_irq
+	 nop
+	END(mipsIRQ)
diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c
new file mode 100644
index 0000000..92c34bd
--- /dev/null
+++ b/arch/mips/mips-boards/generic/pci.c
@@ -0,0 +1,163 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS boards specific PCI support.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/gt64120.h>
+#include <asm/mips-boards/bonito64.h>
+#include <asm/mips-boards/msc01_pci.h>
+#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/malta.h>
+#endif
+
+static struct resource bonito64_mem_resource = {
+	.name	= "Bonito PCI MEM",
+	.start	= 0x10000000UL,
+	.end	= 0x1bffffffUL,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource bonito64_io_resource = {
+	.name	= "Bonito IO MEM",
+	.start	= 0x00002000UL,	/* avoid conflicts with YAMON allocated I/O addresses */
+	.end	= 0x000fffffUL,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource gt64120_mem_resource = {
+	.name	= "GT64120 PCI MEM",
+	.start	= 0x10000000UL,
+	.end	= 0x1bdfffffUL,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource gt64120_io_resource = {
+	.name	= "GT64120 IO MEM",
+#ifdef CONFIG_MIPS_ATLAS
+	.start	= 0x18000000UL,
+	.end	= 0x181fffffUL,
+#endif
+#ifdef CONFIG_MIPS_MALTA
+	.start	= 0x00002000UL,
+	.end	= 0x001fffffUL,
+#endif
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource msc_mem_resource = {
+	.name	= "MSC PCI MEM",
+	.start	= 0x10000000UL,
+	.end	= 0x1fffffffUL,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource msc_io_resource = {
+	.name	= "MSC IO MEM",
+	.start	= 0x00002000UL,
+	.end	= 0x007fffffUL,
+	.flags	= IORESOURCE_IO,
+};
+
+extern struct pci_ops bonito64_pci_ops;
+extern struct pci_ops gt64120_pci_ops;
+extern struct pci_ops msc_pci_ops;
+
+static struct pci_controller bonito64_controller = {
+	.pci_ops	= &bonito64_pci_ops,
+	.io_resource	= &bonito64_io_resource,
+	.mem_resource	= &bonito64_mem_resource,
+	.mem_offset	= 0x10000000UL,
+	.io_offset	= 0x00000000UL,
+};
+
+static struct pci_controller gt64120_controller = {
+	.pci_ops	= &gt64120_pci_ops,
+	.io_resource	= &gt64120_io_resource,
+	.mem_resource	= &gt64120_mem_resource,
+	.mem_offset	= 0x00000000UL,
+	.io_offset	= 0x00000000UL,
+};
+
+static struct pci_controller  msc_controller = {
+	.pci_ops	= &msc_pci_ops,
+	.io_resource	= &msc_io_resource,
+	.mem_resource	= &msc_mem_resource,
+	.mem_offset	= 0x10000000UL,
+	.io_offset	= 0x00000000UL,
+};
+
+static int __init pcibios_init(void)
+{
+	struct pci_controller *controller;
+
+	switch (mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	case MIPS_REVISION_CORID_CORE_FPGAR2:
+		/*
+		 * Due to a bug in the Galileo system controller, we need
+		 * to setup the PCI BAR for the Galileo internal registers.
+		 * This should be done in the bios/bootprom and will be
+		 * fixed in a later revision of YAMON (the MIPS boards
+		 * boot prom).
+		 */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS,
+			 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
+			 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
+			 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
+			 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
+			 GT_PCI0_CFGADDR_CONFIGEN_BIT );
+
+		/* Perform the write */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
+
+		controller = &gt64120_controller;
+		break;
+
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+	case MIPS_REVISION_CORID_CORE_EMUL_BON:
+		controller = &bonito64_controller;
+		break;
+
+	case MIPS_REVISION_CORID_CORE_MSC:
+	case MIPS_REVISION_CORID_CORE_FPGA2:
+	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+		controller = &msc_controller;
+		break;
+	default:
+		return 1;
+	}
+
+	ioport_resource.end = controller->io_resource->end;
+
+	register_pci_controller (controller);
+
+	return 0;
+}
+
+early_initcall(pcibios_init);
diff --git a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/printf.c
new file mode 100644
index 0000000..2c1ab1f
--- /dev/null
+++ b/arch/mips/mips-boards/generic/printf.c
@@ -0,0 +1,79 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Putting things on the screen/serial line using YAMONs facilities.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/serial_reg.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_MIPS_ATLAS
+#include <asm/mips-boards/atlas.h>
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define PORT(offset) (ATLAS_UART_REGS_BASE     + ((offset)<<3))
+#else
+#define PORT(offset) (ATLAS_UART_REGS_BASE + 3 + ((offset)<<3))
+#endif
+
+#elif defined(CONFIG_MIPS_SEAD)
+
+#include <asm/mips-boards/sead.h>
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define PORT(offset) (SEAD_UART0_REGS_BASE     + ((offset)<<3))
+#else
+#define PORT(offset) (SEAD_UART0_REGS_BASE + 3 + ((offset)<<3))
+#endif
+
+#else
+
+#define PORT(offset) (0x3f8 + (offset))
+
+#endif
+
+static inline unsigned int serial_in(int offset)
+{
+	return inb(PORT(offset));
+}
+
+static inline void serial_out(int offset, int value)
+{
+	outb(value, PORT(offset));
+}
+
+int prom_putchar(char c)
+{
+	while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
+		;
+
+	serial_out(UART_TX, c);
+
+	return 1;
+}
+
+char prom_getchar(void)
+{
+	while (!(serial_in(UART_LSR) & UART_LSR_DR))
+		;
+
+	return serial_in(UART_RX);
+}
+
diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c
new file mode 100644
index 0000000..9fdec74
--- /dev/null
+++ b/arch/mips/mips-boards/generic/reset.c
@@ -0,0 +1,73 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Reset the MIPS boards.
+ *
+ */
+#include <linux/config.h>
+
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/mips-boards/generic.h>
+#if defined(CONFIG_MIPS_ATLAS)
+#include <asm/mips-boards/atlas.h>
+#endif
+
+static void mips_machine_restart(char *command);
+static void mips_machine_halt(void);
+#if defined(CONFIG_MIPS_ATLAS)
+static void atlas_machine_power_off(void);
+#endif
+
+static void mips_machine_restart(char *command)
+{
+        volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int));
+
+	*softres_reg = GORESET;
+}
+
+static void mips_machine_halt(void)
+{
+        volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int));
+
+	*softres_reg = GORESET;
+}
+
+#if defined(CONFIG_MIPS_ATLAS)
+static void atlas_machine_power_off(void)
+{
+        volatile unsigned int *psustby_reg = (unsigned int *)ioremap(ATLAS_PSUSTBY_REG, sizeof(unsigned int));
+
+	*psustby_reg = ATLAS_GOSTBY;
+}
+#endif
+
+void mips_reboot_setup(void)
+{
+	_machine_restart = mips_machine_restart;
+	_machine_halt = mips_machine_halt;
+#if defined(CONFIG_MIPS_ATLAS)
+	_machine_power_off = atlas_machine_power_off;
+#endif
+#if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD)
+	_machine_power_off = mips_machine_halt;
+#endif
+}
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
new file mode 100644
index 0000000..fe7fc17
--- /dev/null
+++ b/arch/mips/mips-boards/generic/time.c
@@ -0,0 +1,167 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/div64.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/mc146818-time.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+unsigned long cpu_khz;
+
+#if defined(CONFIG_MIPS_SEAD)
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5)
+#else
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+#endif
+
+#if defined(CONFIG_MIPS_ATLAS)
+static char display_string[] = "        LINUX ON ATLAS       ";
+#endif
+#if defined(CONFIG_MIPS_MALTA)
+static char display_string[] = "        LINUX ON MALTA       ";
+#endif
+#if defined(CONFIG_MIPS_SEAD)
+static char display_string[] = "        LINUX ON SEAD       ";
+#endif
+static unsigned int display_count = 0;
+#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
+
+#define MIPS_CPU_TIMER_IRQ (NR_IRQS-1)
+
+static unsigned int timer_tick_count=0;
+
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+	if ((timer_tick_count++ % HZ) == 0) {
+		mips_display_message(&display_string[display_count++]);
+		if (display_count == MAX_DISPLAY_COUNT)
+		        display_count = 0;
+
+	}
+
+	ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs);
+}
+
+/*
+ * Estimate CPU frequency.  Sets mips_counter_frequency as a side-effect
+ */
+static unsigned int __init estimate_cpu_frequency(void)
+{
+	unsigned int prid = read_c0_prid() & 0xffff00;
+	unsigned int count;
+
+#ifdef CONFIG_MIPS_SEAD
+	/*
+	 * The SEAD board doesn't have a real time clock, so we can't
+	 * really calculate the timer frequency
+	 * For now we hardwire the SEAD board frequency to 12MHz.
+	 */
+	
+	if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
+	    (prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
+		count = 12000000;
+	else
+		count = 6000000;
+#endif
+#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA)
+	unsigned int flags;
+
+	local_irq_save(flags);
+
+	/* Start counter exactly on falling edge of update flag */
+	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+	/* Start r4k counter. */
+	write_c0_count(0);
+
+	/* Read counter exactly on falling edge of update flag */
+	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+	count = read_c0_count();
+
+	/* restore interrupts */
+	local_irq_restore(flags);
+#endif
+
+	mips_hpt_frequency = count;
+	if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
+	    (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
+		count *= 2;
+
+	count += 5000;    /* round */
+	count -= count%10000;
+
+	return count;
+}
+
+unsigned long __init mips_rtc_get_time(void)
+{
+	return mc146818_get_cmos_time();
+}
+
+void __init mips_time_init(void)
+{
+	unsigned int est_freq, flags;
+
+	local_irq_save(flags);
+
+#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA)
+        /* Set Data mode - binary. */
+        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+#endif
+
+	est_freq = estimate_cpu_frequency ();
+
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+	       (est_freq%1000000)*100/1000000);
+
+        cpu_khz = est_freq / 1000;
+
+	local_irq_restore(flags);
+}
+
+void __init mips_timer_setup(struct irqaction *irq)
+{
+	/* we are using the cpu counter for timer interrupts */
+	irq->handler = no_action;     /* we use our own handler */
+	setup_irq(MIPS_CPU_TIMER_IRQ, irq);
+
+        /* to generate the first timer interrupt */
+	write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ);
+	set_c0_status(ALLINTS);
+}