Submitted By: Jim Gifford (patches at jg555 dot com)
Date: 2007-02-24
Initial Package Version: 2.6.20.1
Origin: Linux-MIPS
Upstream Status: http://www.linux-mips.org/pub/linux/mips/kernel/v2.6/
diff -Naur linux-2.6.20.1.orig/arch/mips/Kconfig linux-2.6.20.1/arch/mips/Kconfig
--- linux-2.6.20.1.orig/arch/mips/Kconfig	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/Kconfig	2007-02-20 16:47:41.000000000 -0800
@@ -140,6 +140,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	help
 	  The eXcite is a smart camera platform manufactured by
 	  Basler Vision Technologies AG
@@ -206,6 +207,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	help
 	  This is an evaluation board based on the Galileo GT-64120
 	  single-chip system controller that contains a MIPS R5000 compatible
@@ -370,6 +372,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	help
 	  The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
 	  Momentum Computer .
@@ -387,6 +390,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	help
 	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
 	  Momentum Computer .
@@ -476,6 +480,7 @@
 	select SYS_HAS_CPU_R5432
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	help
 	  This enables support for the R5432-based NEC DDB Vrc-5477,
@@ -504,6 +509,7 @@
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_HIGHMEM
+	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_SMP
 	help
 	  Yosemite is an evaluation board for the RM9000x2 processor
@@ -579,6 +585,7 @@
 	select SYS_HAS_CPU_R10000
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_NUMA
 	select SYS_SUPPORTS_SMP
 	select GENERIC_HARDIRQS_NO__DO_IRQ
@@ -628,6 +635,7 @@
 	select SYS_HAS_CPU_SB1
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_HIGHMEM
+	select SYS_SUPPORTS_KGDB
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_SENTOSA
@@ -762,6 +770,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	select TOSHIBA_BOARDS
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 	help
@@ -782,6 +791,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
 	select TOSHIBA_BOARDS
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 	help
@@ -965,6 +975,7 @@
 
 config DDB5XXX_COMMON
 	bool
+	select SYS_SUPPORTS_KGDB
 
 config MIPS_BOARDS_GEN
 	bool
@@ -1012,6 +1023,7 @@
 	bool
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_KGDB
 
 config PNX8550
 	bool
@@ -1024,6 +1036,7 @@
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select GENERIC_HARDIRQS_NO__DO_IRQ
+	select SYS_SUPPORTS_KGDB
 
 config SWAP_IO_SPACE
 	bool
@@ -1199,7 +1212,7 @@
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	help
-	  The options selects support for the NEC VR4100 series of processors.
+	  The options selects support for the NEC VR41xx series of processors.
 	  Only choose this option if you have one of these processors as a
 	  kernel built with this option will not run on any other type of
 	  processor or vice versa.
diff -Naur linux-2.6.20.1.orig/arch/mips/Kconfig.debug linux-2.6.20.1/arch/mips/Kconfig.debug
--- linux-2.6.20.1.orig/arch/mips/Kconfig.debug	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/Kconfig.debug	2007-02-20 16:47:41.000000000 -0800
@@ -22,10 +22,10 @@
 	string "Default kernel command string"
 	default ""
 	help
-          On some platforms, there is currently no way for the boot loader to
-          pass arguments to the kernel. For these platforms, you can supply
-          some command-line options at build time by entering them here.  In
-          other cases you can specify kernel args so that you don't have
+	  On some platforms, there is currently no way for the boot loader to
+	  pass arguments to the kernel. For these platforms, you can supply
+	  some command-line options at build time by entering them here.  In
+	  other cases you can specify kernel args so that you don't have
 	  to set them up in board prom initialization routines.
 
 config DEBUG_STACK_USAGE
@@ -39,7 +39,7 @@
 
 config KGDB
 	bool "Remote GDB kernel debugging"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && SYS_SUPPORTS_KGDB
 	select DEBUG_INFO
 	help
 	  If you say Y here, it will be possible to remotely debug the MIPS
@@ -48,6 +48,9 @@
 	  better 32 MB RAM to avoid excessive linking time. This is only
 	  useful for kernel hackers. If unsure, say N.
 
+config SYS_SUPPORTS_KGDB
+	bool
+
 config GDB_CONSOLE
 	bool "Console output to GDB"
 	depends on KGDB
diff -Naur linux-2.6.20.1.orig/arch/mips/au1000/common/pci.c linux-2.6.20.1/arch/mips/au1000/common/pci.c
--- linux-2.6.20.1.orig/arch/mips/au1000/common/pci.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/au1000/common/pci.c	2007-02-20 16:47:41.000000000 -0800
@@ -76,13 +76,17 @@
 	}
 
 #ifdef CONFIG_DMA_NONCOHERENT
-	/*
-         *  Set the NC bit in controller for Au1500 pre-AC silicon
-	 */
-	u32 prid = read_c0_prid();
-	if ( (prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
-	       au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
-	       printk("Non-coherent PCI accesses enabled\n");
+	{
+		/*
+		 *  Set the NC bit in controller for Au1500 pre-AC silicon
+		 */
+		u32 prid = read_c0_prid();
+
+		if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
+		       au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
+			         Au1500_PCI_CFG);
+		       printk("Non-coherent PCI accesses enabled\n");
+		}
 	}
 #endif
 
diff -Naur linux-2.6.20.1.orig/arch/mips/au1000/common/setup.c linux-2.6.20.1/arch/mips/au1000/common/setup.c
--- linux-2.6.20.1.orig/arch/mips/au1000/common/setup.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/au1000/common/setup.c	2007-02-20 16:47:41.000000000 -0800
@@ -141,17 +141,20 @@
 /* This routine should be valid for all Au1x based boards */
 phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
 {
-	u32 start, end;
-
 	/* Don't fixup 36 bit addresses */
-	if ((phys_addr >> 32) != 0) return phys_addr;
+	if ((phys_addr >> 32) != 0)
+		return phys_addr;
 
 #ifdef CONFIG_PCI
-	start = (u32)Au1500_PCI_MEM_START;
-	end = (u32)Au1500_PCI_MEM_END;
-	/* check for pci memory window */
-	if ((phys_addr >= start) && ((phys_addr + size) < end)) {
-		return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START);
+	{
+		u32 start, end;
+
+		start = (u32)Au1500_PCI_MEM_START;
+		end = (u32)Au1500_PCI_MEM_END;
+		/* check for pci memory window */
+		if ((phys_addr >= start) && ((phys_addr + size) < end))
+			return (phys_t)
+			       ((phys_addr - start) + Au1500_PCI_MEM_START);
 	}
 #endif
 
diff -Naur linux-2.6.20.1.orig/arch/mips/au1000/pb1100/board_setup.c linux-2.6.20.1/arch/mips/au1000/pb1100/board_setup.c
--- linux-2.6.20.1.orig/arch/mips/au1000/pb1100/board_setup.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/au1000/pb1100/board_setup.c	2007-02-20 16:47:41.000000000 -0800
@@ -47,8 +47,7 @@
 
 void __init board_setup(void)
 {
-	u32 pin_func;
-	u32 sys_freqctrl, sys_clksrc;
+	volatile void __iomem * base = (volatile void __iomem *) 0xac000000UL;
 
 	// set AUX clock to 12MHz * 8 = 96 MHz
 	au_writel(8, SYS_AUXPLL);
@@ -56,58 +55,62 @@
 	udelay(100);
 
 #ifdef CONFIG_USB_OHCI
-	// configure pins GPIO[14:9] as GPIO
-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
+	{
+		u32 pin_func, sys_freqctrl, sys_clksrc;
 
-	/* zero and disable FREQ2 */
-	sys_freqctrl = au_readl(SYS_FREQCTRL0);
-	sys_freqctrl &= ~0xFFF00000;
-	au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
-	/* zero and disable USBH/USBD/IrDA clock */
-	sys_clksrc = au_readl(SYS_CLKSRC);
-	sys_clksrc &= ~0x0000001F;
-	au_writel(sys_clksrc, SYS_CLKSRC);
-
-	sys_freqctrl = au_readl(SYS_FREQCTRL0);
-	sys_freqctrl &= ~0xFFF00000;
-
-	sys_clksrc = au_readl(SYS_CLKSRC);
-	sys_clksrc &= ~0x0000001F;
-
-	// FREQ2 = aux/2 = 48 MHz
-	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
-	au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
-	/*
-	 * Route 48MHz FREQ2 into USBH/USBD/IrDA
-	 */
-	sys_clksrc |= ((4<<2) | (0<<1) | 0 );
-	au_writel(sys_clksrc, SYS_CLKSRC);
-
-	/* setup the static bus controller */
-	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
-	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
-	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
-
-	// get USB Functionality pin state (device vs host drive pins)
-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
-	// 2nd USB port is USB host
-	pin_func |= 0x8000;
-	au_writel(pin_func, SYS_PINFUNC);
+		// configure pins GPIO[14:9] as GPIO
+		pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
+
+		/* zero and disable FREQ2 */
+		sys_freqctrl = au_readl(SYS_FREQCTRL0);
+		sys_freqctrl &= ~0xFFF00000;
+		au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+		/* zero and disable USBH/USBD/IrDA clock */
+		sys_clksrc = au_readl(SYS_CLKSRC);
+		sys_clksrc &= ~0x0000001F;
+		au_writel(sys_clksrc, SYS_CLKSRC);
+
+		sys_freqctrl = au_readl(SYS_FREQCTRL0);
+		sys_freqctrl &= ~0xFFF00000;
+
+		sys_clksrc = au_readl(SYS_CLKSRC);
+		sys_clksrc &= ~0x0000001F;
+
+		// FREQ2 = aux/2 = 48 MHz
+		sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+		au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+		/*
+		 * Route 48MHz FREQ2 into USBH/USBD/IrDA
+		 */
+		sys_clksrc |= ((4<<2) | (0<<1) | 0 );
+		au_writel(sys_clksrc, SYS_CLKSRC);
+
+		/* setup the static bus controller */
+		au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+		au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+		au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+
+		// get USB Functionality pin state (device vs host drive pins)
+		pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+		// 2nd USB port is USB host
+		pin_func |= 0x8000;
+		au_writel(pin_func, SYS_PINFUNC);
+	}
 #endif // defined (CONFIG_USB_OHCI)
 
 	/* Enable sys bus clock divider when IDLE state or no bus activity. */
 	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
 
 	// Enable the RTC if not already enabled
-	if (!(readb(0xac000028) & 0x20)) {
-		writeb(readb(0xac000028) | 0x20, 0xac000028);
+	if (!(readb(base + 0x28) & 0x20)) {
+		writeb(readb(base + 0x28) | 0x20, base + 0x28);
 		au_sync();
 	}
 	// Put the clock in BCD mode
-	if (readb(0xac00002C) & 0x4) { /* reg B */
-		writeb(readb(0xac00002c) & ~0x4, 0xac00002c);
+	if (readb(base + 0x2C) & 0x4) { /* reg B */
+		writeb(readb(base + 0x2c) & ~0x4, base + 0x2c);
 		au_sync();
 	}
 }
diff -Naur linux-2.6.20.1.orig/arch/mips/au1000/pb1200/irqmap.c linux-2.6.20.1/arch/mips/au1000/pb1200/irqmap.c
--- linux-2.6.20.1.orig/arch/mips/au1000/pb1200/irqmap.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/au1000/pb1200/irqmap.c	2007-02-20 16:47:41.000000000 -0800
@@ -137,33 +137,20 @@
 	return;
 }
 
-static inline void pb1200_mask_and_ack_irq(unsigned int irq_nr)
-{
-	pb1200_disable_irq( irq_nr );
-}
-
-static void pb1200_end_irq(unsigned int irq_nr)
-{
-	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
-		pb1200_enable_irq(irq_nr);
-	}
-}
-
 static struct irq_chip external_irq_type =
 {
 #ifdef CONFIG_MIPS_PB1200
-	"Pb1200 Ext",
+	.name = "Pb1200 Ext",
 #endif
 #ifdef CONFIG_MIPS_DB1200
-	"Db1200 Ext",
+	.name = "Db1200 Ext",
 #endif
-	pb1200_startup_irq,
-	pb1200_shutdown_irq,
-	pb1200_enable_irq,
-	pb1200_disable_irq,
-	pb1200_mask_and_ack_irq,
-	pb1200_end_irq,
-	NULL
+	.startup  = pb1200_startup_irq,
+	.shutdown = pb1200_shutdown_irq,
+	.ack      = pb1200_disable_irq,
+	.mask     = pb1200_disable_irq,
+	.mask_ack = pb1200_disable_irq,
+	.unmask   = pb1200_enable_irq,
 };
 
 void _board_init_irq(void)
@@ -172,7 +159,8 @@
 
 	for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++)
 	{
-		irq_desc[irq_nr].chip = &external_irq_type;
+		set_irq_chip_and_handler(irq_nr, &external_irq_type,
+					 handle_level_irq);
 		pb1200_disable_irq(irq_nr);
 	}
 
diff -Naur linux-2.6.20.1.orig/arch/mips/dec/int-handler.S linux-2.6.20.1/arch/mips/dec/int-handler.S
--- linux-2.6.20.1.orig/arch/mips/dec/int-handler.S	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/dec/int-handler.S	2007-02-20 16:47:41.000000000 -0800
@@ -264,9 +264,6 @@
 		 srlv	t3,t1,t2
 
 handle_it:
-		LONG_L	s0, TI_REGS($28)
-		LONG_S	sp, TI_REGS($28)
-		PTR_LA	ra, ret_from_irq
 		j	dec_irq_dispatch
 		 nop
 
@@ -277,7 +274,6 @@
 #endif
 
 spurious:
-		PTR_LA	ra, _ret_from_irq
 		j	spurious_interrupt
 		 nop
 		END(plat_irq_dispatch)
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/Makefile linux-2.6.20.1/arch/mips/kernel/Makefile
--- linux-2.6.20.1.orig/arch/mips/kernel/Makefile	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/Makefile	2007-02-20 16:47:41.000000000 -0800
@@ -55,9 +55,9 @@
 obj-$(CONFIG_32BIT)		+= scall32-o32.o
 obj-$(CONFIG_64BIT)		+= scall64-64.o
 obj-$(CONFIG_BINFMT_IRIX)	+= binfmt_irix.o
-obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o signal32.o
+obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o ptrace32.o signal32.o
 obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
-obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o
+obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o
 
 obj-$(CONFIG_KGDB)		+= gdb-low.o gdb-stub.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/cpu-probe.c linux-2.6.20.1/arch/mips/kernel/cpu-probe.c
--- linux-2.6.20.1.orig/arch/mips/kernel/cpu-probe.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/cpu-probe.c	2007-02-20 16:47:41.000000000 -0800
@@ -97,7 +97,7 @@
 
 static int __initdata nowait = 0;
 
-int __init wait_disable(char *s)
+static int __init wait_disable(char *s)
 {
 	nowait = 1;
 
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/linux32.c linux-2.6.20.1/arch/mips/kernel/linux32.c
--- linux-2.6.20.1.orig/arch/mips/kernel/linux32.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/linux32.c	2007-02-20 16:47:41.000000000 -0800
@@ -39,6 +39,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -780,3 +781,49 @@
 	return do_fork(clone_flags, newsp, ®s, 0,
 	               parent_tidptr, child_tidptr);
 }
+
+/*
+ * Implement the event wait interface for the eventpoll file. It is the kernel
+ * part of the user space epoll_pwait(2).
+ */
+asmlinkage long compat_sys_epoll_pwait(int epfd,
+	struct epoll_event __user *events, int maxevents, int timeout,
+	const compat_sigset_t __user *sigmask, size_t sigsetsize)
+{
+	int error;
+	sigset_t ksigmask, sigsaved;
+
+	/*
+	 * If the caller wants a certain signal mask to be set during the wait,
+	 * we apply it here.
+	 */
+	if (sigmask) {
+		if (sigsetsize != sizeof(sigset_t))
+			return -EINVAL;
+		if (!access_ok(VERIFY_READ, sigmask, sizeof(ksigmask)))
+			return -EFAULT;
+		if (__copy_conv_sigset_from_user(&ksigmask, sigmask))
+			return -EFAULT;
+		sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
+		sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+	}
+
+	error = sys_epoll_wait(epfd, events, maxevents, timeout);
+
+	/*
+	 * If we changed the signal mask, we need to restore the original one.
+	 * In case we've got a signal while waiting, we do not restore the
+	 * signal mask yet, and we allow do_signal() to deliver the signal on
+	 * the way back to userspace, before the signal mask is restored.
+	 */
+	if (sigmask) {
+		if (error == -EINTR) {
+			memcpy(¤t->saved_sigmask, &sigsaved,
+				sizeof(sigsaved));
+			set_thread_flag(TIF_RESTORE_SIGMASK);
+		} else
+			sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+	}
+
+	return error;
+}
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/mips-mt.c linux-2.6.20.1/arch/mips/kernel/mips-mt.c
--- linux-2.6.20.1.orig/arch/mips/kernel/mips-mt.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/mips-mt.c	2007-02-20 16:47:41.000000000 -0800
@@ -3,9 +3,11 @@
  * Copyright (C) 2005 Mips Technologies, Inc
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -96,6 +98,10 @@
 		goto out_unlock;
 	}
 
+	retval = security_task_setscheduler(p, 0, NULL);
+	if (retval)
+		goto out_unlock;
+
 	/* Record new user-specified CPU set for future reference */
 	p->thread.user_cpus_allowed = new_mask;
 
@@ -141,8 +147,9 @@
 	p = find_process_by_pid(pid);
 	if (!p)
 		goto out_unlock;
-
-	retval = 0;
+	retval = security_task_getscheduler(p);
+	if (retval)
+		goto out_unlock;
 
 	cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map);
 
@@ -448,3 +455,20 @@
 #endif /* CONFIG_MIPS_MT_SMTC */
 	/* FILL IN VSMP and AP/SP VERSIONS HERE */
 }
+
+struct class *mt_class;
+
+static int __init mt_init(void)
+{
+	struct class *mtc;
+
+	mtc = class_create(THIS_MODULE, "mt");
+	if (IS_ERR(mtc))
+		return PTR_ERR(mtc);
+
+	mt_class = mtc;
+
+	return 0;
+}
+
+subsys_initcall(mt_init);
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/ptrace.c linux-2.6.20.1/arch/mips/kernel/ptrace.c
--- linux-2.6.20.1.orig/arch/mips/kernel/ptrace.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/ptrace.c	2007-02-20 16:47:41.000000000 -0800
@@ -20,12 +20,12 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
 #include 
-#include 
+#include 
+#include 
 
 #include 
 #include 
@@ -473,12 +473,16 @@
  */
 asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
 {
+	/* do the secure computing check first */
+	secure_computing(regs->orig_eax);
+
 	if (unlikely(current->audit_context) && entryexit)
 		audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]),
 		                   regs->regs[2]);
 
 	if (!(current->ptrace & PT_PTRACED))
 		goto out;
+
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
 		goto out;
 
@@ -496,9 +500,14 @@
 		send_sig(current->exit_code, current, 1);
 		current->exit_code = 0;
 	}
- out:
+
+out:
+	/* There is no ->orig_eax and that's quite intensional for now making
+	   this work will require some work in various other place before it's
+	   more than a placebo.  */
+
 	if (unlikely(current->audit_context) && !entryexit)
-		audit_syscall_entry(audit_arch(), regs->regs[2],
-				    regs->regs[4], regs->regs[5],
-				    regs->regs[6], regs->regs[7]);
+		audit_syscall_entry(audit_arch(), regs->orig_eax,
+		                    regs->regs[4], regs->regs[5],
+		                    regs->regs[6], regs->regs[7]);
 }
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/r4k_fpu.S linux-2.6.20.1/arch/mips/kernel/r4k_fpu.S
--- linux-2.6.20.1.orig/arch/mips/kernel/r4k_fpu.S	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/r4k_fpu.S	2007-02-20 16:47:41.000000000 -0800
@@ -114,6 +114,14 @@
  */
 LEAF(_restore_fp_context)
 	EX	lw t0, SC_FPC_CSR(a0)
+
+	/* Fail if the CSR has exceptions pending */
+	srl	t1, t0, 5
+	and	t1, t0
+	andi	t1, 0x1f << 7
+	bnez	t1, fault
+	 nop
+
 #ifdef CONFIG_64BIT
 	EX	ldc1 $f1, SC_FPREGS+8(a0)
 	EX	ldc1 $f3, SC_FPREGS+24(a0)
@@ -157,6 +165,14 @@
 LEAF(_restore_fp_context32)
 	/* Restore an o32 sigcontext.  */
 	EX	lw t0, SC32_FPC_CSR(a0)
+
+	/* Fail if the CSR has exceptions pending */
+	srl	t1, t0, 5
+	and	t1, t0
+	andi	t1, 0x1f << 7
+	bnez	t1, fault
+	 nop
+
 	EX	ldc1 $f0, SC32_FPREGS+0(a0)
 	EX	ldc1 $f2, SC32_FPREGS+16(a0)
 	EX	ldc1 $f4, SC32_FPREGS+32(a0)
@@ -177,9 +193,10 @@
 	jr	ra
 	 li	v0, 0					# success
 	END(_restore_fp_context32)
-	.set	reorder
 #endif
 
+	.set	reorder
+
 	.type	fault@function
 	.ent	fault
 fault:	li	v0, -EFAULT				# failure
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/rtlx.c linux-2.6.20.1/arch/mips/kernel/rtlx.c
--- linux-2.6.20.1.orig/arch/mips/kernel/rtlx.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/rtlx.c	2007-02-20 16:47:41.000000000 -0800
@@ -17,6 +17,7 @@
  *
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -34,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -498,7 +500,8 @@
 
 static int rtlx_module_init(void)
 {
-	int i;
+	struct device *dev;
+	int i, err;
 
 	major = register_chrdev(0, module_name, &rtlx_fops);
 	if (major < 0) {
@@ -511,6 +514,13 @@
 		init_waitqueue_head(&channel_wqs[i].rt_queue);
 		init_waitqueue_head(&channel_wqs[i].lx_queue);
 		channel_wqs[i].in_open = 0;
+
+		dev = device_create(mt_class, NULL, MKDEV(major, i),
+		                    "%s%d", module_name, i);
+		if (IS_ERR(dev)) {
+			err = PTR_ERR(dev);
+			goto out_chrdev;
+		}
 	}
 
 	/* set up notifiers */
@@ -525,10 +535,21 @@
 	setup_irq(rtlx_irq_num, &rtlx_irq);
 
 	return 0;
+
+out_chrdev:
+	for (i = 0; i < RTLX_CHANNELS; i++)
+		device_destroy(mt_class, MKDEV(major, i));
+
+	return err;
 }
 
 static void __exit rtlx_module_exit(void)
 {
+	int i;
+
+	for (i = 0; i < RTLX_CHANNELS; i++)
+		device_destroy(mt_class, MKDEV(major, i));
+
 	unregister_chrdev(major, module_name);
 }
 
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/scall64-n32.S linux-2.6.20.1/arch/mips/kernel/scall64-n32.S
--- linux-2.6.20.1.orig/arch/mips/kernel/scall64-n32.S	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/scall64-n32.S	2007-02-20 16:47:41.000000000 -0800
@@ -384,7 +384,7 @@
 	PTR	sys_readlinkat
 	PTR	sys_fchmodat
 	PTR	sys_faccessat
-	PTR	sys_pselect6
+	PTR	compat_sys_pselect6
 	PTR	sys_ppoll			/* 6265 */
 	PTR	sys_unshare
 	PTR	sys_splice
@@ -396,4 +396,4 @@
 	PTR	compat_sys_get_robust_list
 	PTR	compat_sys_kexec_load
 	PTR	sys_getcpu
-	PTR	sys_epoll_pwait
+	PTR	compat_sys_epoll_pwait
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/scall64-o32.S linux-2.6.20.1/arch/mips/kernel/scall64-o32.S
--- linux-2.6.20.1.orig/arch/mips/kernel/scall64-o32.S	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/scall64-o32.S	2007-02-24 14:25:52.000000000 -0800
@@ -506,7 +506,7 @@
 	PTR	sys_readlinkat
 	PTR	sys_fchmodat
 	PTR	sys_faccessat			/* 4300 */
-	PTR	sys_pselect6
+	PTR	compat_sys_pselect6
 	PTR	sys_ppoll
 	PTR	sys_unshare
 	PTR	sys_splice
@@ -518,5 +518,5 @@
 	PTR	compat_sys_get_robust_list	/* 4310 */
 	PTR	compat_sys_kexec_load
 	PTR	sys_getcpu
-	PTR	sys_epoll_pwait
+	PTR	compat_sys_epoll_pwait
 	.size	sys_call_table,.-sys_call_table
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/setup.c linux-2.6.20.1/arch/mips/kernel/setup.c
--- linux-2.6.20.1.orig/arch/mips/kernel/setup.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/setup.c	2007-02-20 16:47:41.000000000 -0800
@@ -521,7 +521,7 @@
 #endif
 }
 
-int __init fpu_disable(char *s)
+static int __init fpu_disable(char *s)
 {
 	int i;
 
@@ -533,7 +533,7 @@
 
 __setup("nofpu", fpu_disable);
 
-int __init dsp_disable(char *s)
+static int __init dsp_disable(char *s)
 {
 	cpu_data[0].ases &= ~MIPS_ASE_DSP;
 
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/signal32.c linux-2.6.20.1/arch/mips/kernel/signal32.c
--- linux-2.6.20.1.orig/arch/mips/kernel/signal32.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/signal32.c	2007-02-20 16:47:41.000000000 -0800
@@ -8,6 +8,7 @@
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -24,6 +25,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -108,13 +110,6 @@
 
 /* 32-bit compatibility types */
 
-#define _NSIG_BPW32	32
-#define _NSIG_WORDS32	(_NSIG / _NSIG_BPW32)
-
-typedef struct {
-	unsigned int sig[_NSIG_WORDS32];
-} sigset_t32;
-
 typedef unsigned int __sighandler32_t;
 typedef void (*vfptr_t)(void);
 
@@ -136,7 +131,7 @@
 	s32                 uc_link;
 	stack32_t           uc_stack;
 	struct sigcontext32 uc_mcontext;
-	sigset_t32          uc_sigmask;   /* mask last for extensibility */
+	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
 extern void __put_sigset_unknown_nsig(void);
@@ -391,7 +386,7 @@
 	u32 sf_code[2];			/* signal trampoline */
 #endif
 	struct sigcontext32 sf_sc;
-	sigset_t sf_mask;
+	compat_sigset_t sf_mask;
 #if ICACHE_REFILLS_WORKAROUND_WAR
 	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
 #endif
@@ -473,7 +468,7 @@
 	frame = (struct sigframe __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
-	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
+	if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
 		goto badframe;
 
 	sigdelsetmask(&blocked, ~_BLOCKABLE);
@@ -512,7 +507,7 @@
 	frame = (struct rt_sigframe32 __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
-	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+	if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
@@ -658,7 +653,8 @@
 	flush_cache_sigtramp((unsigned long) frame->sf_code);
 
 	err |= setup_sigcontext32(regs, &frame->sf_sc);
-	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
+
 	if (err)
 		goto give_sigsegv;
 
@@ -728,7 +724,7 @@
 	err |= __put_user(current->sas_ss_size,
 	                  &frame->rs_uc.uc_stack.ss_size);
 	err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
-	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+	err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
 
 	if (err)
 		goto give_sigsegv;
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/signal_n32.c linux-2.6.20.1/arch/mips/kernel/signal_n32.c
--- linux-2.6.20.1.orig/arch/mips/kernel/signal_n32.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/signal_n32.c	2007-02-20 16:47:41.000000000 -0800
@@ -31,6 +31,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -63,7 +64,7 @@
 	s32                 uc_link;
 	stack32_t           uc_stack;
 	struct sigcontext   uc_mcontext;
-	sigset_t            uc_sigmask;   /* mask last for extensibility */
+	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
 struct rt_sigframe_n32 {
@@ -126,7 +127,7 @@
 	frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
-	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+	if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
@@ -192,7 +193,7 @@
 	err |= __put_user(current->sas_ss_size,
 	                  &frame->rs_uc.uc_stack.ss_size);
 	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
-	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+	err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
 
 	if (err)
 		goto give_sigsegv;
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/smp.c linux-2.6.20.1/arch/mips/kernel/smp.c
--- linux-2.6.20.1.orig/arch/mips/kernel/smp.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/smp.c	2007-02-20 16:47:41.000000000 -0800
@@ -51,31 +51,14 @@
 EXPORT_SYMBOL(phys_cpu_present_map);
 EXPORT_SYMBOL(cpu_online_map);
 
+/* This happens early in bootup, can't really do it better */
 static void smp_tune_scheduling (void)
 {
 	struct cache_desc *cd = ¤t_cpu_data.scache;
-	unsigned long cachesize;       /* kB   */
-	unsigned long cpu_khz;
+	unsigned long cachesize = cd->linesz * cd->sets * cd->ways;
 
-	/*
-	 * Crude estimate until we actually meassure ...
-	 */
-	cpu_khz = loops_per_jiffy * 2 * HZ / 1000;
-
-	/*
-	 * Rough estimation for SMP scheduling, this is the number of
-	 * cycles it takes for a fully memory-limited process to flush
-	 * the SMP-local cache.
-	 *
-	 * (For a P5 this pretty much means we will choose another idle
-	 *  CPU almost always at wakeup time (this is due to the small
-	 *  L1 cache), on PIIs it's around 50-100 usecs, depending on
-	 *  the cache size)
-	 */
-	if (!cpu_khz)
-		return;
-
-	cachesize = cd->linesz * cd->sets * cd->ways;
+	if (cachesize > max_cache_size)
+		max_cache_size = cachesize;
 }
 
 extern void __init calibrate_delay(void);
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/traps.c linux-2.6.20.1/arch/mips/kernel/traps.c
--- linux-2.6.20.1.orig/arch/mips/kernel/traps.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/traps.c	2007-02-20 16:47:41.000000000 -0800
@@ -708,6 +708,7 @@
 		die_if_kernel("Break instruction in kernel code", regs);
 		force_sig(SIGTRAP, current);
 	}
+	return;
 
 out_sigsegv:
 	force_sig(SIGSEGV, current);
@@ -751,6 +752,7 @@
 		die_if_kernel("Trap instruction in kernel code", regs);
 		force_sig(SIGTRAP, current);
 	}
+	return;
 
 out_sigsegv:
 	force_sig(SIGSEGV, current);
diff -Naur linux-2.6.20.1.orig/arch/mips/kernel/vpe.c linux-2.6.20.1/arch/mips/kernel/vpe.c
--- linux-2.6.20.1.orig/arch/mips/kernel/vpe.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/kernel/vpe.c	2007-02-20 16:47:41.000000000 -0800
@@ -29,6 +29,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -48,6 +49,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -64,6 +66,7 @@
 
 static char module_name[] = "vpe";
 static int major;
+static const int minor = 1;	/* fixed for now  */
 
 #ifdef CONFIG_MIPS_APSP_KSPD
  static struct kspd_notifications kspd_events;
@@ -1365,12 +1368,15 @@
 }
 #endif
 
+static struct device *vpe_dev;
+
 static int __init vpe_module_init(void)
 {
 	struct vpe *v = NULL;
+	struct device *dev;
 	struct tc *t;
 	unsigned long val;
-	int i;
+	int i, err;
 
 	if (!cpu_has_mipsmt) {
 		printk("VPE loader: not a MIPS MT capable processor\n");
@@ -1383,6 +1389,14 @@
 		return major;
 	}
 
+	dev = device_create(mt_class, NULL, MKDEV(major, minor),
+	                    "tc%d", minor);
+	if (IS_ERR(dev)) {
+		err = PTR_ERR(dev);
+		goto out_chrdev;
+	}
+	vpe_dev = dev;
+
 	dmt();
 	dvpe();
 
@@ -1478,6 +1492,11 @@
 	kspd_events.kspd_sp_exit = kspd_sp_exit;
 #endif
 	return 0;
+
+out_chrdev:
+	unregister_chrdev(major, module_name);
+
+	return err;
 }
 
 static void __exit vpe_module_exit(void)
@@ -1490,6 +1509,7 @@
 		}
 	}
 
+	device_destroy(mt_class, MKDEV(major, minor));
 	unregister_chrdev(major, module_name);
 }
 
diff -Naur linux-2.6.20.1.orig/arch/mips/lib/Makefile linux-2.6.20.1/arch/mips/lib/Makefile
--- linux-2.6.20.1.orig/arch/mips/lib/Makefile	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/lib/Makefile	2007-02-20 16:47:41.000000000 -0800
@@ -2,10 +2,11 @@
 # Makefile for MIPS-specific library files..
 #
 
-lib-y	+= csum_partial.o memcpy.o promlib.o \
+lib-y	+= csum_partial.o memcpy.o memcpy-inatomic.o promlib.o \
 	   strlen_user.o strncpy_user.o strnlen_user.o uncached.o
 
-obj-y	+= iomap.o
+obj-y			+= iomap.o
+obj-$(CONFIG_PCI)	+= iomap-pci.o
 
 # libgcc-style stuff needed in the kernel
 lib-y += ashldi3.o ashrdi3.o lshrdi3.o
diff -Naur linux-2.6.20.1.orig/arch/mips/lib/iomap-pci.c linux-2.6.20.1/arch/mips/lib/iomap-pci.c
--- linux-2.6.20.1.orig/arch/mips/lib/iomap-pci.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.20.1/arch/mips/lib/iomap-pci.c	2007-02-20 16:47:41.000000000 -0800
@@ -0,0 +1,74 @@
+/*
+ * Implement the default iomap interfaces
+ *
+ * (C) Copyright 2004 Linus Torvalds
+ * (C) Copyright 2006 Ralf Baechle 
+ * (C) Copyright 2007 MIPS Technologies, Inc.
+ *     written by Ralf Baechle 
+ */
+#include 
+#include 
+#include 
+
+static void __iomem *ioport_map_pci(struct pci_dev *dev,
+                                     unsigned long port, unsigned int nr)
+{
+	struct pci_controller *ctrl = dev->bus->sysdata;
+	unsigned long base = ctrl->io_map_base;
+
+	/* This will eventually become a BUG_ON but for now be gentle */
+	if (unlikely(!ctrl->io_map_base)) {
+		struct pci_bus *bus = dev->bus;
+		char name[8];
+
+		while (bus->parent)
+			bus = bus->parent;
+
+		ctrl->io_map_base = base = mips_io_port_base;
+
+		sprintf(name, "%04x:%02x", pci_domain_nr(bus), bus->number);
+		printk(KERN_WARNING "io_map_base of root PCI bus %s unset.  "
+		       "Trying to continue but you better\nfix this issue or "
+		       "report it to linux-mips@linux-mips.org or your "
+		       "vendor.\n", name);
+#ifdef CONFIG_PCI_DOMAINS
+		panic("To avoid data corruption io_map_base MUST be set with "
+		      "multiple PCI domains.");
+#endif
+	}
+
+	return (void __iomem *) (ctrl->io_map_base + port);
+}
+
+/*
+ * Create a virtual mapping cookie for a PCI BAR (memory or IO)
+ */
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+	unsigned long start = pci_resource_start(dev, bar);
+	unsigned long len = pci_resource_len(dev, bar);
+	unsigned long flags = pci_resource_flags(dev, bar);
+
+	if (!len || !start)
+		return NULL;
+	if (maxlen && len > maxlen)
+		len = maxlen;
+	if (flags & IORESOURCE_IO)
+		return ioport_map_pci(dev, start, len);
+	if (flags & IORESOURCE_MEM) {
+		if (flags & IORESOURCE_CACHEABLE)
+			return ioremap(start, len);
+		return ioremap_nocache(start, len);
+	}
+	/* What? */
+	return NULL;
+}
+
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
+{
+	iounmap(addr);
+}
+
+EXPORT_SYMBOL(pci_iounmap);
diff -Naur linux-2.6.20.1.orig/arch/mips/lib/iomap.c linux-2.6.20.1/arch/mips/lib/iomap.c
--- linux-2.6.20.1.orig/arch/mips/lib/iomap.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/lib/iomap.c	2007-02-20 16:47:41.000000000 -0800
@@ -1,78 +1,227 @@
 /*
- *  iomap.c, Memory Mapped I/O routines for MIPS architecture.
+ * Implement the default iomap interfaces
  *
- *  This code is based on lib/iomap.c, by Linus Torvalds.
- *
- *  Copyright (C) 2004-2005  Yoichi Yuasa 
- *
- *  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.
+ * (C) Copyright 2004 Linus Torvalds
+ * (C) Copyright 2006 Ralf Baechle 
+ * (C) Copyright 2007 MIPS Technologies, Inc.
+ *     written by Ralf Baechle 
+ */
+#include 
+#include 
+#include 
+
+/*
+ * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
+ * access or a MMIO access, these functions don't care. The info is
+ * encoded in the hardware mapping set up by the mapping functions
+ * (or the cookie itself, depending on implementation and hw).
  *
- *  This program is distributed in the hope that 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.
+ * The generic routines don't assume any hardware mappings, and just
+ * encode the PIO/MMIO as part of the cookie. They coldly assume that
+ * the MMIO IO mappings are not in the low address range.
  *
- *  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
+ * Architectures for which this is not true can't use this generic
+ * implementation and should do their own copy.
  */
-#include 
-#include 
-#include 
 
-#include 
+#define PIO_MASK	0x0ffffUL
 
-void __iomem *ioport_map(unsigned long port, unsigned int nr)
+unsigned int ioread8(void __iomem *addr)
 {
-	unsigned long end;
+	return readb(addr);
+}
 
-	end = port + nr - 1UL;
-	if (ioport_resource.start > port ||
-	    ioport_resource.end < end || port > end)
-		return NULL;
+EXPORT_SYMBOL(ioread8);
 
-	return (void __iomem *)(mips_io_port_base + port);
+unsigned int ioread16(void __iomem *addr)
+{
+	return readw(addr);
 }
 
-void ioport_unmap(void __iomem *addr)
+EXPORT_SYMBOL(ioread16);
+
+unsigned int ioread16be(void __iomem *addr)
 {
+	return be16_to_cpu(__raw_readw(addr));
 }
-EXPORT_SYMBOL(ioport_map);
-EXPORT_SYMBOL(ioport_unmap);
 
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+EXPORT_SYMBOL(ioread16be);
+
+unsigned int ioread32(void __iomem *addr)
 {
-	unsigned long start, len, flags;
+	return readl(addr);
+}
 
-	if (dev == NULL)
-		return NULL;
+EXPORT_SYMBOL(ioread32);
 
-	start = pci_resource_start(dev, bar);
-	len = pci_resource_len(dev, bar);
-	if (!start || !len)
-		return NULL;
+unsigned int ioread32be(void __iomem *addr)
+{
+	return be32_to_cpu(__raw_readl(addr));
+}
 
-	if (maxlen != 0 && len > maxlen)
-		len = maxlen;
+EXPORT_SYMBOL(ioread32be);
+
+void iowrite8(u8 val, void __iomem *addr)
+{
+	writeb(val, addr);
+}
 
-	flags = pci_resource_flags(dev, bar);
-	if (flags & IORESOURCE_IO)
-		return ioport_map(start, len);
-	if (flags & IORESOURCE_MEM) {
-		if (flags & IORESOURCE_CACHEABLE)
-			return ioremap_cachable(start, len);
-		return ioremap_nocache(start, len);
+EXPORT_SYMBOL(iowrite8);
+
+void iowrite16(u16 val, void __iomem *addr)
+{
+	writew(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite16);
+
+void iowrite16be(u16 val, void __iomem *addr)
+{
+	__raw_writew(cpu_to_be16(val), addr);
+}
+
+EXPORT_SYMBOL(iowrite16be);
+
+void iowrite32(u32 val, void __iomem *addr)
+{
+	writel(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite32);
+
+void iowrite32be(u32 val, void __iomem *addr)
+{
+	__raw_writel(cpu_to_be32(val), addr);
+}
+
+EXPORT_SYMBOL(iowrite32be);
+
+/*
+ * These are the "repeat MMIO read/write" functions.
+ * Note the "__raw" accesses, since we don't want to
+ * convert to CPU byte order. We write in "IO byte
+ * order" (we also don't have IO barriers).
+ */
+static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
+{
+	while (--count >= 0) {
+		u8 data = __raw_readb(addr);
+		*dst = data;
+		dst++;
 	}
+}
 
-	return NULL;
+static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
+{
+	while (--count >= 0) {
+		u16 data = __raw_readw(addr);
+		*dst = data;
+		dst++;
+	}
 }
 
-void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
 {
-	iounmap(addr);
+	while (--count >= 0) {
+		u32 data = __raw_readl(addr);
+		*dst = data;
+		dst++;
+	}
 }
-EXPORT_SYMBOL(pci_iomap);
-EXPORT_SYMBOL(pci_iounmap);
+
+static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
+{
+	while (--count >= 0) {
+		__raw_writeb(*src, addr);
+		src++;
+	}
+}
+
+static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
+{
+	while (--count >= 0) {
+		__raw_writew(*src, addr);
+		src++;
+	}
+}
+
+static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
+{
+	while (--count >= 0) {
+		__raw_writel(*src, addr);
+		src++;
+	}
+}
+
+void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	mmio_insb(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread8_rep);
+
+void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	mmio_insw(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread16_rep);
+
+void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	mmio_insl(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread32_rep);
+
+void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	mmio_outsb(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite8_rep);
+
+void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	mmio_outsw(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite16_rep);
+
+void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	mmio_outsl(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite32_rep);
+
+/*
+ * Create a virtual mapping cookie for an IO port range
+ *
+ * This uses the same mapping are as the in/out family which has to be setup
+ * by the platform initialization code.
+ *
+ * Just to make matters somewhat more interesting on MIPS systems with
+ * multiple host bridge each will have it's own ioport address space.
+ */
+static void __iomem *ioport_map_legacy(unsigned long port, unsigned int nr)
+{
+	return (void __iomem *) (mips_io_port_base + port);
+}
+
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	if (port > PIO_MASK)
+		return NULL;
+
+	return ioport_map_legacy(port, nr);
+}
+
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+	/* Nothing to do */
+}
+
+EXPORT_SYMBOL(ioport_unmap);
diff -Naur linux-2.6.20.1.orig/arch/mips/lib/memcpy-inatomic.S linux-2.6.20.1/arch/mips/lib/memcpy-inatomic.S
--- linux-2.6.20.1.orig/arch/mips/lib/memcpy-inatomic.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.20.1/arch/mips/lib/memcpy-inatomic.S	2007-02-20 16:47:41.000000000 -0800
@@ -0,0 +1,436 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Unified implementation of memcpy, memmove and the __copy_user backend.
+ *
+ * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
+ * Copyright (C) 2002 Broadcom, Inc.
+ *   memcpy/copy_user author: Mark Vandevoorde
+ *
+ * Mnemonic names for arguments to memcpy/__copy_user
+ */
+
+/*
+ * Hack to resolve longstanding prefetch issue
+ *
+ * Prefetching may be fatal on some systems if we're prefetching beyond the
+ * end of memory on some systems.  It's also a seriously bad idea on non
+ * dma-coherent systems.
+ */
+#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27)
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+#ifdef CONFIG_MIPS_MALTA
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+
+#include 
+#include 
+#include 
+
+#define dst a0
+#define src a1
+#define len a2
+
+/*
+ * Spec
+ *
+ * memcpy copies len bytes from src to dst and sets v0 to dst.
+ * It assumes that
+ *   - src and dst don't overlap
+ *   - src is readable
+ *   - dst is writable
+ * memcpy uses the standard calling convention
+ *
+ * __copy_user copies up to len bytes from src to dst and sets a2 (len) to
+ * the number of uncopied bytes due to an exception caused by a read or write.
+ * __copy_user assumes that src and dst don't overlap, and that the call is
+ * implementing one of the following:
+ *   copy_to_user
+ *     - src is readable  (no exceptions when reading src)
+ *   copy_from_user
+ *     - dst is writable  (no exceptions when writing dst)
+ * __copy_user uses a non-standard calling convention; see
+ * include/asm-mips/uaccess.h
+ *
+ * When an exception happens on a load, the handler must
+ # ensure that all of the destination buffer is overwritten to prevent
+ * leaking information to user mode programs.
+ */
+
+/*
+ * Implementation
+ */
+
+/*
+ * The exception handler for loads requires that:
+ *  1- AT contain the address of the byte just past the end of the source
+ *     of the copy,
+ *  2- src_entry <= src < AT, and
+ *  3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores adjust len (if necessary) and return.
+ * These handlers do not need to overwrite any data.
+ *
+ * For __rmemcpy and memmove an exception is always a kernel bug, therefore
+ * they're not protected.
+ */
+
+#define EXC(inst_reg,addr,handler)		\
+9:	inst_reg, addr;				\
+	.section __ex_table,"a";		\
+	PTR	9b, handler;			\
+	.previous
+
+/*
+ * Only on the 64-bit kernel we can made use of 64-bit registers.
+ */
+#ifdef CONFIG_64BIT
+#define USE_DOUBLE
+#endif
+
+#ifdef USE_DOUBLE
+
+#define LOAD   ld
+#define LOADL  ldl
+#define LOADR  ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE  sd
+#define ADD    daddu
+#define SUB    dsubu
+#define SRL    dsrl
+#define SRA    dsra
+#define SLL    dsll
+#define SLLV   dsllv
+#define SRLV   dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+/*
+ * As we are sharing code base with the mips32 tree (which use the o32 ABI
+ * register definitions). We need to redefine the register definitions from
+ * the n64 ABI register naming to the o32 ABI register naming.
+ */
+#undef t0
+#undef t1
+#undef t2
+#undef t3
+#define t0	$8
+#define t1	$9
+#define t2	$10
+#define t3	$11
+#define t4	$12
+#define t5	$13
+#define t6	$14
+#define t7	$15
+
+#else
+
+#define LOAD   lw
+#define LOADL  lwl
+#define LOADR  lwr
+#define STOREL swl
+#define STORER swr
+#define STORE  sw
+#define ADD    addu
+#define SUB    subu
+#define SRL    srl
+#define SLL    sll
+#define SRA    sra
+#define SLLV   sllv
+#define SRLV   srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST  LOADL
+#define STFIRST STORER
+#define STREST  STOREL
+#define SHIFT_DISCARD SLLV
+#else
+#define LDFIRST LOADL
+#define LDREST  LOADR
+#define STFIRST STOREL
+#define STREST  STORER
+#define SHIFT_DISCARD SRLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit)  (FIRST(unit)+NBYTES-1)
+#define UNIT(unit)  FIRST(unit)
+
+#define ADDRMASK (NBYTES-1)
+
+	.text
+	.set	noreorder
+	.set	noat
+
+/*
+ * A combined memcpy/__copy_user
+ * __copy_user sets len to 0 for success; else to an upper bound of
+ * the number of uncopied bytes.
+ * memcpy sets v0 to dst.
+ */
+	.align	5
+LEAF(__copy_user_inatomic)
+	/*
+	 * Note: dst & src may be unaligned, len may be 0
+	 * Temps
+	 */
+#define rem t8
+
+	/*
+	 * The "issue break"s below are very approximate.
+	 * Issue delays for dcache fills will perturb the schedule, as will
+	 * load queue full replay traps, etc.
+	 *
+	 * If len < NBYTES use byte operations.
+	 */
+	PREF(	0, 0(src) )
+	PREF(	1, 0(dst) )
+	sltu	t2, len, NBYTES
+	and	t1, dst, ADDRMASK
+	PREF(	0, 1*32(src) )
+	PREF(	1, 1*32(dst) )
+	bnez	t2, copy_bytes_checklen
+	 and	t0, src, ADDRMASK
+	PREF(	0, 2*32(src) )
+	PREF(	1, 2*32(dst) )
+	bnez	t1, dst_unaligned
+	 nop
+	bnez	t0, src_unaligned_dst_aligned
+	/*
+	 * use delay slot for fall-through
+	 * src and dst are aligned; need to compute rem
+	 */
+both_aligned:
+	 SRL	t0, len, LOG_NBYTES+3    # +3 for 8 units/iter
+	beqz	t0, cleanup_both_aligned # len < 8*NBYTES
+	 and	rem, len, (8*NBYTES-1)	 # rem = len % (8*NBYTES)
+	PREF(	0, 3*32(src) )
+	PREF(	1, 3*32(dst) )
+	.align	4
+1:
+EXC(	LOAD	t0, UNIT(0)(src),	l_exc)
+EXC(	LOAD	t1, UNIT(1)(src),	l_exc_copy)
+EXC(	LOAD	t2, UNIT(2)(src),	l_exc_copy)
+EXC(	LOAD	t3, UNIT(3)(src),	l_exc_copy)
+	SUB	len, len, 8*NBYTES
+EXC(	LOAD	t4, UNIT(4)(src),	l_exc_copy)
+EXC(	LOAD	t7, UNIT(5)(src),	l_exc_copy)
+	STORE	t0, UNIT(0)(dst)
+	STORE	t1, UNIT(1)(dst)
+EXC(	LOAD	t0, UNIT(6)(src),	l_exc_copy)
+EXC(	LOAD	t1, UNIT(7)(src),	l_exc_copy)
+	ADD	src, src, 8*NBYTES
+	ADD	dst, dst, 8*NBYTES
+	STORE	t2, UNIT(-6)(dst)
+	STORE	t3, UNIT(-5)(dst)
+	STORE	t4, UNIT(-4)(dst)
+	STORE	t7, UNIT(-3)(dst)
+	STORE	t0, UNIT(-2)(dst)
+	STORE	t1, UNIT(-1)(dst)
+	PREF(	0, 8*32(src) )
+	PREF(	1, 8*32(dst) )
+	bne	len, rem, 1b
+	 nop
+
+	/*
+	 * len == rem == the number of bytes left to copy < 8*NBYTES
+	 */
+cleanup_both_aligned:
+	beqz	len, done
+	 sltu	t0, len, 4*NBYTES
+	bnez	t0, less_than_4units
+	 and	rem, len, (NBYTES-1)	# rem = len % NBYTES
+	/*
+	 * len >= 4*NBYTES
+	 */
+EXC(	LOAD	t0, UNIT(0)(src),	l_exc)
+EXC(	LOAD	t1, UNIT(1)(src),	l_exc_copy)
+EXC(	LOAD	t2, UNIT(2)(src),	l_exc_copy)
+EXC(	LOAD	t3, UNIT(3)(src),	l_exc_copy)
+	SUB	len, len, 4*NBYTES
+	ADD	src, src, 4*NBYTES
+	STORE	t0, UNIT(0)(dst)
+	STORE	t1, UNIT(1)(dst)
+	STORE	t2, UNIT(2)(dst)
+	STORE	t3, UNIT(3)(dst)
+	beqz	len, done
+	 ADD	dst, dst, 4*NBYTES
+less_than_4units:
+	/*
+	 * rem = len % NBYTES
+	 */
+	beq	rem, len, copy_bytes
+	 nop
+1:
+EXC(	LOAD	t0, 0(src),		l_exc)
+	ADD	src, src, NBYTES
+	SUB	len, len, NBYTES
+	STORE	t0, 0(dst)
+	bne	rem, len, 1b
+	 ADD	dst, dst, NBYTES
+
+	/*
+	 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
+	 * A loop would do only a byte at a time with possible branch
+	 * mispredicts.  Can't do an explicit LOAD dst,mask,or,STORE
+	 * because can't assume read-access to dst.  Instead, use
+	 * STREST dst, which doesn't require read access to dst.
+	 *
+	 * This code should perform better than a simple loop on modern,
+	 * wide-issue mips processors because the code has fewer branches and
+	 * more instruction-level parallelism.
+	 */
+#define bits t2
+	beqz	len, done
+	 ADD	t1, dst, len	# t1 is just past last byte of dst
+	li	bits, 8*NBYTES
+	SLL	rem, len, 3	# rem = number of bits to keep
+EXC(	LOAD	t0, 0(src),		l_exc)
+	SUB	bits, bits, rem	# bits = number of bits to discard
+	SHIFT_DISCARD t0, t0, bits
+	STREST	t0, -1(t1)
+	jr	ra
+	 move	len, zero
+dst_unaligned:
+	/*
+	 * dst is unaligned
+	 * t0 = src & ADDRMASK
+	 * t1 = dst & ADDRMASK; T1 > 0
+	 * len >= NBYTES
+	 *
+	 * Copy enough bytes to align dst
+	 * Set match = (src and dst have same alignment)
+	 */
+#define match rem
+EXC(	LDFIRST	t3, FIRST(0)(src),	l_exc)
+	ADD	t2, zero, NBYTES
+EXC(	LDREST	t3, REST(0)(src),	l_exc_copy)
+	SUB	t2, t2, t1	# t2 = number of bytes copied
+	xor	match, t0, t1
+	STFIRST t3, FIRST(0)(dst)
+	beq	len, t2, done
+	 SUB	len, len, t2
+	ADD	dst, dst, t2
+	beqz	match, both_aligned
+	 ADD	src, src, t2
+
+src_unaligned_dst_aligned:
+	SRL	t0, len, LOG_NBYTES+2    # +2 for 4 units/iter
+	PREF(	0, 3*32(src) )
+	beqz	t0, cleanup_src_unaligned
+	 and	rem, len, (4*NBYTES-1)   # rem = len % 4*NBYTES
+	PREF(	1, 3*32(dst) )
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+EXC(	LDFIRST	t0, FIRST(0)(src),	l_exc)
+EXC(	LDFIRST	t1, FIRST(1)(src),	l_exc_copy)
+	SUB     len, len, 4*NBYTES
+EXC(	LDREST	t0, REST(0)(src),	l_exc_copy)
+EXC(	LDREST	t1, REST(1)(src),	l_exc_copy)
+EXC(	LDFIRST	t2, FIRST(2)(src),	l_exc_copy)
+EXC(	LDFIRST	t3, FIRST(3)(src),	l_exc_copy)
+EXC(	LDREST	t2, REST(2)(src),	l_exc_copy)
+EXC(	LDREST	t3, REST(3)(src),	l_exc_copy)
+	PREF(	0, 9*32(src) )		# 0 is PREF_LOAD  (not streamed)
+	ADD	src, src, 4*NBYTES
+#ifdef CONFIG_CPU_SB1
+	nop				# improves slotting
+#endif
+	STORE	t0, UNIT(0)(dst)
+	STORE	t1, UNIT(1)(dst)
+	STORE	t2, UNIT(2)(dst)
+	STORE	t3, UNIT(3)(dst)
+	PREF(	1, 9*32(dst) )     	# 1 is PREF_STORE (not streamed)
+	bne	len, rem, 1b
+	 ADD	dst, dst, 4*NBYTES
+
+cleanup_src_unaligned:
+	beqz	len, done
+	 and	rem, len, NBYTES-1  # rem = len % NBYTES
+	beq	rem, len, copy_bytes
+	 nop
+1:
+EXC(	LDFIRST t0, FIRST(0)(src),	l_exc)
+EXC(	LDREST	t0, REST(0)(src),	l_exc_copy)
+	ADD	src, src, NBYTES
+	SUB	len, len, NBYTES
+	STORE	t0, 0(dst)
+	bne	len, rem, 1b
+	 ADD	dst, dst, NBYTES
+
+copy_bytes_checklen:
+	beqz	len, done
+	 nop
+copy_bytes:
+	/* 0 < len < NBYTES  */
+#define COPY_BYTE(N)			\
+EXC(	lb	t0, N(src), l_exc);	\
+	SUB	len, len, 1;		\
+	beqz	len, done;		\
+	 sb	t0, N(dst)
+
+	COPY_BYTE(0)
+	COPY_BYTE(1)
+#ifdef USE_DOUBLE
+	COPY_BYTE(2)
+	COPY_BYTE(3)
+	COPY_BYTE(4)
+	COPY_BYTE(5)
+#endif
+EXC(	lb	t0, NBYTES-2(src), l_exc)
+	SUB	len, len, 1
+	jr	ra
+	 sb	t0, NBYTES-2(dst)
+done:
+	jr	ra
+	 nop
+	END(__copy_user_inatomic)
+
+l_exc_copy:
+	/*
+	 * Copy bytes from src until faulting load address (or until a
+	 * lb faults)
+	 *
+	 * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+	 * may be more than a byte beyond the last address.
+	 * Hence, the lb below may get an exception.
+	 *
+	 * Assumes src < THREAD_BUADDR($28)
+	 */
+	LOAD	t0, TI_TASK($28)
+	 nop
+	LOAD	t0, THREAD_BUADDR(t0)
+1:
+EXC(	lb	t1, 0(src),	l_exc)
+	ADD	src, src, 1
+	sb	t1, 0(dst)	# can't fault -- we're copy_from_user
+	bne	src, t0, 1b
+	 ADD	dst, dst, 1
+l_exc:
+	LOAD	t0, TI_TASK($28)
+	 nop
+	LOAD	t0, THREAD_BUADDR(t0)	# t0 is just past last good address
+	 nop
+	SUB	len, AT, t0		# len number of uncopied bytes
+	jr	ra
+	 nop
diff -Naur linux-2.6.20.1.orig/arch/mips/lib-32/dump_tlb.c linux-2.6.20.1/arch/mips/lib-32/dump_tlb.c
--- linux-2.6.20.1.orig/arch/mips/lib-32/dump_tlb.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/lib-32/dump_tlb.c	2007-02-20 16:47:41.000000000 -0800
@@ -40,8 +40,6 @@
 		return "256Mb";
 #endif
 	}
-
-	return "unknown";
 }
 
 #define BARRIER()					\
diff -Naur linux-2.6.20.1.orig/arch/mips/lib-64/dump_tlb.c linux-2.6.20.1/arch/mips/lib-64/dump_tlb.c
--- linux-2.6.20.1.orig/arch/mips/lib-64/dump_tlb.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/lib-64/dump_tlb.c	2007-02-20 16:47:41.000000000 -0800
@@ -31,8 +31,6 @@
 	case PM_256M:	return "256Mb";
 #endif
 	}
-
-	return "unknown";
 }
 
 #define BARRIER()					\
diff -Naur linux-2.6.20.1.orig/arch/mips/mm/c-sb1.c linux-2.6.20.1/arch/mips/mm/c-sb1.c
--- linux-2.6.20.1.orig/arch/mips/mm/c-sb1.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/mm/c-sb1.c	2007-02-20 16:47:41.000000000 -0800
@@ -259,6 +259,12 @@
 		on_each_cpu(sb1_flush_cache_data_page_ipi, (void *) addr, 1, 1);
 }
 #else
+
+static void local_sb1_flush_cache_data_page(unsigned long addr)
+{
+	__sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE);
+}
+
 void sb1_flush_cache_data_page(unsigned long)
 	__attribute__((alias("local_sb1_flush_cache_data_page")));
 #endif
diff -Naur linux-2.6.20.1.orig/arch/mips/mm/init.c linux-2.6.20.1/arch/mips/mm/init.c
--- linux-2.6.20.1.orig/arch/mips/mm/init.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/mm/init.c	2007-02-20 16:47:41.000000000 -0800
@@ -61,8 +61,6 @@
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-unsigned long highstart_pfn, highend_pfn;
-
 /*
  * We have up to 8 empty zeroed pages so we can map one of the right colour
  * when needed.  This is necessary only on R4000 / R4400 SC and MC versions
@@ -261,6 +259,8 @@
 
 
 #ifdef CONFIG_HIGHMEM
+unsigned long highstart_pfn, highend_pfn;
+
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
 
diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/Makefile linux-2.6.20.1/arch/mips/momentum/jaguar_atx/Makefile
--- linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/Makefile	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/momentum/jaguar_atx/Makefile	2007-02-20 16:47:41.000000000 -0800
@@ -6,7 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-obj-y += irq.o prom.o reset.o setup.o
+obj-y += irq.o platform.o prom.o reset.o setup.o
 
 obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o
 obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h linux-2.6.20.1/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h
--- linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h	2007-02-20 16:47:41.000000000 -0800
@@ -46,7 +46,9 @@
 
 extern unsigned long ja_fpga_base;
 
-#define JAGUAR_FPGA_WRITE(x,y) writeb(x, ja_fpga_base + JAGUAR_ATX_REG_##y)
-#define JAGUAR_FPGA_READ(x) readb(ja_fpga_base + JAGUAR_ATX_REG_##x)
+#define __FPGA_REG_TO_ADDR(reg)						\
+	((void *) ja_fpga_base + JAGUAR_ATX_REG_##reg)
+#define JAGUAR_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg))
+#define JAGUAR_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg))
 
 #endif
diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/platform.c linux-2.6.20.1/arch/mips/momentum/jaguar_atx/platform.c
--- linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/platform.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.20.1/arch/mips/momentum/jaguar_atx/platform.c	2007-02-20 16:47:41.000000000 -0800
@@ -0,0 +1,235 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "jaguar_atx_fpga.h"
+
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
+
+static struct resource mv643xx_eth_shared_resources[] = {
+	[0] = {
+		.name   = "ethernet shared base",
+		.start  = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
+		.end    = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
+		                       MV643XX_ETH_SHARED_REGS_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device mv643xx_eth_shared_device = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv643xx_eth_shared_resources),
+	.resource	= mv643xx_eth_shared_resources,
+};
+
+#define MV_SRAM_BASE			0xfe000000UL
+#define MV_SRAM_SIZE			(256 * 1024)
+
+#define MV_SRAM_RXRING_SIZE		(MV_SRAM_SIZE / 4)
+#define MV_SRAM_TXRING_SIZE		(MV_SRAM_SIZE / 4)
+
+#define MV_SRAM_BASE_ETH0		MV_SRAM_BASE
+#define MV_SRAM_BASE_ETH1		(MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
+
+#define MV64x60_IRQ_ETH_0 48
+#define MV64x60_IRQ_ETH_1 49
+#define MV64x60_IRQ_ETH_2 50
+
+#ifdef CONFIG_MV643XX_ETH_0
+
+static struct resource mv64x60_eth0_resources[] = {
+	[0] = {
+		.name	= "eth0 irq",
+		.start	= MV64x60_IRQ_ETH_0,
+		.end	= MV64x60_IRQ_ETH_0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static char eth0_mac_addr[ETH_ALEN];
+
+static struct mv643xx_eth_platform_data eth0_pd = {
+	.mac_addr	= eth0_mac_addr,
+
+	.tx_sram_addr	= MV_SRAM_BASE_ETH0,
+	.tx_sram_size	= MV_SRAM_TXRING_SIZE,
+	.tx_queue_size	= MV_SRAM_TXRING_SIZE / 16,
+
+	.rx_sram_addr	= MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
+	.rx_sram_size	= MV_SRAM_RXRING_SIZE,
+	.rx_queue_size	= MV_SRAM_RXRING_SIZE / 16,
+};
+
+static struct platform_device eth0_device = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth0_resources),
+	.resource	= mv64x60_eth0_resources,
+	.dev = {
+		.platform_data = ð0_pd,
+	},
+};
+#endif /* CONFIG_MV643XX_ETH_0 */
+
+#ifdef CONFIG_MV643XX_ETH_1
+
+static struct resource mv64x60_eth1_resources[] = {
+	[0] = {
+		.name	= "eth1 irq",
+		.start	= MV64x60_IRQ_ETH_1,
+		.end	= MV64x60_IRQ_ETH_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static char eth1_mac_addr[ETH_ALEN];
+
+static struct mv643xx_eth_platform_data eth1_pd = {
+	.mac_addr	= eth1_mac_addr,
+
+	.tx_sram_addr	= MV_SRAM_BASE_ETH1,
+	.tx_sram_size	= MV_SRAM_TXRING_SIZE,
+	.tx_queue_size	= MV_SRAM_TXRING_SIZE / 16,
+
+	.rx_sram_addr	= MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
+	.rx_sram_size	= MV_SRAM_RXRING_SIZE,
+	.rx_queue_size	= MV_SRAM_RXRING_SIZE / 16,
+};
+
+static struct platform_device eth1_device = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth1_resources),
+	.resource	= mv64x60_eth1_resources,
+	.dev = {
+		.platform_data = ð1_pd,
+	},
+};
+#endif /* CONFIG_MV643XX_ETH_1 */
+
+#ifdef CONFIG_MV643XX_ETH_2
+
+static struct resource mv64x60_eth2_resources[] = {
+	[0] = {
+		.name	= "eth2 irq",
+		.start	= MV64x60_IRQ_ETH_2,
+		.end	= MV64x60_IRQ_ETH_2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static char eth2_mac_addr[ETH_ALEN];
+
+static struct mv643xx_eth_platform_data eth2_pd = {
+	.mac_addr	= eth2_mac_addr,
+};
+
+static struct platform_device eth2_device = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(mv64x60_eth2_resources),
+	.resource	= mv64x60_eth2_resources,
+	.dev = {
+		.platform_data = ð2_pd,
+	},
+};
+#endif /* CONFIG_MV643XX_ETH_2 */
+
+static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
+	&mv643xx_eth_shared_device,
+#ifdef CONFIG_MV643XX_ETH_0
+	ð0_device,
+#endif
+#ifdef CONFIG_MV643XX_ETH_1
+	ð1_device,
+#endif
+#ifdef CONFIG_MV643XX_ETH_2
+	ð2_device,
+#endif
+};
+
+static u8 __init exchange_bit(u8 val, u8 cs)
+{
+	/* place the data */
+	JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
+	udelay(1);
+
+	/* turn the clock on */
+	JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
+	udelay(1);
+
+	/* turn the clock off and read-strobe */
+	JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
+
+	/* return the data */
+	return (JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
+}
+
+static void __init get_mac(char dest[6])
+{
+	u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	int i,j;
+
+	for (i = 0; i < 12; i++)
+		exchange_bit(read_opcode[i], 1);
+
+	for (j = 0; j < 6; j++) {
+		dest[j] = 0;
+		for (i = 0; i < 8; i++) {
+			dest[j] <<= 1;
+			dest[j] |= exchange_bit(0, 1);
+		}
+	}
+
+	/* turn off CS */
+	exchange_bit(0,0);
+}
+
+/*
+ * Copy and increment ethernet MAC address by a small value.
+ *
+ * This is useful for systems where the only one MAC address is stored in
+ * non-volatile memory for multiple ports.
+ */
+static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
+	unsigned int add)
+{
+	int i;
+
+	BUG_ON(add >= 256);
+
+	for (i = ETH_ALEN; i >= 0; i--) {
+		dst[i] = src[i] + add;
+		add = dst[i] < src[i];		/* compute carry */
+	}
+
+	WARN_ON(add);
+}
+
+static int __init mv643xx_eth_add_pds(void)
+{
+	unsigned char mac[ETH_ALEN];
+	int ret;
+
+	get_mac(mac);
+#ifdef CONFIG_MV643XX_ETH_0
+	eth_mac_add(eth1_mac_addr, mac, 0);
+#endif
+#ifdef CONFIG_MV643XX_ETH_1
+	eth_mac_add(eth1_mac_addr, mac, 1);
+#endif
+#ifdef CONFIG_MV643XX_ETH_2
+	eth_mac_add(eth2_mac_addr, mac, 2);
+#endif
+	ret = platform_add_devices(mv643xx_eth_pd_devs,
+			ARRAY_SIZE(mv643xx_eth_pd_devs));
+
+	return ret;
+}
+
+device_initcall(mv643xx_eth_add_pds);
+
+#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/prom.c linux-2.6.20.1/arch/mips/momentum/jaguar_atx/prom.c
--- linux-2.6.20.1.orig/arch/mips/momentum/jaguar_atx/prom.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/momentum/jaguar_atx/prom.c	2007-02-20 16:47:41.000000000 -0800
@@ -39,56 +39,6 @@
 	return "Momentum Jaguar-ATX";
 }
 
-#ifdef CONFIG_MV643XX_ETH
-extern unsigned char prom_mac_addr_base[6];
-
-static void burn_clocks(void)
-{
-	int i;
-
-	/* this loop should burn at least 1us -- this should be plenty */
-	for (i = 0; i < 0x10000; i++)
-		;
-}
-
-static u8 exchange_bit(u8 val, u8 cs)
-{
-	/* place the data */
-	JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
-	burn_clocks();
-
-	/* turn the clock on */
-	JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
-	burn_clocks();
-
-	/* turn the clock off and read-strobe */
-	JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
-
-	/* return the data */
-	return ((JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1);
-}
-
-void get_mac(char dest[6])
-{
-	u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-	int i,j;
-
-	for (i = 0; i < 12; i++)
-		exchange_bit(read_opcode[i], 1);
-
-	for (j = 0; j < 6; j++) {
-		dest[j] = 0;
-		for (i = 0; i < 8; i++) {
-			dest[j] <<= 1;
-			dest[j] |= exchange_bit(0, 1);
-		}
-	}
-
-	/* turn off CS */
-	exchange_bit(0,0);
-}
-#endif
-
 #ifdef CONFIG_64BIT
 
 unsigned long signext(unsigned long addr)
@@ -228,11 +178,6 @@
 #endif /* CONFIG_64BIT */
 	mips_machgroup = MACH_GROUP_MOMENCO;
 	mips_machtype = MACH_MOMENCO_JAGUAR_ATX;
-
-#ifdef CONFIG_MV643XX_ETH
-	/* get the base MAC address for on-board ethernet ports */
-	get_mac(prom_mac_addr_base);
-#endif
 }
 
 unsigned long __init prom_free_prom_memory(void)
diff -Naur linux-2.6.20.1.orig/arch/mips/momentum/ocelot_3/platform.c linux-2.6.20.1/arch/mips/momentum/ocelot_3/platform.c
--- linux-2.6.20.1.orig/arch/mips/momentum/ocelot_3/platform.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/momentum/ocelot_3/platform.c	2007-02-20 16:47:41.000000000 -0800
@@ -129,7 +129,7 @@
 
 static struct platform_device eth2_device = {
 	.name		= MV643XX_ETH_NAME,
-	.id		= 1,
+	.id		= 2,
 	.num_resources	= ARRAY_SIZE(mv64x60_eth2_resources),
 	.resource	= mv64x60_eth2_resources,
 	.dev = {
diff -Naur linux-2.6.20.1.orig/arch/mips/oprofile/Kconfig linux-2.6.20.1/arch/mips/oprofile/Kconfig
--- linux-2.6.20.1.orig/arch/mips/oprofile/Kconfig	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/oprofile/Kconfig	2007-02-20 16:47:41.000000000 -0800
@@ -11,7 +11,7 @@
 
 config OPROFILE
 	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING && EXPERIMENTAL
+	depends on PROFILING && !MIPS_MT_SMTC && EXPERIMENTAL
 	help
 	  OProfile is a profiling system capable of profiling the
 	  whole system, include the kernel, kernel modules, libraries,
diff -Naur linux-2.6.20.1.orig/arch/mips/pci/fixup-tb0219.c linux-2.6.20.1/arch/mips/pci/fixup-tb0219.c
--- linux-2.6.20.1.orig/arch/mips/pci/fixup-tb0219.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/pci/fixup-tb0219.c	2007-02-20 16:47:41.000000000 -0800
@@ -2,7 +2,7 @@
  *  fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups.
  *
  *  Copyright (C) 2003  Megasolution Inc. 
- *  Copyright (C) 2004  Yoichi Yuasa 
+ *  Copyright (C) 2004-2005  Yoichi Yuasa 
  *
  *  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
diff -Naur linux-2.6.20.1.orig/arch/mips/pci/pci.c linux-2.6.20.1/arch/mips/pci/pci.c
--- linux-2.6.20.1.orig/arch/mips/pci/pci.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/pci/pci.c	2007-02-20 16:47:41.000000000 -0800
@@ -79,6 +79,14 @@
 {
 	*hose_tail = hose;
 	hose_tail = &hose->next;
+
+	/*
+	 * Do not panic here but later - this might hapen before console init.
+	 */
+	if (!hose->io_map_base) {
+		printk(KERN_WARNING
+		       "registering PCI controller with io_map_base unset\n");
+	}
 }
 
 /* Most MIPS systems have straight-forward swizzling needs.  */
@@ -103,10 +111,15 @@
 	return PCI_SLOT(dev->devfn);
 }
 
+int mips_system_has_legacy_ide;
+
+EXPORT_SYMBOL_GPL(mips_system_has_legacy_ide);
+
 static int __init pcibios_init(void)
 {
 	struct pci_controller *hose;
 	struct pci_bus *bus;
+	struct pci_dev *dev;
 	int next_busno;
 	int need_domain_info = 0;
 
@@ -150,6 +163,13 @@
 		pci_assign_unassigned_resources();
 	pci_fixup_irqs(common_swizzle, pcibios_map_irq);
 
+	if ((dev = pci_get_class(PCI_CLASS_BRIDGE_EISA << 8, NULL)) != NULL ||
+	    (dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL)) != NULL) {
+		pci_dev_put(dev);
+
+		mips_system_has_legacy_ide = 1;
+	}
+
 	return 0;
 }
 
diff -Naur linux-2.6.20.1.orig/arch/mips/pmc-sierra/yosemite/dbg_io.c linux-2.6.20.1/arch/mips/pmc-sierra/yosemite/dbg_io.c
--- linux-2.6.20.1.orig/arch/mips/pmc-sierra/yosemite/dbg_io.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/pmc-sierra/yosemite/dbg_io.c	2007-02-20 16:47:41.000000000 -0800
@@ -93,7 +93,7 @@
  * Functions to READ and WRITE to serial port 1
  */
 #define	SERIAL_READ_1(ofs)		(*((volatile unsigned char*)	\
-					(TITAN_SERIAL_BASE_1 + ofs)
+					(TITAN_SERIAL_BASE_1 + ofs)))
 
 #define	SERIAL_WRITE_1(ofs, val)	((*((volatile unsigned char*)	\
 					(TITAN_SERIAL_BASE_1 + ofs))) = val)
diff -Naur linux-2.6.20.1.orig/arch/mips/pmc-sierra/yosemite/setup.c linux-2.6.20.1/arch/mips/pmc-sierra/yosemite/setup.c
--- linux-2.6.20.1.orig/arch/mips/pmc-sierra/yosemite/setup.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/pmc-sierra/yosemite/setup.c	2007-02-20 16:47:41.000000000 -0800
@@ -171,6 +171,7 @@
 
 static void __init py_uart_setup(void)
 {
+#ifdef CONFIG_SERIAL_8250
 	struct uart_port up;
 
 	/*
@@ -188,6 +189,7 @@
 
 	if (early_serial_setup(&up))
 		printk(KERN_ERR "Early serial init of port 0 failed\n");
+#endif /* CONFIG_SERIAL_8250 */
 }
 
 static void __init py_rtc_setup(void)
diff -Naur linux-2.6.20.1.orig/arch/mips/qemu/Makefile linux-2.6.20.1/arch/mips/qemu/Makefile
--- linux-2.6.20.1.orig/arch/mips/qemu/Makefile	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/qemu/Makefile	2007-02-20 16:47:41.000000000 -0800
@@ -4,4 +4,5 @@
 
 obj-y		= q-firmware.o q-irq.o q-mem.o q-setup.o q-reset.o
 
+obj-$(CONFIG_VT) += q-vga.o
 obj-$(CONFIG_SMP) += q-smp.o
diff -Naur linux-2.6.20.1.orig/arch/mips/qemu/q-setup.c linux-2.6.20.1/arch/mips/qemu/q-setup.c
--- linux-2.6.20.1.orig/arch/mips/qemu/q-setup.c	2007-02-19 22:34:32.000000000 -0800
+++ linux-2.6.20.1/arch/mips/qemu/q-setup.c	2007-02-20 16:47:41.000000000 -0800
@@ -2,6 +2,7 @@
 #include 
 #include 
 
+extern void qvga_init(void);
 extern void qemu_reboot_setup(void);
 
 #define QEMU_PORT_BASE 0xb4000000
@@ -23,5 +24,9 @@
 void __init plat_mem_setup(void)
 {
 	set_io_port_base(QEMU_PORT_BASE);
+#ifdef CONFIG_VT
+	qvga_init();
+#endif
+
 	qemu_reboot_setup();
 }
diff -Naur linux-2.6.20.1.orig/arch/mips/qemu/q-vga.c linux-2.6.20.1/arch/mips/qemu/q-vga.c
--- linux-2.6.20.1.orig/arch/mips/qemu/q-vga.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.20.1/arch/mips/qemu/q-vga.c	2007-02-20 16:47:41.000000000 -0800
@@ -0,0 +1,189 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This will eventually go into the qemu firmware.
+ */
+#include 
+#include 
+#include 
+#include 
+#include