## Automatically generated incremental diff
## From:   linux-2.2.8-pre4
## To:     linux-2.2.8-pre5
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp hpa $

diff -urN linux-2.2.8-pre4/arch/alpha/kernel/osf_sys.c linux-2.2.8-pre5/arch/alpha/kernel/osf_sys.c
--- linux-2.2.8-pre4/arch/alpha/kernel/osf_sys.c	2003-08-15 15:06:09.000000000 -0700
+++ linux-2.2.8-pre5/arch/alpha/kernel/osf_sys.c	2003-08-15 15:06:10.000000000 -0700
@@ -141,6 +141,7 @@
 	struct inode *inode;
 	struct osf_dirent_callback buf;
 
+	lock_kernel();
 	error = -EBADF;
 	file = fget(fd);
 	if (!file)
@@ -173,6 +174,7 @@
 out_putf:
 	fput(file);
 out:
+	unlock_kernel();
 	return error;
 }
 
diff -urN linux-2.2.8-pre4/arch/arm/kernel/sys_arm.c linux-2.2.8-pre5/arch/arm/kernel/sys_arm.c
--- linux-2.2.8-pre4/arch/arm/kernel/sys_arm.c	1998-12-17 09:05:42.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/kernel/sys_arm.c	2003-08-15 15:06:10.000000000 -0700
@@ -77,12 +77,14 @@
 		goto out;
 	if (!(a.flags & MAP_ANONYMOUS)) {
 		error = -EBADF;
-		if (a.fd >= current->files->max_fds || 
-		    !(file = current->files->fd[a.fd]))
+		file = fget(a.fd);
+		if (!file)
 			goto out;
 	}
 	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 	error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+	if (file)
+		fput(file);
 out:
 	unlock_kernel();
 	return error;
diff -urN linux-2.2.8-pre4/arch/arm/mm/fault-armo.c linux-2.2.8-pre5/arch/arm/mm/fault-armo.c
--- linux-2.2.8-pre4/arch/arm/mm/fault-armo.c	1998-12-17 09:05:42.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/mm/fault-armo.c	2003-08-15 15:06:10.000000000 -0700
@@ -1,11 +1,10 @@
 /*
- *  linux/arch/arm/mm/fault.c
+ *  linux/arch/arm/mm/fault-armo.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Modifications for ARM processor (c) 1995, 1996 Russell King
+ *  Modifications for ARM processor (c) 1995-1999 Russell King
  */
 
-#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -15,8 +14,7 @@
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -27,35 +25,32 @@
 #define FAULT_CODE_WRITE	0x02
 #define FAULT_CODE_USER		0x01
 
-struct pgtable_cache_struct quicklists;
+#define DO_COW(m)		((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW))
+#define READ_FAULT(m)		(!((m) & FAULT_CODE_WRITE))
 
-void __bad_pmd(pmd_t *pmd)
+#include "fault-common.c"
+
+static void *alloc_table(int size, int prio)
 {
-	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-#ifdef CONFIG_DEBUG_ERRORS
-	__backtrace();
-#endif
-	set_pmd(pmd, mk_pmd(BAD_PAGETABLE));
+	if (size != 128)
+		printk("invalid table size\n");
+	return (void *)get_page_8k(prio);
 }
 
-void __bad_pmd_kernel(pmd_t *pmd)
+void free_table(void *table)
 {
-	printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
-#ifdef CONFIG_DEBUG_ERRORS
-	__backtrace();
-#endif
-	set_pmd(pmd, mk_pmd(BAD_PAGETABLE));
+	free_page_8k((unsigned long)table);
 }
 
 pgd_t *get_pgd_slow(void)
 {
-	pgd_t *pgd = (pgd_t *) kmalloc(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL);
+	pgd_t *pgd = (pgd_t *)alloc_table(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL);
 	pgd_t *init;
-	
+
 	if (pgd) {
 		init = pgd_offset(&init_mm, 0);
-		memzero (pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
-		memcpy (pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+		memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
+		memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
 			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
 	}
 	return pgd;
@@ -65,17 +60,17 @@
 {
 	pte_t *pte;
 
-	pte = (pte_t *) kmalloc (PTRS_PER_PTE * BYTES_PER_PTR, GFP_KERNEL);
+	pte = (pte_t *)alloc_table(PTRS_PER_PTE * BYTES_PER_PTR, GFP_KERNEL);
 	if (pmd_none(*pmd)) {
 		if (pte) {
-			memzero (pte, PTRS_PER_PTE * BYTES_PER_PTR);
+			memzero(pte, PTRS_PER_PTE * BYTES_PER_PTR);
 			set_pmd(pmd, mk_pmd(pte));
 			return pte + offset;
 		}
 		set_pmd(pmd, mk_pmd(BAD_PAGETABLE));
 		return NULL;
 	}
-	kfree (pte);
+	free_table((void *)pte);
 	if (pmd_bad(*pmd)) {
 		__bad_pmd(pmd);
 		return NULL;
@@ -83,126 +78,22 @@
 	return (pte_t *) pmd_page(*pmd) + offset;
 }
 
-extern void die_if_kernel(char *msg, struct pt_regs *regs, unsigned int err, unsigned int ret);
-
-static void kernel_page_fault (unsigned long addr, int mode, struct pt_regs *regs,
-			       struct task_struct *tsk, struct mm_struct *mm)
-{
-	/*
-	 * Oops. The kernel tried to access some bad page. We'll have to
-	 * terminate things with extreme prejudice.
-	 */
-	pgd_t *pgd;
-	if (addr < PAGE_SIZE)
-	    printk (KERN_ALERT "Unable to handle kernel NULL pointer dereference");
-	else
-	    printk (KERN_ALERT "Unable to handle kernel paging request");
-	printk (" at virtual address %08lx\n", addr);
-	printk (KERN_ALERT "current->tss.memmap = %08lX\n", tsk->tss.memmap);
-	pgd = pgd_offset (mm, addr);
-	printk (KERN_ALERT "*pgd = %08lx", pgd_val (*pgd));
-	if (!pgd_none (*pgd)) {
-		pmd_t *pmd;
-		pmd = pmd_offset (pgd, addr);
-		printk (", *pmd = %08lx", pmd_val (*pmd));
-		if (!pmd_none (*pmd))
-			printk (", *pte = %08lx", pte_val (*pte_offset (pmd, addr)));
-	}
-	printk ("\n");
-	die_if_kernel ("Oops", regs, mode, SIGKILL);
-	do_exit (SIGKILL);
-}
-
-static void
-handle_dataabort (unsigned long addr, int mode, struct pt_regs *regs)
-{
-	struct task_struct *tsk;
-	struct mm_struct *mm;
-	struct vm_area_struct *vma;
-	unsigned long fixup;
-
-	lock_kernel();
-	tsk = current;
-	mm = tsk->mm;
-
-	down(&mm->mmap_sem);
-	vma = find_vma (mm, addr);
-	if (!vma)
-		goto bad_area;
-	if (addr >= vma->vm_start)
-		goto good_area;
-	if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack (vma, addr))
-		goto bad_area;
-
-	/*
-	 * Ok, we have a good vm_area for this memory access, so
-	 * we can handle it..
-	 */
-good_area:
-	if (!(mode & FAULT_CODE_WRITE)) { /* write? */
-		if (!(vma->vm_flags & (VM_READ|VM_EXEC)))
-			goto bad_area;
-	} else {
-		if (!(vma->vm_flags & VM_WRITE))
-			goto bad_area;
-	}
-	handle_mm_fault (tsk, vma, addr, mode & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW));
-	up(&mm->mmap_sem);
-	goto out;
-
-	/*
-	 * Something tried to access memory that isn't in our memory map..
-	 * Fix it, but check if it's kernel or user first..
-	 */
-bad_area:
-	up(&mm->mmap_sem);
-	if (mode & FAULT_CODE_USER) {
-//extern int console_loglevel;
-//cli();
-		tsk->tss.error_code = mode;
-		tsk->tss.trap_no = 14;
-//console_loglevel = 9;
-		printk ("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
-			tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
-//#ifdef DEBUG
-		show_regs (regs);
-		c_backtrace (regs->ARM_fp, 0);
-//#endif
-		force_sig(SIGSEGV, tsk);
-//while (1);
-		goto out;
-	}
-
-	/* Are we prepared to handle this kernel fault?  */
-	if ((fixup = search_exception_table(instruction_pointer(regs))) != 0) {
-		printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
-			tsk->comm, regs->ARM_pc, addr, fixup);
-		regs->ARM_pc = fixup;
-		goto out;
-	}
-
-
-	kernel_page_fault (addr, mode, regs, tsk, mm);
-out:
-	unlock_kernel();
-}
-
 /*
  * Handle a data abort.  Note that we have to handle a range of addresses
  * on ARM2/3 for ldm.  If both pages are zero-mapped, then we have to force
- * a copy-on-write
+ * a copy-on-write.  However, on the second page, we always force COW.
  */
 asmlinkage void
-do_DataAbort (unsigned long min_addr, unsigned long max_addr, int mode, struct pt_regs *regs)
+do_DataAbort(unsigned long min_addr, unsigned long max_addr, int mode, struct pt_regs *regs)
 {
-	handle_dataabort (min_addr, mode, regs);
+	do_page_fault(min_addr, mode, regs);
 
 	if ((min_addr ^ max_addr) >> PAGE_SHIFT)
-		handle_dataabort (max_addr, mode | FAULT_CODE_FORCECOW, regs);
+		do_page_fault(max_addr, mode | FAULT_CODE_FORCECOW, regs);
 }
 
 asmlinkage int
-do_PrefetchAbort (unsigned long addr, int mode, struct pt_regs *regs)
+do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
 {
 #if 0
 	if (the memc mapping for this page exists - can check now...) {
@@ -210,6 +101,6 @@
 		return 0;
 	}
 #endif
-	handle_dataabort (addr, mode, regs);
+	do_page_fault(addr, FAULT_CODE_USER|FAULT_CODE_PREFETCH, regs);
 	return 1;
 }
diff -urN linux-2.2.8-pre4/arch/arm/mm/fault-armv.c linux-2.2.8-pre5/arch/arm/mm/fault-armv.c
--- linux-2.2.8-pre4/arch/arm/mm/fault-armv.c	1998-12-17 09:05:42.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/mm/fault-armv.c	2003-08-15 15:06:10.000000000 -0700
@@ -1,10 +1,11 @@
 /*
- *  linux/arch/arm/mm/fault.c
+ *  linux/arch/arm/mm/fault-armv.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Modifications for ARM processor (c) 1995, 1996 Russell King
+ *  Modifications for ARM processor (c) 1995-1999 Russell King
  */
 
+#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -14,43 +15,37 @@
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/unaligned.h>
 
 #define FAULT_CODE_READ		0x02
 #define FAULT_CODE_USER		0x01
 
-struct pgtable_cache_struct quicklists;
+#define DO_COW(m)		(!((m) & FAULT_CODE_READ))
+#define READ_FAULT(m)		((m) & FAULT_CODE_READ)
 
-void __bad_pmd(pmd_t *pmd)
-{
-	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-	set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
-}
-
-void __bad_pmd_kernel(pmd_t *pmd)
-{
-	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-	set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
-}
+#include "fault-common.c"
 
 pgd_t *get_pgd_slow(void)
 {
 	/*
 	 * need to get a 16k page for level 1
 	 */
-	pgd_t *pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,2);
+	pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL,2);
 	pgd_t *init;
-	
+
 	if (pgd) {
 		init = pgd_offset(&init_mm, 0);
-		memzero ((void *)pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
-		memcpy (pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+		memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
+		memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
 			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
+		clean_cache_area(pgd, PTRS_PER_PGD * BYTES_PER_PTR);
 	}
 	return pgd;
 }
@@ -59,17 +54,19 @@
 {
 	pte_t *pte;
 
-	pte = (pte_t *) get_small_page(GFP_KERNEL);
+	pte = (pte_t *)get_page_2k(GFP_KERNEL);
 	if (pmd_none(*pmd)) {
 		if (pte) {
-			memzero (pte, PTRS_PER_PTE * BYTES_PER_PTR);
+			memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
+			clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
+			pte += PTRS_PER_PTE;
 			set_pmd(pmd, mk_user_pmd(pte));
 			return pte + offset;
 		}
 		set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
 		return NULL;
 	}
-	free_small_page ((unsigned long) pte);
+	free_page_2k((unsigned long)pte);
 	if (pmd_bad(*pmd)) {
 		__bad_pmd(pmd);
 		return NULL;
@@ -81,17 +78,19 @@
 {
 	pte_t *pte;
 
-	pte = (pte_t *) get_small_page(GFP_KERNEL);
+	pte = (pte_t *)get_page_2k(GFP_KERNEL);
 	if (pmd_none(*pmd)) {
 		if (pte) {
-			memzero (pte, PTRS_PER_PTE * BYTES_PER_PTR);
+			memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
+			clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
+			pte += PTRS_PER_PTE;
 			set_pmd(pmd, mk_kernel_pmd(pte));
 			return pte + offset;
 		}
 		set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
 		return NULL;
 	}
-	free_small_page ((unsigned long) pte);
+	free_page_2k((unsigned long)pte);
 	if (pmd_bad(*pmd)) {
 		__bad_pmd_kernel(pmd);
 		return NULL;
@@ -99,10 +98,8 @@
 	return (pte_t *) pmd_page(*pmd) + offset;
 }
 
-extern void die_if_kernel(char *msg, struct pt_regs *regs, unsigned int err, unsigned int ret);
-
 #ifdef DEBUG
-static int sp_valid (unsigned long *sp)
+static int sp_valid(unsigned long *sp)
 {
 	unsigned long addr = (unsigned long) sp;
 
@@ -114,187 +111,371 @@
 }
 #endif
 
-static void kernel_page_fault (unsigned long addr, int mode, struct pt_regs *regs,
-			       struct task_struct *tsk, struct mm_struct *mm)
+#ifdef CONFIG_ALIGNMENT_TRAP
+/*
+ * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
+ * /proc/sys/debug/alignment, modified and integrated into
+ * Linux 2.1 by Russell King
+ *
+ * NOTE!!! This is not portable onto the ARM6/ARM7 processors yet.  Also,
+ * it seems to give a severe performance impact (1 abort/ms - NW runs at
+ * ARM6 speeds) with GCC 2.7.2.2 - needs checking with a later GCC/EGCS.
+ *
+ * IMHO, I don't think that the trap handler is advantageous on ARM6,7
+ * processors (they'll run like an ARM3).  We'll see.
+ */
+#define CODING_BITS(i)	(i & 0x0e000000)
+
+#define LDST_I_BIT(i)	(i & (1 << 26))		/* Immediate constant	*/
+#define LDST_P_BIT(i)	(i & (1 << 24))		/* Preindex		*/
+#define LDST_U_BIT(i)	(i & (1 << 23))		/* Add offset		*/
+#define LDST_W_BIT(i)	(i & (1 << 21))		/* Writeback		*/
+#define LDST_L_BIT(i)	(i & (1 << 20))		/* Load			*/
+
+#define LDSTH_I_BIT(i)	(i & (1 << 22))		/* half-word immed	*/
+#define LDM_S_BIT(i)	(i & (1 << 22))		/* write CPSR from SPSR	*/
+
+#define RN_BITS(i)	((i >> 16) & 15)	/* Rn			*/
+#define RD_BITS(i)	((i >> 12) & 15)	/* Rd			*/
+#define RM_BITS(i)	(i & 15)		/* Rm			*/
+
+#define REGMASK_BITS(i)	(i & 0xffff)
+#define OFFSET_BITS(i)	(i & 0x0fff)
+
+#define IS_SHIFT(i)	(i & 0x0ff0)
+#define SHIFT_BITS(i)	((i >> 7) & 0x1f)
+#define SHIFT_TYPE(i)	(i & 0x60)
+#define SHIFT_LSL	0x00
+#define SHIFT_LSR	0x20
+#define SHIFT_ASR	0x40
+#define SHIFT_RORRRX	0x60
+
+static unsigned long ai_user;
+static unsigned long ai_sys;
+static unsigned long ai_skipped;
+static unsigned long ai_half;
+static unsigned long ai_word;
+static unsigned long ai_multi;
+
+static int proc_alignment_read(char *page, char **start, off_t off,
+			       int count, int *eof, void *data)
 {
-	/*
-	 * Oops. The kernel tried to access some bad page. We'll have to
-	 * terminate things with extreme prejudice.
-	 */
-	pgd_t *pgd;
-	if (addr < PAGE_SIZE)
-	    printk (KERN_ALERT "Unable to handle kernel NULL pointer dereference");
-	else
-	    printk (KERN_ALERT "Unable to handle kernel paging request");
-	printk (" at virtual address %08lx\n", addr);
-	printk (KERN_ALERT "current->tss.memmap = %08lX\n", tsk->tss.memmap);
-	pgd = pgd_offset (mm, addr);
-	printk (KERN_ALERT "*pgd = %08lx", pgd_val (*pgd));
-	if (!pgd_none (*pgd)) {
-		pmd_t *pmd;
-		pmd = pmd_offset (pgd, addr);
-		printk (", *pmd = %08lx", pmd_val (*pmd));
-		if (!pmd_none (*pmd))
-			printk (", *pte = %08lx", pte_val (*pte_offset (pmd, addr)));
-	}
-	printk ("\n");
-	die_if_kernel ("Oops", regs, mode, SIGKILL);
-	do_exit (SIGKILL);
+	char *p = page;
+	int len;
+
+	p += sprintf(p, "User:\t\t%li\n", ai_user);
+	p += sprintf(p, "System:\t\t%li\n", ai_sys);
+	p += sprintf(p, "Skipped:\t%li\n", ai_skipped);
+	p += sprintf(p, "Half:\t\t%li\n", ai_half);
+	p += sprintf(p, "Word:\t\t%li\n", ai_word);
+	p += sprintf(p, "Multi:\t\t%li\n", ai_multi);
+
+	len = (p - page) - off;
+	if (len < 0)
+		len = 0;
+
+	*eof = (len <= count) ? 1 : 0;
+	*start = page + off;
+
+	return len;
 }
 
-static void page_fault (unsigned long addr, int mode, struct pt_regs *regs)
+/*
+ * This needs to be done after sysctl_init, otherwise sys/
+ * will be overwritten.
+ */
+void __init alignment_init(void)
 {
-	struct task_struct *tsk;
-	struct mm_struct *mm;
-	struct vm_area_struct *vma;
-	unsigned long fixup;
-
-	lock_kernel();
-	tsk = current;
-	mm = tsk->mm;
-
-	down(&mm->mmap_sem);
-	vma = find_vma (mm, addr);
-	if (!vma)
-		goto bad_area;
-	if (vma->vm_start <= addr)
-		goto good_area;
-	if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack (vma, addr))
-		goto bad_area;
+	struct proc_dir_entry *e;
 
-	/*
-	 * Ok, we have a good vm_area for this memory access, so
-	 * we can handle it..
-	 */
-good_area:
-	if (mode & FAULT_CODE_READ) { /* read? */
-		if (!(vma->vm_flags & (VM_READ|VM_EXEC)))
-			goto bad_area;
-	} else {
-		if (!(vma->vm_flags & VM_WRITE))
-			goto bad_area;
+	e = create_proc_entry("sys/debug/alignment", S_IFREG | S_IRUGO, NULL);
+
+	if (e)
+		e->read_proc = proc_alignment_read;
+}
+
+static int
+do_alignment_exception(struct pt_regs *regs)
+{
+	unsigned int instr, rd, rn, correction, nr_regs, regbits;
+	unsigned long eaddr;
+	union { unsigned long un; signed long sn; } offset;
+
+	if (user_mode(regs)) {
+		set_cr(cr_no_alignment);
+		ai_user += 1;
+		return 0;
 	}
-	handle_mm_fault (tsk, vma, addr & PAGE_MASK, !(mode & FAULT_CODE_READ));
-	up(&mm->mmap_sem);
-	goto out;
 
-	/*
-	 * Something tried to access memory that isn't in our memory map..
-	 * Fix it, but check if it's kernel or user first..
-	 */
-bad_area:
-	up(&mm->mmap_sem);
-	if (mode & FAULT_CODE_USER) {
-		tsk->tss.error_code = mode;
-		tsk->tss.trap_no = 14;
-		printk ("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
-			tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
-#ifdef DEBUG
-		{
-			unsigned int i, j;
-			unsigned long *sp = (unsigned long *) (regs->ARM_sp - 128);
-			for (j = 0; j < 20 && sp_valid (sp); j++) {
-				printk ("%p: ", sp);
-				for (i = 0; i < 8 && sp_valid (sp); i += 1, sp++)
-					printk ("%08lx ", *sp);
-				printk ("\n");
+	ai_sys += 1;
+
+	instr = *(unsigned long *)instruction_pointer(regs);
+	correction = 4; /* sometimes 8 on ARMv3 */
+	regs->ARM_pc += correction + 4;
+
+	rd = RD_BITS(instr);
+	rn = RN_BITS(instr);
+	eaddr = regs->uregs[rn];
+
+	switch(CODING_BITS(instr)) {
+	case 0x00000000:
+		if ((instr & 0x0ff00ff0) == 0x01000090) {
+			ai_skipped += 1;
+			printk(KERN_ERR "Unaligned trap: not handling swp instruction\n");
+			return 1;
+		}
+
+		if (((instr & 0x0e000090) == 0x00000090) && (instr & 0x60) != 0) {
+			ai_half += 1;
+			if (LDSTH_I_BIT(instr))
+				offset.un = (instr & 0xf00) >> 4 | (instr & 15);
+			else
+				offset.un = regs->uregs[RM_BITS(instr)];
+
+			if (LDST_P_BIT(instr)) {
+				if (LDST_U_BIT(instr))
+					eaddr += offset.un;
+				else
+					eaddr -= offset.un;
 			}
+
+			if (LDST_L_BIT(instr))
+				regs->uregs[rd] = get_unaligned((unsigned short *)eaddr);
+			else
+				put_unaligned(regs->uregs[rd], (unsigned short *)eaddr);
+
+			/* signed half-word? */
+			if (instr & 0x40)
+				regs->uregs[rd] = (long)((short) regs->uregs[rd]);
+
+			if (!LDST_P_BIT(instr)) {
+				if (LDST_U_BIT(instr))
+					eaddr += offset.un;
+				else
+					eaddr -= offset.un;
+				regs->uregs[rn] = eaddr;
+			} else if (LDST_W_BIT(instr))
+				regs->uregs[rn] = eaddr;
+			break;
 		}
-		show_regs (regs);
-		c_backtrace (regs->ARM_fp, regs->ARM_cpsr);
-#endif
-		force_sig(SIGSEGV, tsk);
-		goto out;
-	}
 
-	/* Are we prepared to handle this kernel fault?  */
-	if ((fixup = search_exception_table(instruction_pointer(regs))) != 0) {
-		printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
-			tsk->comm, regs->ARM_pc, addr, fixup);
-		regs->ARM_pc = fixup;
-		goto out;
+	default:
+		ai_skipped += 1;
+		panic("Alignment trap: not handling instruction %08X at %08lX",
+				instr, regs->ARM_pc - correction - 4);
+		break;
+
+	case 0x04000000:
+		offset.un = OFFSET_BITS(instr);
+		goto ldr_str;
+
+	case 0x06000000:
+		offset.un = regs->uregs[RM_BITS(instr)];
+
+		if (IS_SHIFT(instr)) {
+			unsigned int shiftval = SHIFT_BITS(instr);
+
+			switch(SHIFT_TYPE(instr)) {
+			case SHIFT_LSL:
+				offset.un <<= shiftval;
+				break;
+
+			case SHIFT_LSR:
+				offset.un >>= shiftval;
+				break;
+
+			case SHIFT_ASR:
+				offset.sn >>= shiftval;
+				break;
+
+			case SHIFT_RORRRX:
+				if (shiftval == 0) {
+					offset.un >>= 1;
+					if (regs->ARM_cpsr & CC_C_BIT)
+						offset.un |= 1 << 31;
+				} else
+					offset.un = offset.un >> shiftval |
+							  offset.un << (32 - shiftval);
+				break;
+			}
+		}
+
+	ldr_str:
+		ai_word += 1;
+		if (LDST_P_BIT(instr)) {
+			if (LDST_U_BIT(instr))
+				eaddr += offset.un;
+			else
+				eaddr -= offset.un;
+		} else {
+			if (LDST_W_BIT(instr)) {
+				printk(KERN_ERR "Not handling ldrt/strt correctly\n");
+				return 1;
+			}
+		}
+
+		if (LDST_L_BIT(instr)) {
+			regs->uregs[rd] = get_unaligned((unsigned long *)eaddr);
+			if (rd == 15)
+				correction = 0;
+		} else
+			put_unaligned(regs->uregs[rd], (unsigned long *)eaddr);
+
+		if (!LDST_P_BIT(instr)) {
+			if (LDST_U_BIT(instr))
+				eaddr += offset.un;
+			else
+				eaddr -= offset.un;
+
+			regs->uregs[rn] = eaddr;
+		} else if (LDST_W_BIT(instr))
+			regs->uregs[rn] = eaddr;
+		break;
+
+	case 0x08000000:
+		if (LDM_S_BIT(instr))
+			panic("Alignment trap: not handling LDM with s-bit\n");
+		ai_multi += 1;
+
+		for (regbits = REGMASK_BITS(instr), nr_regs = 0; regbits; regbits >>= 1)
+			nr_regs += 4;
+
+		if  (!LDST_U_BIT(instr))
+			eaddr -= nr_regs;
+
+		if ((LDST_U_BIT(instr) == 0 && LDST_P_BIT(instr) == 0) ||
+		    (LDST_U_BIT(instr)      && LDST_P_BIT(instr)))
+			eaddr += 4;
+
+		for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
+			if (regbits & 1) {
+				if (LDST_L_BIT(instr)) {
+					regs->uregs[rd] = get_unaligned((unsigned long *)eaddr);
+					if (rd == 15)
+						correction = 0;
+				} else
+					put_unaligned(regs->uregs[rd], (unsigned long *)eaddr);
+				eaddr += 4;
+			}
+
+		if (LDST_W_BIT(instr)) {
+			if (LDST_P_BIT(instr) && !LDST_U_BIT(instr))
+				eaddr -= nr_regs;
+			else if (LDST_P_BIT(instr))
+				eaddr -= 4;
+			else if (!LDST_U_BIT(instr))
+				eaddr -= 4 + nr_regs;
+			regs->uregs[rn] = eaddr;
+		}
+		break;
 	}
 
-	kernel_page_fault (addr, mode, regs, tsk, mm);
-out:
-	unlock_kernel();
+	regs->ARM_pc -= correction;
+
+	return 0;
 }
 
-/*
- * Handle a data abort.  Note that we have to handle a range of addresses
- * on ARM2/3 for ldm.  If both pages are zero-mapped, then we have to force
- * a copy-on-write
- */
+#endif
+
 asmlinkage void
-do_DataAbort (unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
+do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
 {
 	if (user_mode(regs))
 		error_code |= FAULT_CODE_USER;
+
 #define DIE(signr,nam)\
 		force_sig(signr, current);\
-		die_if_kernel(nam, regs, fsr, signr);\
-		break;
+		die(nam, regs, fsr);\
+		do_exit(signr);\
+		break
 
 	switch (fsr & 15) {
-	case 2:
-		DIE(SIGKILL, "Terminal exception")
+	/*
+	 *  0 - vector exception
+	 */
 	case 0:
-		DIE(SIGSEGV, "Vector exception")
+		force_sig(SIGSEGV, current);
+		if (!user_mode(regs)) {
+			die("vector exception", regs, fsr);
+			do_exit(SIGSEGV);
+		}
+		break;
+
+	/*
+	 * 15 - permission fault on page
+	 *  5 - page-table entry descriptor fault
+	 *  7 - first-level descriptor fault
+	 */
+	case 15: case 5: case 7:
+		do_page_fault(addr, error_code, regs);
+		break;
+
+	/*
+	 * 13 - permission fault on section
+	 */
+	case 13:
+		force_sig(SIGSEGV, current);
+		if (!user_mode(regs)) {
+			die("section permission fault", regs, fsr);
+			do_exit(SIGSEGV);
+		} else {
+#ifdef CONFIG_DEBUG_USER
+			printk("%s: permission fault on section, "
+			       "address=0x%08lx, code %d\n",
+			       current->comm, addr, error_code);
+#ifdef DEBUG
+			{
+				unsigned int i, j;
+				unsigned long *sp;
+
+				sp = (unsigned long *) (regs->ARM_sp - 128);
+				for (j = 0; j < 20 && sp_valid(sp); j++) {
+					printk("%p: ", sp);
+					for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++)
+						printk("%08lx ", *sp);
+					printk("\n");
+				}
+				show_regs(regs);
+				c_backtrace(regs->ARM_fp, regs->ARM_cpsr);
+			}
+#endif
+#endif
+		}
+		break;
+
 	case 1:
 	case 3:
-		DIE(SIGBUS, "Alignment exception")
+#ifdef CONFIG_ALIGNMENT_TRAP
+		if (!do_alignment_exception(regs))
+			break;
+#endif
+		/*
+		 * this should never happen
+		 */
+		DIE(SIGBUS, "Alignment exception");
+		break;
+
+	case 2:
+		DIE(SIGKILL, "Terminal exception");
 	case 12:
 	case 14:
-		DIE(SIGBUS, "External abort on translation")
+		DIE(SIGBUS, "External abort on translation");
 	case 9:
 	case 11:
-		DIE(SIGSEGV, "Domain fault")
-	case 13:/* permission fault on section */
-#ifdef DEBUG
-		{
-			unsigned int i, j;
-			unsigned long *sp;
-
-			printk ("%s: section permission fault (bad address=0x%08lx, code %d)\n",
-				current->comm, addr, error_code);
-			sp = (unsigned long *) (regs->ARM_sp - 128);
-			for (j = 0; j < 20 && sp_valid (sp); j++) {
-				printk ("%p: ", sp);
-				for (i = 0; i < 8 && sp_valid (sp); i += 1, sp++)
-					printk ("%08lx ", *sp);
-				printk ("\n");
-			}
-			show_regs (regs);
-			c_backtrace(regs->ARM_fp, regs->ARM_cpsr);
-		}
-#endif
-		DIE(SIGSEGV, "Permission fault")
+		DIE(SIGSEGV, "Domain fault");
 
-	case 15:/* permission fault on page */
-	case 5:	/* page-table entry descriptor fault */
-	case 7:	/* first-level descriptor fault */
-		page_fault (addr, error_code, regs);
-		break;
 	case 4:
 	case 6:
-		DIE(SIGBUS, "External abort on linefetch")
+		DIE(SIGBUS, "External abort on linefetch");
 	case 8:
 	case 10:
-		DIE(SIGBUS, "External abort on non-linefetch")
+		DIE(SIGBUS, "External abort on non-linefetch");
 	}
 }
 
 asmlinkage int
-do_PrefetchAbort (unsigned long addr, struct pt_regs *regs)
+do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
 {
-#if 0
-	/* does this still apply ? */
-	if (the memc mapping for this page exists - can check now...) {
-		printk ("Page in, but got abort (undefined instruction?)\n");
-		return 0;
-	}
-#endif
-	page_fault (addr, FAULT_CODE_USER|FAULT_CODE_READ, regs);
+	do_page_fault(addr, FAULT_CODE_USER|FAULT_CODE_READ, regs);
 	return 1;
 }
-
diff -urN linux-2.2.8-pre4/arch/arm/mm/fault-common.c linux-2.2.8-pre5/arch/arm/mm/fault-common.c
--- linux-2.2.8-pre4/arch/arm/mm/fault-common.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/mm/fault-common.c	2003-08-15 15:06:10.000000000 -0700
@@ -0,0 +1,188 @@
+/*
+ *  linux/arch/arm/mm/fault-common.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Modifications for ARM processor (c) 1995-1999 Russell King
+ */
+#include <linux/config.h>
+
+extern void die(char *msg, struct pt_regs *regs, unsigned int err);
+
+void __bad_pmd(pmd_t *pmd)
+{
+	printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+#ifdef CONFIG_DEBUG_ERRORS
+	__backtrace();
+#endif
+	set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
+}
+
+void __bad_pmd_kernel(pmd_t *pmd)
+{
+	printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
+#ifdef CONFIG_DEBUG_ERRORS
+	__backtrace();
+#endif
+	set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
+}
+
+static void
+kernel_page_fault(unsigned long addr, int mode, struct pt_regs *regs,
+		  struct task_struct *tsk, struct mm_struct *mm)
+{
+	char *reason;
+	/*
+	 * Oops. The kernel tried to access some bad page. We'll have to
+	 * terminate things with extreme prejudice.
+	 */
+	pgd_t *pgd;
+
+	if (addr < PAGE_SIZE)
+		reason = "NULL pointer dereference";
+	else
+		reason = "paging request";
+
+	printk(KERN_ALERT "Unable to handle kernel %s at virtual address %08lx\n",
+		reason, addr);
+	printk(KERN_ALERT "memmap = %08lX, pgd = %p\n", tsk->tss.memmap, mm->pgd);
+	pgd = pgd_offset(mm, addr);
+	printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd));
+
+	do {
+		pmd_t *pmd;
+		pte_t *pte;
+
+		if (pgd_none(*pgd))
+			break;
+
+		if (pgd_bad(*pgd)) {
+			printk("(bad)\n");
+			break;
+		}
+
+		pmd = pmd_offset(pgd, addr);
+		printk(", *pmd = %08lx", pmd_val(*pmd));
+
+		if (pmd_none(*pmd))
+			break;
+
+		if (pmd_bad(*pmd)) {
+			printk("(bad)\n");
+			break;
+		}
+
+		pte = pte_offset(pmd, addr);
+		printk(", *pte = %08lx", pte_val(*pte));
+		printk(", *ppte = %08lx", pte_val(pte[-PTRS_PER_PTE]));
+	} while(0);
+
+	printk("\n");
+	die("Oops", regs, mode);
+
+	do_exit(SIGKILL);
+}
+
+static void do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
+{
+	struct task_struct *tsk;
+	struct mm_struct *mm;
+	struct vm_area_struct *vma;
+	unsigned long fixup;
+
+	tsk = current;
+	mm  = tsk->mm;
+
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_interrupt() || mm == &init_mm)
+		goto no_context;
+
+	down(&mm->mmap_sem);
+	vma = find_vma(mm, addr);
+	if (!vma)
+		goto bad_area;
+	if (vma->vm_start <= addr)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack(vma, addr))
+		goto bad_area;
+
+	/*
+	 * Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
+good_area:
+	if (READ_FAULT(mode)) { /* read? */
+		if (!(vma->vm_flags & (VM_READ|VM_EXEC)))
+			goto bad_area;
+	} else {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	}
+
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+	if (!handle_mm_fault(tsk, vma, addr & PAGE_MASK, DO_COW(mode)))
+		goto do_sigbus;
+
+	up(&mm->mmap_sem);
+	return;
+
+	/*
+	 * Something tried to access memory that isn't in our memory map..
+	 * Fix it, but check if it's kernel or user first..
+	 */
+bad_area:
+	up(&mm->mmap_sem);
+
+	/* User mode accesses just cause a SIGSEGV */
+	if (mode & FAULT_CODE_USER) {
+		tsk->tss.error_code = mode;
+		tsk->tss.trap_no = 14;
+#ifdef CONFIG_DEBUG_USER
+		printk("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
+			tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
+#endif
+		force_sig(SIGSEGV, tsk);
+		return;
+	}
+
+no_context:
+	/* Are we prepared to handle this kernel fault?  */
+	if ((fixup = search_exception_table(instruction_pointer(regs))) != 0) {
+#ifdef DEBUG
+		printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
+			tsk->comm, regs->ARM_pc, addr, fixup);
+#endif
+		regs->ARM_pc = fixup;
+		return;
+	}
+
+	kernel_page_fault(addr, mode, regs, tsk, mm);
+	return;
+
+do_sigbus:
+	/*
+	 * We ran out of memory, or some other thing happened to us that made
+	 * us unable to handle the page fault gracefully.
+	 */
+	up(&mm->mmap_sem);
+
+	/*
+	 * Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 */
+	tsk->tss.error_code = mode;
+	tsk->tss.trap_no = 14;
+	force_sig(SIGBUS, tsk);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (!(mode & FAULT_CODE_USER))
+		goto no_context;
+}
+
+
diff -urN linux-2.2.8-pre4/arch/arm/mm/init.c linux-2.2.8-pre5/arch/arm/mm/init.c
--- linux-2.2.8-pre4/arch/arm/mm/init.c	1998-12-17 09:05:42.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/mm/init.c	2003-08-15 15:06:10.000000000 -0700
@@ -29,6 +29,9 @@
 #include <asm/proc/mm-init.h>
 
 pgd_t swapper_pg_dir[PTRS_PER_PGD];
+#ifndef CONFIG_NO_PGT_CACHE
+struct pgtable_cache_struct quicklists;
+#endif
 
 extern char _etext, _stext, _edata, __bss_start, _end;
 extern char __init_begin, __init_end;
@@ -36,6 +39,7 @@
 int do_check_pgt_cache(int low, int high)
 {
 	int freed = 0;
+#ifndef CONFIG_NO_PGT_CACHE
 	if(pgtable_cache_size > high) {
 		do {
 			if(pgd_quicklist)
@@ -46,6 +50,7 @@
 				free_pte_slow(get_pte_fast()), freed++;
 		} while(pgtable_cache_size > low);
 	}
+#endif
 	return freed;
 }
 
@@ -63,17 +68,18 @@
  * data and COW.
  */
 #if PTRS_PER_PTE != 1
-unsigned long *empty_bad_page_table;
+pte_t *empty_bad_page_table;
 
 pte_t *__bad_pagetable(void)
 {
-	int i;
 	pte_t bad_page;
+	int i;
 
 	bad_page = BAD_PAGE;
 	for (i = 0; i < PTRS_PER_PTE; i++)
-		empty_bad_page_table[i] = (unsigned long)pte_val(bad_page);
-	return (pte_t *) empty_bad_page_table;
+		set_pte(empty_bad_page_table + i, bad_page);
+
+	return empty_bad_page_table;
 }
 #endif
 
@@ -128,8 +134,11 @@
 	empty_bad_page = (unsigned long *)start_mem;
 	start_mem += PAGE_SIZE;
 #if PTRS_PER_PTE != 1
-	empty_bad_page_table = (unsigned long *)start_mem;
-	start_mem += PTRS_PER_PTE * sizeof (void *);
+#ifdef CONFIG_CPU_32
+	start_mem += PTRS_PER_PTE * BYTES_PER_PTR;
+#endif
+	empty_bad_page_table = (pte_t *)start_mem;
+	start_mem += PTRS_PER_PTE * BYTES_PER_PTR;
 #endif
 	memzero (empty_zero_page, PAGE_SIZE);
 	start_mem = setup_pagetables (start_mem, end_mem);
@@ -137,6 +146,9 @@
 	flush_tlb_all();
 	update_memc_all();
 
+	end_mem &= PAGE_MASK;
+	high_memory = (void *)end_mem;
+
 	return free_area_init(start_mem, end_mem);
 }
 
@@ -161,19 +173,18 @@
 	/* mark usable pages in the mem_map[] */
 	mark_usable_memory_areas(&start_mem, end_mem);
 
+#define BETWEEN(w,min,max) ((w) >= (unsigned long)(min) && \
+			    (w) < (unsigned long)(max))
+
 	for (tmp = PAGE_OFFSET; tmp < end_mem ; tmp += PAGE_SIZE) {
 		if (PageReserved(mem_map+MAP_NR(tmp))) {
-			if (tmp >= KERNTOPHYS(_stext) &&
-			    tmp < KERNTOPHYS(_edata)) {
-				if (tmp < KERNTOPHYS(_etext))
-					codepages++;
-				else
-					datapages++;
-			} else if (tmp >= KERNTOPHYS(__init_begin)
-				   && tmp < KERNTOPHYS(__init_end))
+			if (BETWEEN(tmp, &__init_begin, &__init_end))
 				initpages++;
-			else if (tmp >= KERNTOPHYS(__bss_start)
-				 && tmp < (unsigned long) start_mem)
+			else if (BETWEEN(tmp, &_stext, &_etext))
+				codepages++;
+			else if (BETWEEN(tmp, &_etext, &_edata))
+				datapages++;
+			else if (BETWEEN(tmp, &__bss_start, start_mem))
 				datapages++;
 			else
 				reservedpages++;
@@ -181,13 +192,16 @@
 		}
 		atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
 #ifdef CONFIG_BLK_DEV_INITRD
-		if (!initrd_start || (tmp < initrd_start || tmp >= initrd_end))
+		if (!initrd_start || !BETWEEN(tmp, initrd_start, initrd_end))
 #endif
 			free_page(tmp);
 	}
-	printk ("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
+
+#undef BETWEEN
+
+	printk ("Memory: %luk/%luM available (%dk code, %dk reserved, %dk data, %dk init)\n",
 		 (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
-		 max_mapnr << (PAGE_SHIFT-10),
+		 max_mapnr >> (20 - PAGE_SHIFT),
 		 codepages << (PAGE_SHIFT-10),
 		 reservedpages << (PAGE_SHIFT-10),
 		 datapages << (PAGE_SHIFT-10),
@@ -203,17 +217,45 @@
 #endif
 }
 
-void free_initmem (void)
+static void free_area(unsigned long addr, unsigned long end, char *s)
 {
-	unsigned long addr;
+	unsigned int size = (end - addr) >> 10;
 
-	addr = (unsigned long)(&__init_begin);
-	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+	for (; addr < end; addr += PAGE_SIZE) {
 		mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
 		atomic_set(&mem_map[MAP_NR(addr)].count, 1);
 		free_page(addr);
 	}
-	printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
+
+	if (size)
+		printk(" %dk %s", size, s);
+}
+
+void free_initmem (void)
+{
+	printk("Freeing unused kernel memory:");
+
+	free_area((unsigned long)(&__init_begin),
+		  (unsigned long)(&__init_end),
+		  "init");
+
+#ifdef CONFIG_FOOTBRIDGE
+	{
+	extern int __netwinder_begin, __netwinder_end, __ebsa285_begin, __ebsa285_end;
+
+	if (!machine_is_netwinder())
+		free_area((unsigned long)(&__netwinder_begin),
+			  (unsigned long)(&__netwinder_end),
+			  "netwinder");
+
+	if (!machine_is_ebsa285() && !machine_is_cats())
+		free_area((unsigned long)(&__ebsa285_begin),
+			  (unsigned long)(&__ebsa285_end),
+			  "ebsa285/cats");
+	}
+#endif
+
+	printk("\n");
 }
 
 void si_meminfo(struct sysinfo *val)
diff -urN linux-2.2.8-pre4/arch/arm/mm/ioremap.c linux-2.2.8-pre5/arch/arm/mm/ioremap.c
--- linux-2.2.8-pre4/arch/arm/mm/ioremap.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/mm/ioremap.c	2003-08-15 15:06:10.000000000 -0700
@@ -0,0 +1,149 @@
+/*
+ * arch/arm/mm/ioremap.c
+ *
+ * Re-map IO memory to kernel address space so that we can access it.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ *
+ * Hacked for ARM by Phil Blundell <philb@gnu.org>
+ * Hacked to allow all architectures to build, and various cleanups
+ * by Russell King
+ */
+
+/*
+ * This allows a driver to remap an arbitrary region of bus memory into
+ * virtual space.  One should *only* use readl, writel, memcpy_toio and
+ * so on with such remapped areas.
+ *
+ * Because the ARM only has a 32-bit address space we can't address the
+ * whole of the (physical) PCI space at once.  PCI huge-mode addressing
+ * allows us to circumvent this restriction by splitting PCI space into
+ * two 2GB chunks and mapping only one at a time into processor memory.
+ * We use MMU protection domains to trap any attempt to access the bank
+ * that is not currently mapped.  (This isn't fully implemented yet.)
+ *
+ * DC21285 currently has a bug in that the PCI address extension
+ * register affects the address of any writes waiting in the outbound
+ * FIFO.  Unfortunately, it is not possible to tell the DC21285 to
+ * flush this - flushing the area causes the bus to lock.
+ */
+
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+	unsigned long phys_addr, pgprot_t pgprot)
+{
+	unsigned long end;
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	do {
+		if (!pte_none(*pte))
+			printk("remap_area_pte: page already exists\n");
+		set_pte(pte, mk_pte_phys(phys_addr, pgprot));
+		address += PAGE_SIZE;
+		phys_addr += PAGE_SIZE;
+		pte++;
+	} while (address < end);
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
+	unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+	pgprot_t pgprot;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+
+	phys_addr -= address;
+	pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
+	do {
+		pte_t * pte = pte_alloc_kernel(pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address < end);
+	return 0;
+}
+
+static int remap_area_pages(unsigned long address, unsigned long phys_addr,
+				 unsigned long size, unsigned long flags)
+{
+	pgd_t * dir;
+	unsigned long end = address + size;
+
+	phys_addr -= address;
+	dir = pgd_offset(&init_mm, address);
+	flush_cache_all();
+	while (address < end) {
+		pmd_t *pmd = pmd_alloc_kernel(dir, address);
+		if (!pmd)
+			return -ENOMEM;
+		if (remap_area_pmd(pmd, address, end - address,
+					 phys_addr + address, flags))
+			return -ENOMEM;
+		set_pgdir(address, *dir);
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	}
+	flush_tlb_all();
+	return 0;
+}
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ *
+ * 'flags' are the extra L_PTE_ flags that you want to specify for this
+ * mapping.  See include/asm-arm/proc-armv/pgtable.h for more information.
+ */
+void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+{
+	void * addr;
+	struct vm_struct * area;
+	unsigned long offset;
+
+	/*
+	 * Mappings have to be page-aligned
+	 */
+	offset = phys_addr & ~PAGE_MASK;
+	size = PAGE_ALIGN(size + offset);
+
+	/*
+	 * Don't allow mappings that wrap..
+	 */
+	if (!size || size > phys_addr + size)
+		return NULL;
+
+	/*
+	 * Ok, go for it..
+	 */
+	area = get_vm_area(size);
+	if (!area)
+		return NULL;
+	addr = area->addr;
+	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+		vfree(addr);
+		return NULL;
+	}
+	return (void *) (offset + (char *)addr);
+}
+
+void iounmap(void *addr)
+{
+	return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+}
diff -urN linux-2.2.8-pre4/arch/arm/mm/Makefile linux-2.2.8-pre5/arch/arm/mm/Makefile
--- linux-2.2.8-pre4/arch/arm/mm/Makefile	1998-05-08 00:42:38.000000000 -0700
+++ linux-2.2.8-pre5/arch/arm/mm/Makefile	2003-08-15 15:06:10.000000000 -0700
@@ -8,37 +8,30 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 all:	lib first_rule
-ifeq ($(MACHINE),a5k)
-MMARCH=arc
-else
-MMARCH=$(MACHINE)
-endif
 
 O_TARGET := mm.o
-O_OBJS   := init.o extable.o fault-$(PROCESSOR).o mm-$(MMARCH).o
+O_OBJS   := init.o extable.o fault-$(PROCESSOR).o small_page.o
 
 ifeq ($(PROCESSOR),armo)
  O_OBJS += proc-arm2,3.o
 endif
 
 ifeq ($(PROCESSOR),armv)
- O_OBJS += small_page.o proc-arm6,7.o proc-sa110.o
+ O_OBJS += mm-$(MACHINE).o proc-arm6,7.o proc-sa110.o ioremap.o
 endif
 
 include $(TOPDIR)/Rules.make
 
-proc-arm2,3.o:	../lib/constants.h
-proc-arm6,7.o:	../lib/constants.h
-proc-sa110.o:	../lib/constants.h
-
 %.o: %.S
-ifneq ($(CONFIG_BINUTILS_NEW),y)
-	$(CC) $(CFLAGS) -D__ASSEMBLY__ -E $< | tr ';$$' '\n#' > ..$@.tmp.s
-	$(CC) $(CFLAGS:-pipe=) -c -o $@ ..$@.tmp.s
-	$(RM) ..$@.tmp.s
-else
 	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $<
-endif
 
 .PHONY:	lib
 lib:;	@$(MAKE) -C ../lib constants.h
+
+# Special dependencies
+fault-armv.o: fault-common.c
+fault-armo.o: fault-common.c
+proc-arm2,3.o:	../lib/constants.h
+proc-arm6,7.o:	../lib/constants.h
+proc-sa110.o:	../lib/constants.h
+
diff -urN linux-2.2.8-pre4/arch/arm/mm/mm-arc.c linux-2.2.8-pre5/arch/arm/mm/mm-arc.c
--- linux-2.2.8-pre4/arch/arm/mm/mm-arc.c	1998-07-18 11:55:23.000000000 -0700
+++ linux-2.2.8-pre5/arch/arm/mm/mm-arc.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,82 +0,0 @@
-/*
- * arch/arm/mm/mm-arc.c
- *
- * Extra MM routines for the Archimedes architecture
- *
- * Copyright (C) 1998 Russell King
- */
-#include <linux/init.h>
-#include <asm/hardware.h>
-#include <asm/pgtable.h>
-
-unsigned long phys_screen_end;
-
-/*
- * This routine needs more work to make it dynamically release/allocate mem!
- */
-__initfunc(unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update))
-{
-	static int updated = 0;
-
-	if (updated)
-		return 0;
-
-	updated = update;
-
-	if (update) {
-		unsigned long address = log_start, offset;
-		pgd_t *pgdp;
-
-		kmem = (kmem + 3) & ~3;
-
-		pgdp = pgd_offset (&init_mm, address);				/* +31 */
-		offset = SCREEN_START;
-		while (address < SCREEN1_END) {
-			unsigned long addr_pmd, end_pmd;
-			pmd_t *pmdp;
-
-			/* if (pgd_none (*pgdp)) alloc pmd */
-			pmdp = pmd_offset (pgdp, address);			/* +0 */
-			addr_pmd = address & ~PGDIR_MASK;			/* 088000 */
-			end_pmd = addr_pmd + SCREEN1_END - address;		/* 100000 */
-			if (end_pmd > PGDIR_SIZE)
-				end_pmd = PGDIR_SIZE;
-
-			do {
-				unsigned long addr_pte, end_pte;
-				pte_t *ptep;
-
-				if (pmd_none (*pmdp)) {
-					pte_t *new_pte = (pte_t *)kmem;
-					kmem += PTRS_PER_PTE * BYTES_PER_PTR;
-					memzero (new_pte, PTRS_PER_PTE * BYTES_PER_PTR);
-					set_pmd (pmdp, mk_pmd(new_pte));
-				}
-
-				ptep = pte_offset (pmdp, addr_pmd);		/* +11 */
-				addr_pte = addr_pmd & ~PMD_MASK;		/* 088000 */
-				end_pte = addr_pte + end_pmd - addr_pmd;	/* 100000 */
-				if (end_pte > PMD_SIZE)
-					end_pte = PMD_SIZE;
-
-				do {
-					set_pte (ptep, mk_pte(offset, PAGE_KERNEL));
-					addr_pte += PAGE_SIZE;
-					offset += PAGE_SIZE;
-					ptep++;
-				} while (addr_pte < end_pte);
-
-				pmdp++;
-				addr_pmd = (addr_pmd + PMD_SIZE) & PMD_MASK;
-			} while (addr_pmd < end_pmd);
-
-			address = (address + PGDIR_SIZE) & PGDIR_MASK;
-			pgdp ++;
-		}
-
-		phys_screen_end = offset;
-		flush_tlb_all ();
-		update_memc_all ();
-	}
-	return kmem;
-}
diff -urN linux-2.2.8-pre4/arch/arm/mm/mm-armv.c linux-2.2.8-pre5/arch/arm/mm/mm-armv.c
--- linux-2.2.8-pre4/arch/arm/mm/mm-armv.c	1998-09-06 10:44:47.000000000 -0700
+++ linux-2.2.8-pre5/arch/arm/mm/mm-armv.c	2003-08-15 15:06:10.000000000 -0700
@@ -37,7 +37,8 @@
 		virtual = mp->virtual;
 		physical = mp->physical;
 		length = mp->length;
-		prot = (mp->prot_read ? PTE_AP_READ : 0) | (mp->prot_write ? PTE_AP_WRITE : 0);
+		prot = (mp->prot_read ? L_PTE_USER : 0) | (mp->prot_write ? L_PTE_WRITE : 0)
+			| L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY;
 
 		while ((virtual & 1048575 || physical & 1048575) && length >= PAGE_SIZE) {
 			alloc_init_page(&start_mem, virtual, physical, mp->domain, prot);
@@ -56,7 +57,8 @@
 			physical += 1048576;
 		}
 
-		prot = (mp->prot_read ? PTE_AP_READ : 0) | (mp->prot_write ? PTE_AP_WRITE : 0);
+		prot = (mp->prot_read ? L_PTE_USER : 0) | (mp->prot_write ? L_PTE_WRITE : 0)
+			| L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY;
 
 		while (length >= PAGE_SIZE) {
 			alloc_init_page(&start_mem, virtual, physical, mp->domain, prot);
diff -urN linux-2.2.8-pre4/arch/arm/mm/mm-ebsa285.c linux-2.2.8-pre5/arch/arm/mm/mm-ebsa285.c
--- linux-2.2.8-pre4/arch/arm/mm/mm-ebsa285.c	1998-12-17 09:05:42.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/mm/mm-ebsa285.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,39 +0,0 @@
-/*
- * arch/arm/mm/mm-ebsa285.c
- *
- * Extra MM routines for the EBSA285 architecture
- *
- * Copyright (C) 1998 Russell King, Dave Gilbert.
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
- 
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/proc/mm-init.h>
-#include <asm/dec21285.h>
-
-/*
- * This is to allow us to fiddle with the EEPROM
- *  This entry will go away in time, once the fmu
- *  can mmap() the flash.
- *
- * These ones are so that we can fiddle
- *  with the various cards (eg VGA)
- *  until we're happy with them...
- */
-#define MAPPING \
-  { 0xd8000000, DC21285_FLASH,		      0x00400000, DOMAIN_USER, 1, 1 },	/* EEPROM */	    \
-  { 0xdc000000, 0x7c000000,		      0x00100000, DOMAIN_USER, 1, 1 },	/* VGA */	    \
-  { 0xe0000000, DC21285_PCI_MEM,	      0x18000000, DOMAIN_USER, 1, 1 },	/* VGA */	    \
-  { 0xf8000000, DC21285_PCI_TYPE_0_CONFIG,    0x01000000, DOMAIN_IO  , 0, 1 },	/* Type 0 Config */ \
-  { 0xf9000000, DC21285_PCI_TYPE_1_CONFIG,    0x01000000, DOMAIN_IO  , 0, 1 },	/* Type 1 Config */ \
-  { PCI_IACK,	DC21285_PCI_IACK,	      0x01000000, DOMAIN_IO  , 0, 1 },	/* PCI IACK	 */ \
-  { 0xfd000000, DC21285_OUTBOUND_WRITE_FLUSH, 0x01000000, DOMAIN_IO  , 0, 1 },	/* Out wrflsh	 */ \
-  { 0xfe000000, DC21285_ARMCSR_BASE,	      0x01000000, DOMAIN_IO  , 0, 1 },	/* CSR		 */ \
-  { 0xffe00000, DC21285_PCI_IO, 	      0x00100000, DOMAIN_IO  , 0, 1 },	/* PCI I/O	 */ \
-  { 0xfff00000, 0x40000000,		      0x00100000, DOMAIN_IO  , 0, 1 },	/* X-Bus	 */
-
-#include "mm-armv.c"
diff -urN linux-2.2.8-pre4/arch/arm/mm/mm-footbridge.c linux-2.2.8-pre5/arch/arm/mm/mm-footbridge.c
--- linux-2.2.8-pre4/arch/arm/mm/mm-footbridge.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/mm/mm-footbridge.c	2003-08-15 15:06:10.000000000 -0700
@@ -0,0 +1,91 @@
+/*
+ * arch/arm/mm/mm-ebsa285.c
+ *
+ * Extra MM routines for the EBSA285 architecture
+ *
+ * Copyright (C) 1998 Russell King, Dave Gilbert.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+ 
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/proc/mm-init.h>
+#include <asm/dec21285.h>
+
+/*
+ * The first entry allows us to fiddle with the EEPROM from user-space.
+ *  This entry will go away in time, once the fmu32 can mmap() the
+ *  flash.  It can't at the moment.
+ *
+ * If you want to fiddle with PCI VGA cards from user space, then
+ * change the '0, 1 }' for the PCI MEM and PCI IO to '1, 1 }'
+ * You can then access the PCI bus at 0xe0000000 and 0xffe00000.
+ */
+
+#ifdef CONFIG_HOST_FOOTBRIDGE
+
+/*
+ * The mapping when the footbridge is in host mode.
+ */
+#define MAPPING \
+ { FLASH_BASE,   DC21285_FLASH,			FLASH_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { PCIMEM_BASE,  DC21285_PCI_MEM,		PCIMEM_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG,	PCICFG0_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG,	PCICFG1_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { PCIIACK_BASE, DC21285_PCI_IACK,		PCIIACK_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { WFLUSH_BASE,  DC21285_OUTBOUND_WRITE_FLUSH,	WFLUSH_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { ARMCSR_BASE,  DC21285_ARMCSR_BASE,		ARMCSR_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { PCIO_BASE,    DC21285_PCI_IO,		PCIO_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { XBUS_BASE,    0x40000000,			XBUS_SIZE,	DOMAIN_IO, 0, 1 }
+
+#else
+
+/*
+ * These two functions convert virtual addresses to PCI addresses
+ * and PCI addresses to virtual addresses.  Note that it is only
+ * legal to use these on memory obtained via get_free_page or
+ * kmalloc.
+ */
+unsigned long __virt_to_bus(unsigned long res)
+{
+#ifdef CONFIG_DEBUG_ERRORS
+	if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) {
+		printk("__virt_to_phys: invalid virtual address 0x%08lx\n", res);
+		__backtrace();
+	}
+#endif
+	return (res - PAGE_OFFSET) + (*CSR_PCISDRAMBASE & 0xfffffff0);
+}
+
+unsigned long __bus_to_virt(unsigned long res)
+{
+	res -= (*CSR_PCISDRAMBASE & 0xfffffff0);
+	res += PAGE_OFFSET;
+
+#ifdef CONFIG_DEBUG_ERRORS
+	if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) {
+		printk("__phys_to_virt: invalid virtual address 0x%08lx\n", res);
+		__backtrace();
+	}
+#endif
+	return res;
+}
+
+/*
+ * The mapping when the footbridge is in add-in mode.
+ */
+#define MAPPING \
+ { PCIO_BASE,	 DC21285_PCI_IO,		PCIO_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { XBUS_BASE,	 0x40000000,			XBUS_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { ARMCSR_BASE,  DC21285_ARMCSR_BASE,		ARMCSR_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { WFLUSH_BASE,	 DC21285_OUTBOUND_WRITE_FLUSH,	WFLUSH_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { FLASH_BASE,	 DC21285_FLASH,			FLASH_SIZE,	DOMAIN_IO, 0, 1 }, \
+ { PCIMEM_BASE,	 DC21285_PCI_MEM,		PCIMEM_SIZE,	DOMAIN_IO, 0, 1 }
+
+#endif
+
+#include "mm-armv.c"
diff -urN linux-2.2.8-pre4/arch/arm/mm/mm-vnc.c linux-2.2.8-pre5/arch/arm/mm/mm-vnc.c
--- linux-2.2.8-pre4/arch/arm/mm/mm-vnc.c	1998-12-17 09:05:42.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/mm/mm-vnc.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,31 +0,0 @@
-/*
- * arch/arm/mm/mm-vnc.c
- *
- * Extra MM routines for the Corel VNC architecture
- *
- * Copyright (C) 1998 Russell King
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
- 
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/proc/mm-init.h>
-#include <asm/dec21285.h>
-
-/* Table describing the MMU translation mapping
- * mainly used to set up the I/O mappings.
- */ 
-#define MAPPING \
-  { 0xd0000000, DC21285_FLASH,		      0x00800000, DOMAIN_IO  , 0, 1 },	/* Flash	 */ \
-  { 0xe0000000, DC21285_PCI_MEM,	      0x18000000, DOMAIN_IO  , 0, 1 },	/* PCI Mem 	 */ \
-  { 0xf8000000, DC21285_PCI_TYPE_0_CONFIG,    0x01000000, DOMAIN_IO  , 0, 1 },	/* Type 0 Config */ \
-  { 0xf9000000, DC21285_PCI_TYPE_1_CONFIG,    0x01000000, DOMAIN_IO  , 0, 1 },	/* Type 1 Config */ \
-  { PCI_IACK,	DC21285_PCI_IACK,	      0x01000000, DOMAIN_IO  , 0, 1 },	/* PCI IACK	 */ \
-  { 0xfd000000, DC21285_OUTBOUND_WRITE_FLUSH, 0x01000000, DOMAIN_IO  , 0, 1 },	/* Out wrflsh	 */ \
-  { 0xfe000000, DC21285_ARMCSR_BASE,	      0x01000000, DOMAIN_IO  , 0, 1 },	/* CSR		 */ \
-  { 0xffe00000, DC21285_PCI_IO, 	      0x00100000, DOMAIN_IO  , 0, 1 },	/* PCI I/O	 */ \
-
-#include "mm-armv.c"
diff -urN linux-2.2.8-pre4/arch/arm/mm/proc-arm2,3.S linux-2.2.8-pre5/arch/arm/mm/proc-arm2,3.S
--- linux-2.2.8-pre4/arch/arm/mm/proc-arm2,3.S	1998-05-20 18:54:35.000000000 -0700
+++ linux-2.2.8-pre5/arch/arm/mm/proc-arm2,3.S	2003-08-15 15:06:10.000000000 -0700
@@ -193,7 +193,7 @@
 		movs	pc, lr
 
 _arm2_3_check_bugs:
-		movs	pc, lr
+		bics	pc, lr, #0x04000000		@ Clear FIQ disable bit
 
 /*
  * Processor specific - ARM2
@@ -206,6 +206,8 @@
  * Params  : prev	Old task structure
  *	   : next	New task structure for process to run
  *
+ * Returns : prev
+ *
  * Purpose : Perform a task switch, saving the old processes state, and restoring
  *	     the new.
  *
@@ -218,15 +220,15 @@
 		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
 		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
 		mov	r4, r1
-		add	r0, r1, #TSS_MEMCMAP		@ Remap MEMC
+		add	r7, r1, #TSS_MEMCMAP		@ Remap MEMC
 		ldr	r1, LC0
 		ldr	r1, [r1]
-1:		ldmia	r0!, {r2, r3, r5, r6}
+1:		ldmia	r7!, {r2, r3, r5, r6}
 		strb	r2, [r2]
 		strb	r3, [r3]
 		strb	r5, [r5]
 		strb	r6, [r6]
-		ldmia	r0!, {r2, r3, r5, r6}
+		ldmia	r7!, {r2, r3, r5, r6}
 		strb	r2, [r2]
 		strb	r3, [r3]
 		strb	r5, [r5]
@@ -318,6 +320,8 @@
  * Params  : prev	Old task structure
  *	   : next	New task structure for process to run
  *
+ * Returns : prev
+ *
  * Purpose : Perform a task switch, saving the old processes state, and restoring
  *	     the new.
  *
@@ -330,22 +334,22 @@
 		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
 		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
 		mov	r4, r1
-		add	r0, r1, #TSS_MEMCMAP		@ Remap MEMC
+		add	r7, r1, #TSS_MEMCMAP		@ Remap MEMC
 		ldr	r1, LC0
 		ldr	r1, [r1]
-1:		ldmia	r0!, {r2, r3, r5, r6}
+1:		ldmia	r7!, {r2, r3, r5, r6}
 		strb	r2, [r2]
 		strb	r3, [r3]
 		strb	r5, [r5]
 		strb	r6, [r6]
-		ldmia	r0!, {r2, r3, r5, r6}
+		ldmia	r7!, {r2, r3, r5, r6}
 		strb	r2, [r2]
 		strb	r3, [r3]
 		strb	r5, [r5]
 		strb	r6, [r6]
 		subs	r1, r1, #8
 		bhi	1b
-		mcr	p15, 0, r0, c1, c0, 0		@ flush cache
+		mcr	p15, 0, r7, c1, c0, 0		@ flush cache
 		ldmfd	sp!, {r4 - r9, fp, pc}^		@ Load all regs saved previously
 /*
  * Function: arm3_remap_memc (struct task_struct *tsk)
diff -urN linux-2.2.8-pre4/arch/arm/mm/proc-arm6,7.S linux-2.2.8-pre5/arch/arm/mm/proc-arm6,7.S
--- linux-2.2.8-pre4/arch/arm/mm/proc-arm6,7.S	1998-09-06 10:44:47.000000000 -0700
+++ linux-2.2.8-pre5/arch/arm/mm/proc-arm6,7.S	2003-08-15 15:06:10.000000000 -0700
@@ -52,13 +52,14 @@
 		blt	1b
 		mov	pc, lr
 
-@LC0:		.word	_current
 /*
  * Function: arm6_7_switch_to (struct task_struct *prev, struct task_struct *next)
  *
  * Params  : prev	Old task structure
  *	   : next	New task structure for process to run
  *
+ * Returns : prev
+ *
  * Purpose : Perform a task switch, saving the old processes state, and restoring
  *	     the new.
  *
@@ -72,15 +73,15 @@
 		stmfd	sp!, {ip}			@ Save cpsr_SVC
 		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
 		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
-		ldr	r0, [r1, #TSK_ADDR_LIMIT]
-		teq	r0, #0
-		moveq	r0, #DOM_KERNELDOMAIN
-		movne	r0, #DOM_USERDOMAIN
-		mcr	p15, 0, r0, c3, c0		@ Set domain reg
-		ldr	r0, [r1, #TSS_MEMMAP]		@ Page table pointer
+		ldr	r2, [r1, #TSK_ADDR_LIMIT]
+		teq	r2, #0
+		moveq	r2, #DOM_KERNELDOMAIN
+		movne	r2, #DOM_USERDOMAIN
+		mcr	p15, 0, r2, c3, c0		@ Set domain reg
+		ldr	r2, [r1, #TSS_MEMMAP]		@ Page table pointer
 		mov	r1, #0
 		mcr	p15, 0, r1, c7, c0, 0		@ flush cache
-		mcr	p15, 0, r0, c2, c0, 0		@ update page table ptr
+		mcr	p15, 0, r2, c2, c0, 0		@ update page table ptr
 		mcr	p15, 0, r1, c5, c0, 0		@ flush TLBs
 		ldmfd	sp!, {ip}
 		msr	spsr, ip			@ Save tasks CPSR into SPSR for this return
@@ -369,6 +370,35 @@
 		mov	pc, lr
 
 /*
+ * Function: arm6_7_set_pte(pte_t *ptep, pte_t pte)
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ * Purpose : Set a PTE and flush it out of any WB cache
+ */
+		.align	5
+_arm6_7_set_pte:
+		str	r1, [r0], #-1024		@ linux version
+
+		bic	r2, r1, #0xff0
+		bic	r2, r2, #3
+		orr	r2, r2, #HPTE_TYPE_SMALL
+
+		tst	r1, #LPTE_USER | LPTE_EXEC
+		orrne	r2, r2, #HPTE_AP_READ
+
+		tst	r1, #LPTE_WRITE
+		tstne	r1, #LPTE_DIRTY
+		orrne	r2, r2, #HPTE_AP_WRITE
+
+		tst	r1, #LPTE_PRESENT
+		tstne	r1, #LPTE_YOUNG
+		moveq	r2, #0
+
+		str	r2, [r0]			@ hardware version
+		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry	 (drain is done by TLB fns)
+		mov	pc, lr
+
+/*
  * Function: _arm6_7_reset
  *
  * Notes   : This sets up everything for a reset
@@ -405,8 +435,12 @@
 		.word	_arm6_7_flush_tlb_all		@ 44
 		.word	_arm6_7_flush_tlb_area		@ 48
 		.word	_arm6_set_pmd			@ 52
-		.word	_arm6_7_reset			@ 54
-		.word	_arm6_7_flush_cache		@ 58
+		.word	_arm6_7_set_pte			@ 56
+		.word	_arm6_7_reset			@ 60
+		.word	_arm6_7_flush_cache		@ 64
+
+		.word	_arm6_7_flush_cache		@ 68
+		.word	_arm6_7_flush_cache		@ 72
 
 /*
  * Purpose : Function pointers used to access above functions - all calls
@@ -431,8 +465,9 @@
 		.word	_arm6_7_flush_tlb_all		@ 44
 		.word	_arm6_7_flush_tlb_area		@ 48
 		.word	_arm7_set_pmd			@ 52
-		.word	_arm6_7_reset			@ 56
-		.word	_arm6_7_flush_cache		@ 60
-
+		.word	_arm6_7_set_pte			@ 56
+		.word	_arm6_7_reset			@ 60
 		.word	_arm6_7_flush_cache		@ 64
+
 		.word	_arm6_7_flush_cache		@ 68
+		.word	_arm6_7_flush_cache		@ 72
diff -urN linux-2.2.8-pre4/arch/arm/mm/proc-sa110.S linux-2.2.8-pre5/arch/arm/mm/proc-sa110.S
--- linux-2.2.8-pre4/arch/arm/mm/proc-sa110.S	1998-12-17 09:05:42.000000000 -0800
+++ linux-2.2.8-pre5/arch/arm/mm/proc-sa110.S	2003-08-15 15:06:10.000000000 -0700
@@ -8,6 +8,7 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/hardware.h>
 #include "../lib/constants.h"
 
 /* This is the maximum size of an area which will be flushed.  If the area
@@ -21,7 +22,6 @@
 
 /*
  * Function: sa110_flush_cache_all (void)
- *
  * Purpose : Flush all cache lines
  */
 		.align	5
@@ -33,7 +33,7 @@
 		ands	r1, r1, #1
 		eor	r1, r1, #1
 		str	r1, [r3]
-		ldr	ip, =0xdf000000
+		ldr	ip, =FLUSH_BASE
 		addne	ip, ip, #32768
 		add	r1, ip, #16384			@ only necessary for 16k
 1:		ldr	r3, [ip], #32
@@ -47,11 +47,9 @@
 
 /*
  * Function: sa110_flush_cache_area (unsigned long address, int end, int flags)
- *
  * Params  : address	Area start address
  *	   : end	Area end address
  *	   : flags	b0 = I cache as well
- *
  * Purpose : clean & flush all cache lines associated with this area of memory
  */
 		.align	5
@@ -74,10 +72,8 @@
 
 /*
  * Function: sa110_cache_wback_area(unsigned long address, unsigned long end)
- *
  * Params  : address	Area start address
  *	   : end	Area end address
- *
  * Purpose : ensure all dirty cachelines in the specified area have been
  *	     written out to memory (for DMA)
  */
@@ -99,13 +95,10 @@
 
 /*
  * Function: sa110_cache_purge_area(unsigned long address, unsigned long end)
- *
  * Params  : address	Area start address
  *	   : end	Area end address
- *
  * Purpose : throw away all D-cached data in specified region without
- *	     an obligation to write it ack.
- *
+ *	     an obligation to write it back.
  * Note    : Must clean the D-cached entries around the boundaries if the
  *	     start and/or end address are not cache aligned.
  */
@@ -124,9 +117,7 @@
 
 /*
  * Function: sa110_flush_cache_entry (unsigned long address)
- *
  * Params  : address	Address of cache line to flush
- *
  * Purpose : clean & flush an entry
  */
 		.align	5
@@ -138,24 +129,23 @@
 		mov	pc, lr
 
 /*
- * Function: sa110_flush_cache_pte (unsigned long address)
- *
+ * Function: sa110_clean_cache_area(unsigned long start, unsigned long size)
  * Params  : address	Address of cache line to clean
- *
  * Purpose : Ensure that physical memory reflects cache at this location
  *	     for page table purposes.
  */
-_sa110_flush_cache_pte:
-		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry	 (drain is done by TLB fns)
+_sa110_clean_cache_area:
+1:		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry	 (drain is done by TLB fns)
+		add	r0, r0, #32
+		subs	r1, r1, #32
+		bhi	1b
 		mov	pc, lr
 
 /*
  * Function: sa110_flush_ram_page (unsigned long page)
- *
  * Params  : address	Area start address
  *	   : size	size of area
  *	   : flags	b0 = I cache as well
- *
  * Purpose : clean & flush all cache lines associated with this area of memory
  */
 		.align	5
@@ -176,7 +166,6 @@
 
 /*
  * Function: sa110_flush_tlb_all (void)
- *
  * Purpose : flush all TLB entries in all caches
  */
 		.align	5
@@ -188,11 +177,9 @@
 
 /*
  * Function: sa110_flush_tlb_area (unsigned long address, unsigned long end, int flags)
- *
  * Params  : address	Area start address
  *	   : end	Area end address
  *	   : flags	b0 = I cache as well
- *
  * Purpose : flush a TLB entry
  */
 		.align	5
@@ -212,22 +199,21 @@
 
 		.align	5
 _sa110_flush_icache_area:
-		mov	r3, #0
 1:		mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
 		add	r0, r0, #32
-		cmp	r0, r1
-		blt	1b
+		subs	r1, r1, #32
+		bhi	1b
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 		mcr	p15, 0, r0, c7, c5, 0		@ flush I cache
 		mov	pc, lr
 /*
  * Function: sa110_switch_to (struct task_struct *prev, struct task_struct *next)
- *
  * Params  : prev	Old task structure
  *	   : next	New task structure for process to run
- *
+ * Returns : prev
  * Purpose : Perform a task switch, saving the old processes state, and restoring
  *	     the new.
- *
  * Notes   : We don't fiddle with the FP registers here - we postpone this until
  *	     the new task actually uses FP.  This way, we don't swap FP for tasks
  *	     that do not require it.
@@ -237,20 +223,30 @@
 		stmfd	sp!, {r4 - r9, fp, lr}		@ Store most regs on stack
 		mrs	ip, cpsr
 		stmfd	sp!, {ip}			@ Save cpsr_SVC
+		ldr	r2, [r0, #TSS_MEMMAP]		@ Get old page tables
 		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
 		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
-		ldr	r0, [r1, #TSK_ADDR_LIMIT]
-		teq	r0, #0
-		moveq	r0, #DOM_KERNELDOMAIN
-		movne	r0, #DOM_USERDOMAIN
-		mcr	p15, 0, r0, c3, c0		@ Set segment
-		ldr	r0, [r1, #TSS_MEMMAP]		@ Page table pointer
+		ldr	r4, [r1, #TSK_ADDR_LIMIT]
+		teq	r4, #0
+		moveq	r4, #DOM_KERNELDOMAIN
+		movne	r4, #DOM_USERDOMAIN
+		mcr	p15, 0, r4, c3, c0		@ Set segment
+		ldr	r4, [r1, #TSS_MEMMAP]		@ Page table pointer
+/*
+ * Flushing the cache is nightmarishly slow, so we take any excuse
+ * to get out of it.  If the old page table is the same as the new,
+ * this is a CLONE_VM relative of the old task and there is no need
+ * to flush.  The overhead of the tests isn't even on the radar
+ * compared to the cost of the flush itself.
+ */
+		teq	r4, r2
+		beq	2f
 		ldr	r3, =Lclean_switch
 		ldr	r2, [r3]
 		ands	r2, r2, #1
 		eor	r2, r2, #1
 		str	r2, [r3]
-		ldr	r2, =0xdf000000
+		ldr	r2, =FLUSH_BASE
 		addne	r2, r2, #32768
 		add	r1, r2, #16384			@ only necessary for 16k
 1:		ldr	r3, [r2], #32
@@ -259,19 +255,16 @@
 		mov	r1, #0
 		mcr	p15, 0, r1, c7, c5, 0		@ flush I cache
 		mcr	p15, 0, r1, c7, c10, 4		@ drain WB
-		mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+		mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 		mcr	p15, 0, r1, c8, c7, 0		@ flush TLBs
-		ldmfd	sp!, {ip}
+2:		ldmfd	sp!, {ip}
 		msr	spsr, ip			@ Save tasks CPSR into SPSR for this return
 		ldmfd	sp!, {r4 - r9, fp, pc}^		@ Load all regs saved previously
 
 /*
  * Function: sa110_data_abort ()
- *
  * Params  : r0 = address of aborted instruction
- *
  * Purpose : obtain information about current aborted instruction
- *
  * Returns : r0 = address of abort
  *	   : r1 = FSR
  *	   : r2 != 0 if writing
@@ -288,12 +281,10 @@
 		mov	pc, lr
 
 /*
- * Function: sa110_set_pmd ()
- *
+ * Function: sa110_set_pmd(pmd_t *pmdp, pmd_t pmd)
  * Params  : r0 = Address to set
  *	   : r1 = value to set
- *
- * Purpose : Set a PMD and flush it out of any WB cache
+ * Purpose : Set a PMD and flush it out
  */
 		.align	5
 _sa110_set_pmd:	str	r1, [r0]
@@ -301,23 +292,51 @@
 		mov	pc, lr
 
 /*
+ * Function: sa110_set_pte(pte_t *ptep, pte_t pte)
+ * Params  : r0 = Address to set
+ *	   : r1 = value to set
+ * Purpose : Set a PTE and flush it out
+ */
+		.align	5
+_sa110_set_pte:	str	r1, [r0], #-1024		@ linux version
+
+		eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+		bic	r2, r1, #0xff0
+		bic	r2, r2, #3
+		orr	r2, r2, #HPTE_TYPE_SMALL
+
+		tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+		orrne	r2, r2, #HPTE_AP_READ
+
+		tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+		orreq	r2, r2, #HPTE_AP_WRITE
+
+		tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
+		movne	r2, #0
+
+		str	r2, [r0]			@ hardware version
+		mov	r0, r0
+		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry	 (drain is done by TLB fns)
+		mov	pc, lr
+
+/*
  * Function: sa110_check_bugs (void)
  *	   : sa110_proc_init (void)
  *	   : sa110_proc_fin (void)
- *
  * Notes   : This processor does not require these
  */
 _sa110_check_bugs:
 		mrs	ip, cpsr
 		bic	ip, ip, #F_BIT
 		msr	cpsr, ip
+
 _sa110_proc_init:
 _sa110_proc_fin:
 		mov	pc, lr
 
 /*
  * Function: sa110_reset
- *
  * Notes   : This sets up everything for a reset
  */
 _sa110_reset:	mrs	r1, cpsr
@@ -350,14 +369,15 @@
 		.word	_sa110_flush_cache_all		@ 24
 		.word	_sa110_flush_cache_area		@ 28
 		.word	_sa110_flush_cache_entry	@ 32
-		.word	_sa110_flush_cache_pte		@ 36
+		.word	_sa110_clean_cache_area		@ 36
 		.word	_sa110_flush_ram_page		@ 40
 		.word	_sa110_flush_tlb_all		@ 44
 		.word	_sa110_flush_tlb_area		@ 48
 
 		.word	_sa110_set_pmd			@ 52
-		.word	_sa110_reset			@ 56
-		.word	_sa110_flush_icache_area	@ 60
+		.word	_sa110_set_pte			@ 56
+		.word	_sa110_reset			@ 60
+		.word	_sa110_flush_icache_area	@ 64
 
-		.word	_sa110_cache_wback_area		@ 64
-		.word	_sa110_cache_purge_area		@ 68
+		.word	_sa110_cache_wback_area		@ 68
+		.word	_sa110_cache_purge_area		@ 72
diff -urN linux-2.2.8-pre4/arch/arm/mm/small_page.c linux-2.2.8-pre5/arch/arm/mm/small_page.c
--- linux-2.2.8-pre4/arch/arm/mm/small_page.c	1998-09-09 08:56:58.000000000 -0700
+++ linux-2.2.8-pre5/arch/arm/mm/small_page.c	2003-08-15 15:06:10.000000000 -0700
@@ -5,6 +5,8 @@
  *
  * Changelog:
  *  26/01/1996	RMK	Cleaned up various areas to make little more generic
+ *  07/02/1999	RMK	Support added for 16K and 32K page sizes
+ *			containing 8K blocks
  */
 
 #include <linux/signal.h>
@@ -19,21 +21,32 @@
 #include <linux/swap.h>
 #include <linux/smp.h>
 
-#define SMALL_ALLOC_SHIFT	(10)
+#if PAGE_SIZE == 4096
+/* 2K blocks */
+#define SMALL_ALLOC_SHIFT	(11)
+#define NAME(x)			x##_2k
+#elif PAGE_SIZE == 32768 || PAGE_SIZE == 16384
+/* 8K blocks */
+#define SMALL_ALLOC_SHIFT	(13)
+#define NAME(x)			x##_8k
+#endif
+
 #define SMALL_ALLOC_SIZE	(1 << SMALL_ALLOC_SHIFT)
 #define NR_BLOCKS		(PAGE_SIZE / SMALL_ALLOC_SIZE)
+#define BLOCK_MASK		((1 << NR_BLOCKS) - 1)
 
-#if NR_BLOCKS != 4
-#error I only support 4 blocks per page!
-#endif
-
-#define USED(pg)		((atomic_read(&(pg)->count) >> 8) & 15)
+#define USED(pg)		((atomic_read(&(pg)->count) >> 8) & BLOCK_MASK)
 #define SET_USED(pg,off)	(atomic_read(&(pg)->count) |= 256 << off)
 #define CLEAR_USED(pg,off)	(atomic_read(&(pg)->count) &= ~(256 << off))
+#define ALL_USED		BLOCK_MASK
 #define IS_FREE(pg,off)		(!(atomic_read(&(pg)->count) & (256 << off)))
-#define PAGE_PTR(page,block)	((struct free_small_page *)((page) + \
+#define SM_PAGE_PTR(page,block)	((struct free_small_page *)((page) + \
 					((block) << SMALL_ALLOC_SHIFT)))
 
+#if NR_BLOCKS != 2 && NR_BLOCKS != 4
+#error I only support 2 or 4 blocks per page
+#endif
+
 struct free_small_page {
 	unsigned long next;
 	unsigned long prev;
@@ -52,6 +65,7 @@
 	1,	/* 0001 */
 	0,	/* 0010 */
 	2,	/* 0011 */
+#if NR_BLOCKS == 4
 	0,	/* 0100 */
 	1,	/* 0101 */
 	0,	/* 0110 */
@@ -64,6 +78,7 @@
 	1,	/* 1101 */
 	0,	/* 1110 */
 	4	/* 1111 */
+#endif
 };
 
 static inline void clear_page_links(unsigned long page)
@@ -72,7 +87,7 @@
 	int i;
 
 	for (i = 0; i < NR_BLOCKS; i++) {
-		fsp = PAGE_PTR(page, i);
+		fsp = SM_PAGE_PTR(page, i);
 		fsp->next = fsp->prev = 0;
 	}
 }
@@ -90,7 +105,7 @@
 	for (i = 0; i < NR_BLOCKS; i++) {
 		if (mask & (1 << i))
 			continue;
-		fsp = PAGE_PTR(page, i);
+		fsp = SM_PAGE_PTR(page, i);
 		fsp->prev = prev;
 	}
 }
@@ -108,12 +123,12 @@
 	for (i = 0; i < NR_BLOCKS; i++) {
 		if (mask & (1 << i))
 			continue;
-		fsp = PAGE_PTR(page, i);
+		fsp = SM_PAGE_PTR(page, i);
 		fsp->next = next;
 	}
 }
 
-unsigned long get_small_page(int priority)
+unsigned long NAME(get_page)(int priority)
 {
 	struct free_small_page *fsp;
 	unsigned long new_page;
@@ -129,8 +144,8 @@
 	page = mem_map + MAP_NR(small_page_ptr);
 	offset = offsets[USED(page)];
 	SET_USED(page, offset);
-	new_page = (unsigned long)PAGE_PTR(small_page_ptr, offset);
-	if (USED(page) == 15) {
+	new_page = (unsigned long)SM_PAGE_PTR(small_page_ptr, offset);
+	if (USED(page) == ALL_USED) {
 		fsp = (struct free_small_page *)new_page;
 		set_page_links_prev (fsp->next, 0);
 		small_page_ptr = fsp->next;
@@ -156,30 +171,31 @@
 	goto again;
 }
 
-void free_small_page(unsigned long spage)
+void NAME(free_page)(unsigned long spage)
 {
 	struct free_small_page *ofsp, *cfsp;
 	unsigned long flags;
 	struct page *page;
 	int offset, oldoffset;
 
+	if (!spage)
+		goto none;
+
 	offset = (spage >> SMALL_ALLOC_SHIFT) & (NR_BLOCKS - 1);
 	spage -= offset << SMALL_ALLOC_SHIFT;
 
 	page = mem_map + MAP_NR(spage);
-	if (!PageReserved(page) || !USED(page)) {
-		printk ("Trying to free non-small page from %p\n", __builtin_return_address(0));
-		return;
-	}
-	if (IS_FREE(page, offset)) {
-		printk ("Trying to free free small page from %p\n", __builtin_return_address(0));
-		return;
-	}
+	if (!PageReserved(page) || !USED(page))
+		goto non_small;
+
+	if (IS_FREE(page, offset))
+		goto free;
+
 	save_flags_cli (flags);
 	oldoffset = offsets[USED(page)];
 	CLEAR_USED(page, offset);
-	ofsp = PAGE_PTR(spage, oldoffset);
-	cfsp = PAGE_PTR(spage, offset);
+	ofsp = SM_PAGE_PTR(spage, oldoffset);
+	cfsp = SM_PAGE_PTR(spage, offset);
 
 	if (oldoffset == NR_BLOCKS) { /* going from totally used to mostly used */
 		cfsp->prev = 0;
@@ -197,4 +213,13 @@
 	} else
 		*cfsp = *ofsp;
 	restore_flags(flags);
+	return;
+
+non_small:
+	printk ("Trying to free non-small page from %p\n", __builtin_return_address(0));
+	return;
+free:
+	printk ("Trying to free free small page from %p\n", __builtin_return_address(0));
+none:
+	return;
 }
diff -urN linux-2.2.8-pre4/arch/mips/kernel/irixioctl.c linux-2.2.8-pre5/arch/mips/kernel/irixioctl.c
--- linux-2.2.8-pre4/arch/mips/kernel/irixioctl.c	1998-10-20 13:52:54.000000000 -0700
+++ linux-2.2.8-pre5/arch/mips/kernel/irixioctl.c	2003-08-15 15:06:10.000000000 -0700
@@ -33,13 +33,15 @@
 {
 	struct file *filp;
 
-	if(fd >= NR_OPEN || !(filp = current->files->fd[fd]))
+	file = fcheck(fd);
+	if(!file)
 		return ((struct tty_struct *) 0);
 	if(filp->private_data) {
 		struct tty_struct *ttyp = (struct tty_struct *) filp->private_data;
 
-		if(ttyp->magic == TTY_MAGIC)
+		if(ttyp->magic == TTY_MAGIC) {
 			return ttyp;
+		}
 	}
 	return ((struct tty_struct *) 0);
 }
diff -urN linux-2.2.8-pre4/arch/mips/kernel/sysirix.c linux-2.2.8-pre5/arch/mips/kernel/sysirix.c
--- linux-2.2.8-pre4/arch/mips/kernel/sysirix.c	1999-03-11 23:25:14.000000000 -0800
+++ linux-2.2.8-pre5/arch/mips/kernel/sysirix.c	2003-08-15 15:06:10.000000000 -0700
@@ -23,6 +23,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/utsname.h>
+#include <linux/file.h>
 
 #include <asm/ptrace.h>
 #include <asm/page.h>
@@ -734,6 +735,7 @@
 	int error, i;
 
 	/* We don't support this feature yet. */
+	lock_kernel();
 	if(fs_type) {
 		error = -EINVAL;
 		goto out;
@@ -776,7 +778,6 @@
 
 asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
 {
-	struct dentry *dentry;
 	struct inode *inode;
 	struct statfs kbuf;
 	mm_segment_t old_fs;
@@ -787,25 +788,22 @@
 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
 	if (error)
 		goto out;
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+	if (!(file = fget(fd))) {
 		error = -EBADF;
 		goto out;
 	}
-	if (!(dentry = file->f_dentry)) {
+
+	if (!(inode = file->f_dentry->d_inode)) {
 		error = -ENOENT;
-		goto out;
-	}
-	if (!(inode = dentry->d_inode)) {
-		error = -ENOENT;
-		goto out;
+		goto out_f;
 	}
 	if (!inode->i_sb) {
 		error = -ENODEV;
-		goto out;
+		goto out_f;
 	}
 	if (!inode->i_sb->s_op->statfs) {
 		error = -ENOSYS;
-		goto out;
+		goto out_f;
 	}
 
 	old_fs = get_fs(); set_fs(get_ds());
@@ -813,7 +811,7 @@
 	                                  sizeof(struct statfs));
 	set_fs(old_fs);
 	if (error)
-		goto out;
+		goto out_f;
 
 	__put_user(kbuf.f_type, &buf->f_type);
 	__put_user(kbuf.f_bsize, &buf->f_bsize);
@@ -826,9 +824,9 @@
 		__put_user(0, &buf->f_fname[i]);
 		__put_user(0, &buf->f_fpack[i]);
 	}
-	error = 0;
 
-	dput(dentry);
+out_f:
+	fput(file);
 out:
 	unlock_kernel();
 	return error;
@@ -1110,7 +1108,7 @@
 
 	lock_kernel();
 	if(!(flags & MAP_ANONYMOUS)) {
-		if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+		if(!(file = fget(fd))) {
 			retval = -EBADF;
 			goto out;
 		}
@@ -1130,6 +1128,8 @@
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
 	retval = do_mmap(file, addr, len, prot, flags, offset);
+	if (file)
+		fput(file);
 
 out:
 	unlock_kernel();
@@ -1568,7 +1568,6 @@
 
 asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
 {
-	struct dentry *dentry;
 	struct inode *inode;
 	mm_segment_t old_fs;
 	struct statfs kbuf;
@@ -1582,21 +1581,21 @@
 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
 	if (error)
 		goto out;
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+	if (!(file = fget(fd))) {
 		error = -EBADF;
 		goto out;
 	}
-	if (!(dentry = file->f_dentry)) {
+	if (!(inode = file->f_dentry->d_inode)) {
 		error = -ENOENT;
-		goto out;
+		goto out_f;
 	}
-	if (!(inode = dentry->d_inode)) {
-		error = -ENOENT;
-		goto out;
+	if (!inode->i_sb) {
+		error = -ENODEV;
+		goto out_f;
 	}
 	if (!inode->i_sb->s_op->statfs) {
 		error = -ENOSYS;
-		goto out;
+		goto out_f;
 	}
 
 	old_fs = get_fs(); set_fs(get_ds());
@@ -1604,7 +1603,7 @@
 	                                  sizeof(struct statfs));
 	set_fs(old_fs);
 	if (error)
-		goto out;
+		goto out_f;
 
 	__put_user(kbuf.f_bsize, &buf->f_bsize);
 	__put_user(kbuf.f_frsize, &buf->f_frsize);
@@ -1626,9 +1625,8 @@
 	for(i = 0; i < 32; i++)
 		__put_user(0, &buf->f_fstr[i]);
 
-	error = 0;
-
-	dput(dentry);
+out_f:
+	fput(file);
 out:
 	unlock_kernel();
 	return error;
@@ -1726,7 +1724,7 @@
 	}
 
 	if(!(flags & MAP_ANONYMOUS)) {
-		if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+		if(!(file = fcheck(fd))) {
 			error = -EBADF;
 			goto out;
 		}
@@ -1812,6 +1810,7 @@
 	struct statfs kbuf;
 	int error, i;
 
+	lock_kernel();
 	printk("[%s:%ld] Wheee.. irix_statvfs(%s,%p)\n",
 	       current->comm, current->pid, fname, buf);
 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
@@ -1864,7 +1863,6 @@
 
 asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
 {
-	struct dentry *dentry;
 	struct inode *inode;
 	mm_segment_t old_fs;
 	struct statfs kbuf;
@@ -1878,21 +1876,21 @@
 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
 	if (error)
 		goto out;
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+	if (!(file = fget(fd))) {
 		error = -EBADF;
 		goto out;
 	}
-	if (!(dentry = file->f_dentry)) {
+	if (!(inode = file->f_dentry->d_inode)) {
 		error = -ENOENT;
-		goto out;
+		goto out_f;
 	}
-	if (!(inode = dentry->d_inode)) {
-		error = -ENOENT;
-		goto out;
+	if (!inode->i_sb) {
+		error = -ENODEV;
+		goto out_f;
 	}
 	if (!inode->i_sb->s_op->statfs) {
 		error = -ENOSYS;
-		goto out;
+		goto out_f;
 	}
 
 	old_fs = get_fs(); set_fs(get_ds());
@@ -1900,7 +1898,7 @@
 	                                  sizeof(struct statfs));
 	set_fs(old_fs);
 	if (error)
-		goto out;
+		goto out_f;
 
 	__put_user(kbuf.f_bsize, &buf->f_bsize);
 	__put_user(kbuf.f_frsize, &buf->f_frsize);
@@ -1921,10 +1919,8 @@
 	__put_user(kbuf.f_namelen, &buf->f_namemax);
 	for(i = 0; i < 32; i++)
 		__put_user(0, &buf->f_fstr[i]);
-
-	error = 0;
-
-	dput(dentry);
+out_f:
+	fput(file);
 out:
 	unlock_kernel();
 	return error;
@@ -1994,7 +1990,6 @@
 	unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
 	int retval;
 
-	lock_kernel();
 #ifdef DEBUG_GETDENTS
 	printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
 	       reclen, namlen, buf->count);
@@ -2020,14 +2015,12 @@
 	retval = 0;
 
 out:
-	unlock_kernel();
 	return retval;
 }
 
 asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob)
 {
 	struct file *file;
-	struct dentry *dentry;
 	struct inode *inode;
 	struct irix_dirent32 *lastdirent;
 	struct irix_dirent32_callback buf;
@@ -2039,46 +2032,56 @@
 	       current->pid, fd, dirent, count, eob);
 #endif
 	error = -EBADF;
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+	file = fget(fd);
+	if (!file)
 		goto out;
 
-	dentry = file->f_dentry;
-	if (!dentry)
-		goto out;
+	inode = file->f_dentry->d_inode;
+	if (!inode)
+		goto out_putf;
 
 	inode = dentry->d_inode;
 	if (!inode)
-		goto out;
+		goto out_putf;
 
-	error = -ENOTDIR;
-	if (!file->f_op || !file->f_op->readdir)
-		goto out;
-
-	error = -EFAULT;
-	if(!access_ok(VERIFY_WRITE, dirent, count) ||
-	   !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
-		goto out;
-
-	__put_user(0, eob);
 	buf.current_dir = (struct irix_dirent32 *) dirent;
 	buf.previous = NULL;
 	buf.count = count;
 	buf.error = 0;
 
+	error = -ENOTDIR;
+	if (!file->f_op || !file->f_op->readdir)
+		goto out_putf;
+
+	/*
+	 * Get the inode's semaphore to prevent changes
+	 * to the directory while we read it.
+	 */
+	down(&inode->i_sem);
 	error = file->f_op->readdir(file, &buf, irix_filldir32);
+	up(&inode->i_sem);
 	if (error < 0)
-		goto out;
+		goto out_putf;
+	error = buf.error;
 	lastdirent = buf.previous;
-	if (!lastdirent) {
-		error = buf.error;
-		goto out;
+	if (lastdirent) {
+		put_user(file->f_pos, &lastdirent->d_off);
+		error = count - buf.count;
 	}
-	lastdirent->d_off = (u32) file->f_pos;
+
+	if (put_user(0, eob) < 0) {
+		error = EFAULT;
+		goto out_putf;
+	}
+
+
 #ifdef DEBUG_GETDENTS
 	printk("eob=%d returning %d\n", *eob, count - buf.count);
 #endif
 	error = count - buf.count;
 
+out_putf:
+	fput(file);
 out:
 	unlock_kernel();
 	return error;
@@ -2110,7 +2113,6 @@
 	unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
 	int retval;
 
-	lock_kernel();
 	buf->error = -EINVAL;	/* only used if we fail.. */
 	if (reclen > buf->count) {
 		retval = -EINVAL;
@@ -2131,14 +2133,12 @@
 
 	retval = 0;
 out:
-	unlock_kernel();
 	return retval;
 }
 
 asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
 {
 	struct file *file;
-	struct dentry *dentry;
 	struct inode *inode;
 	struct irix_dirent64 *lastdirent;
 	struct irix_dirent64_callback buf;
@@ -2150,40 +2150,38 @@
 	       current->pid, fd, dirent, cnt);
 #endif
 	error = -EBADF;
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-		goto out;
-
-	dentry = file->f_dentry;
-	if (!dentry)
+	if (!(file = fget(fd)))
 		goto out;
 
-	inode = dentry->d_inode;
+	inode = file->f_dentry->d_inode;
 	if (!inode)
-		goto out;
+		goto out_f;
 
 	error = -ENOTDIR;
 	if (!file->f_op || !file->f_op->readdir)
-		goto out;
+		goto out_f;
 
 	error = -EFAULT;
 	if(!access_ok(VERIFY_WRITE, dirent, cnt))
-		goto out;
+		goto out_f;
 
 	error = -EINVAL;
 	if(cnt < (sizeof(struct irix_dirent64) + 255))
-		goto out;
+		goto out_f;
 
 	buf.curr = (struct irix_dirent64 *) dirent;
 	buf.previous = NULL;
 	buf.count = cnt;
 	buf.error = 0;
+	down(&inode->i_sem);
 	error = file->f_op->readdir(file, &buf, irix_filldir64);
+	up(&inode->i_sem);
 	if (error < 0)
-		goto out;
+		goto out_f;
 	lastdirent = buf.previous;
 	if (!lastdirent) {
 		error = buf.error;
-		goto out;
+		goto out_f;
 	}
 	lastdirent->d_off = (u64) file->f_pos;
 #ifdef DEBUG_GETDENTS
@@ -2191,6 +2189,8 @@
 #endif
 	error = cnt - buf.count;
 
+out_f:
+	fput(file);
 out:
 	unlock_kernel();
 	return error;
@@ -2199,7 +2199,6 @@
 asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
 {
 	struct file *file;
-	struct dentry *dentry;
 	struct inode *inode;
 	struct irix_dirent64 *lastdirent;
 	struct irix_dirent64_callback buf;
@@ -2211,42 +2210,40 @@
 	       current->pid, fd, dirent, cnt);
 #endif
 	error = -EBADF;
-	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-		goto out;
-
-	dentry = file->f_dentry;
-	if (!dentry)
+	if (!(file = fget(fd)))
 		goto out;
 
-	inode = dentry->d_inode;
+	inode = file->f_dentry->d_inode;
 	if (!inode)
-		goto out;
+		goto out_f;
 
 	error = -ENOTDIR;
 	if (!file->f_op || !file->f_op->readdir)
-		goto out;
+		goto out_f;
 
 	error = -EFAULT;
 	if(!access_ok(VERIFY_WRITE, dirent, cnt) ||
 	   !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
-		goto out;
+		goto out_f;
 
 	error = -EINVAL;
 	if(cnt < (sizeof(struct irix_dirent64) + 255))
-		goto out;
+		goto out_f;
 
 	*eob = 0;
 	buf.curr = (struct irix_dirent64 *) dirent;
 	buf.previous = NULL;
 	buf.count = cnt;
 	buf.error = 0;
+	down(&inode->i_sem);
 	error = file->f_op->readdir(file, &buf, irix_filldir64);
+	up(&inode->i_sem);
 	if (error < 0)
-		goto out;
+		goto out_f;
 	lastdirent = buf.previous;
 	if (!lastdirent) {
 		error = buf.error;
-		goto out;
+		goto out_f;
 	}
 	lastdirent->d_off = (u64) file->f_pos;
 #ifdef DEBUG_GETDENTS
@@ -2254,6 +2251,8 @@
 #endif
 	error = cnt - buf.count;
 
+out_f:
+	fput(file);
 out:
 	unlock_kernel();
 	return error;
diff -urN linux-2.2.8-pre4/arch/ppc/kernel/syscalls.c linux-2.2.8-pre5/arch/ppc/kernel/syscalls.c
--- linux-2.2.8-pre4/arch/ppc/kernel/syscalls.c	1998-09-30 10:14:17.000000000 -0700
+++ linux-2.2.8-pre5/arch/ppc/kernel/syscalls.c	2003-08-15 15:06:10.000000000 -0700
@@ -205,12 +205,15 @@
 
 	lock_kernel();
 	if (!(flags & MAP_ANONYMOUS)) {
-		if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+		file = fget(fd);
+		if (!file)
 			goto out;
 	}
 	
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 	ret = do_mmap(file, addr, len, prot, flags, offset);
+	if (file)
+		fput(file);
 out:
 	unlock_kernel();
 	return ret;
diff -urN linux-2.2.8-pre4/drivers/net/de4x5.c linux-2.2.8-pre5/drivers/net/de4x5.c
--- linux-2.2.8-pre4/drivers/net/de4x5.c	1998-12-30 15:09:18.000000000 -0800
+++ linux-2.2.8-pre5/drivers/net/de4x5.c	2003-08-15 15:06:10.000000000 -0700
@@ -225,11 +225,18 @@
     to  determine this in  advance other than by  trial and error and common
     sense, e.g. call a BNC connectored port 'BNC', not '10Mb'.
 
-    TO DO:
-    ------
+    Changed the bus probing.  EISA used to be  done first,  followed by PCI.
+    Most people probably don't even know  what a de425 is today and the EISA
+    probe has messed  up some SCSI cards  in the past,  so now PCI is always
+    probed  first  followed by  EISA if  a) the architecture allows EISA and
+    either  b) there have been no PCI cards detected or  c) an EISA probe is
+    forced by  the user.  To force  a probe  include  "force_eisa"  in  your
+    insmod "args" line;  for built-in kernels either change the driver to do
+    this  automatically  or include  #define DE4X5_FORCE_EISA  on or  before
+    line 1040 in the driver.
 
-    o check what revision numbers the 21142 and 21143 have
-    o
+    TO DO: 
+    ------
 
     Revision History
     ----------------
@@ -416,11 +423,14 @@
 			   access traps. This flag is merely for log messages:
 			   should do something more definitive though...
       0.543  30-Dec-98    Add SMP spin locking.
-
+      0.544   8-May-99    Fix for buggy SROM in Motorola embedded boards using
+                           a 21143 by <mmporter@home.com>.
+			  Change PCI/EISA bus probing order.
+ 
     =========================================================================
 */
 
-static const char *version = "de4x5.c:V0.543 1998/12/30 davies@maniac.ultranet.com\n";
+static const char *version = "de4x5.c:V0.544 1999/5/8 davies@maniac.ultranet.com\n";
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -1027,8 +1037,11 @@
 #if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
 static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
 static int lastEISA = 0;
-#else
-static int lastEISA = MAX_EISA_SLOTS;           /* Only PCI probes */
+#  ifdef DE4X5_FORCE_EISA                 /* Force an EISA bus probe or not */
+static int forceEISA = 1;
+#  else
+static int forceEISA = 0;
+#  endif
 #endif
 static int num_de4x5s = 0;
 static int cfrv = 0, useSROM = 0;
@@ -1098,12 +1111,12 @@
 {
     u_long iobase = dev->base_addr;
 
+    pci_probe(dev, iobase);
 #if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
-    eisa_probe(dev, iobase);
-#endif
-    if (lastEISA == MAX_EISA_SLOTS) {
-	pci_probe(dev, iobase);
+    if ((lastPCI == NO_MORE_PCI) && ((num_de4x5s == 0) || forceEISA)) {
+        eisa_probe(dev, iobase);
     }
+#endif
     
     return (dev->priv ? 0 : -ENODEV);
 }
@@ -1230,6 +1243,7 @@
 	if ((tmp = (void *)kmalloc(RX_BUFF_SZ * NUM_RX_DESC + ALIGN, 
 				   GFP_KERNEL)) == NULL) {
 	    kfree(lp->cache.priv);
+	    lp->cache.priv = NULL;
 	    return -ENOMEM;
 	}
 
@@ -2066,38 +2080,36 @@
     }
     
     for (status = -ENODEV; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
-	if (EISA_signature(name, EISA_ID)) {
-	    cfid = (u32) inl(PCI_CFID);
-	    cfrv = (u_short) inl(PCI_CFRV);
-	    device = (cfid >> 8) & 0x00ffff00;
-	    vendor = (u_short) cfid;
+	if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE)) continue;
+	if (!EISA_signature(name, EISA_ID)) continue;
+
+	cfid = (u32) inl(PCI_CFID);
+	cfrv = (u_short) inl(PCI_CFRV);
+	device = (cfid >> 8) & 0x00ffff00;
+	vendor = (u_short) cfid;
 	    
-	    /* Read the EISA Configuration Registers */
-	    irq = inb(EISA_REG0);
-	    irq = de4x5_irq[(irq >> 1) & 0x03];
-
-	    if (is_DC2114x) {
-		device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
-	    }
-	    lp->chipset = device;
-
-	    /* Write the PCI Configuration Registers */
-	    outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS);
-	    outl(0x00006000, PCI_CFLT);
-	    outl(iobase, PCI_CBIO);
+	/* Read the EISA Configuration Registers */
+	irq = inb(EISA_REG0);
+	irq = de4x5_irq[(irq >> 1) & 0x03];
+
+	if (is_DC2114x) {
+	    device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+	}
+	lp->chipset = device;
+
+	/* Write the PCI Configuration Registers */
+	outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS);
+	outl(0x00006000, PCI_CFLT);
+	outl(iobase, PCI_CBIO);
 	    
-	    DevicePresent(EISA_APROM);
-	    if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE) == 0) {
-		dev->irq = irq;
-		if ((status = de4x5_hw_init(dev, iobase)) == 0) {
-		    num_de4x5s++;
-		    if (loading_module) link_modules(lastModule, dev);
-		    lastEISA = i;
-		    return;
-		}
-	    } else if (ioaddr != 0) {
-		printk("%s: region already allocated at 0x%04lx.\n", dev->name,iobase);
-	    }
+	DevicePresent(EISA_APROM);
+
+	dev->irq = irq;
+	if ((status = de4x5_hw_init(dev, iobase)) == 0) {
+	    num_de4x5s++;
+	    if (loading_module) link_modules(lastModule, dev);
+	    lastEISA = i;
+	    return;
 	}
     }
 
@@ -4794,6 +4806,7 @@
     if (lp->state == INITIALISED) {
         lp->ibn = 3;
         lp->active = *p++;
+	if (MOTO_SROM_BUG) lp->active = 0;
 	lp->phy[lp->active].gep = (*p ? p : 0); p += (2 * (*p) + 1);
 	lp->phy[lp->active].rst = (*p ? p : 0); p += (2 * (*p) + 1);
 	lp->phy[lp->active].mc  = TWIDDLE(p); p += 2;
@@ -5326,6 +5339,9 @@
 	t = *q;
 	*q = '\0';
 
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
+	if (strstr(p, "force_eisa") || strstr(p, "FORCE_EISA")) forceEISA = 1;
+#endif
 	if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = 1;
 
 	if (strstr(p, "autosense") || strstr(p, "AUTOSENSE")) {
@@ -5766,6 +5782,12 @@
 		release_region(p->base_addr, (lp->bus == PCI ? 
 					      DE4X5_PCI_TOTAL_SIZE :
 					      DE4X5_EISA_TOTAL_SIZE));
+		if (lp->cache.buf) {        /* MAC buffers allocated?    */
+		    kfree(lp->cache.buf);   /* Free the MAC buffers      */
+		}
+		if (lp->cache.priv) {       /* Private area allocated?   */
+		    kfree(lp->cache.priv);  /* Free the private area     */
+		}
 	    }
 	    kfree(p);
 	} else {
@@ -5799,10 +5821,10 @@
 	if (lp->cache.buf) {                /* MAC buffers allocated?    */
 	    kfree(lp->cache.buf);           /* Free the MAC buffers      */
 	}
-	kfree(lp->cache.priv);              /* Free the private area     */
 	release_region(p->base_addr, (lp->bus == PCI ? 
 				      DE4X5_PCI_TOTAL_SIZE :
 				      DE4X5_EISA_TOTAL_SIZE));
+	kfree(lp->cache.priv);              /* Free the private area     */
     }
     unregister_netdev(p);
     kfree(p);                               /* Free the device structure */
@@ -5867,6 +5889,9 @@
  * Local variables:
  *  compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c de4x5.c"
  *
- *  compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c de4x5.c"
+ * Delete -D__SMP__ below if you didn't define this in your kernel
+ * Delete -DMODVERSIONS below if you didn't define this in your kernel
+ *
+ *  compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -DMODVERSIONS -include /linux/include/linux/modversions.h -c de4x5.c"
  * End:
  */
diff -urN linux-2.2.8-pre4/drivers/net/de4x5.h linux-2.2.8-pre5/drivers/net/de4x5.h
--- linux-2.2.8-pre4/drivers/net/de4x5.h	1998-12-30 15:09:18.000000000 -0800
+++ linux-2.2.8-pre5/drivers/net/de4x5.h	2003-08-15 15:06:10.000000000 -0700
@@ -1027,3 +1027,5 @@
 #define DE4X5_GET_REG           0x0e /* Get the DE4X5 Registers */
 
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+
+#define MOTO_SROM_BUG    ((lp->active == 8) && ((*((s32 *)le32_to_cpu(get_unaligned(dev->dev_addr)))&0x00ffffff)==0x3e0008))
diff -urN linux-2.2.8-pre4/fs/autofs/root.c linux-2.2.8-pre5/fs/autofs/root.c
--- linux-2.2.8-pre4/fs/autofs/root.c	1999-04-23 21:20:37.000000000 -0700
+++ linux-2.2.8-pre5/fs/autofs/root.c	2003-08-15 15:06:10.000000000 -0700
@@ -168,7 +168,7 @@
  * yet completely filled in, and revalidate has to delay such
  * lookups..
  */
-static int autofs_revalidate(struct dentry * dentry)
+static int autofs_revalidate(struct dentry * dentry, int flags)
 {
 	struct inode * dir = dentry->d_parent->d_inode;
 	struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
@@ -241,7 +241,7 @@
 	d_add(dentry, NULL);
 
 	up(&dir->i_sem);
-	autofs_revalidate(dentry);
+	autofs_revalidate(dentry, 0);
 	down(&dir->i_sem);
 
 	/*
diff -urN linux-2.2.8-pre4/fs/coda/dir.c linux-2.2.8-pre5/fs/coda/dir.c
--- linux-2.2.8-pre4/fs/coda/dir.c	1999-04-23 21:20:37.000000000 -0700
+++ linux-2.2.8-pre5/fs/coda/dir.c	2003-08-15 15:06:10.000000000 -0700
@@ -44,7 +44,7 @@
 static int coda_readdir(struct file *file, void *dirent, filldir_t filldir);
 
 /* dentry ops */
-static int coda_dentry_revalidate(struct dentry *de);
+static int coda_dentry_revalidate(struct dentry *de, int);
 static void coda_dentry_delete(struct dentry *);
 
 /* support routines */
@@ -778,7 +778,7 @@
 }
 
 /* called when a cache lookup succeeds */
-static int coda_dentry_revalidate(struct dentry *de)
+static int coda_dentry_revalidate(struct dentry *de, int flags)
 {
 	int valid = 1;
 	struct inode *inode = de->d_inode;
diff -urN linux-2.2.8-pre4/fs/devpts/root.c linux-2.2.8-pre5/fs/devpts/root.c
--- linux-2.2.8-pre4/fs/devpts/root.c	1999-04-23 21:20:37.000000000 -0700
+++ linux-2.2.8-pre5/fs/devpts/root.c	2003-08-15 15:06:10.000000000 -0700
@@ -18,7 +18,7 @@
 
 static int devpts_root_readdir(struct file *,void *,filldir_t);
 static struct dentry *devpts_root_lookup(struct inode *,struct dentry *);
-static int devpts_revalidate(struct dentry *);
+static int devpts_revalidate(struct dentry *, int);
 
 static struct file_operations devpts_root_operations = {
 	NULL,                   /* llseek */
@@ -116,7 +116,7 @@
  * the pty really does still exist.  Never revalidate negative dentries;
  * for simplicity (fix later?)
  */
-static int devpts_revalidate(struct dentry * dentry)
+static int devpts_revalidate(struct dentry * dentry, int flags)
 {
 	struct devpts_sb_info *sbi;
 
diff -urN linux-2.2.8-pre4/fs/dquot.c linux-2.2.8-pre5/fs/dquot.c
--- linux-2.2.8-pre4/fs/dquot.c	2003-08-15 15:06:09.000000000 -0700
+++ linux-2.2.8-pre5/fs/dquot.c	2003-08-15 15:06:10.000000000 -0700
@@ -1349,8 +1349,8 @@
 		case Q_GETSTATS:
 			break;
 		case Q_GETQUOTA:
-			if (((type == USRQUOTA && current->uid != id) ||
-			     (type == GRPQUOTA && current->gid != id)) &&
+			if (((type == USRQUOTA && current->euid != id) ||
+			     (type == GRPQUOTA && current->egid != id)) &&
 			    !capable(CAP_SYS_RESOURCE))
 				goto out;
 			break;
diff -urN linux-2.2.8-pre4/fs/hfs/sysdep.c linux-2.2.8-pre5/fs/hfs/sysdep.c
--- linux-2.2.8-pre4/fs/hfs/sysdep.c	1998-12-23 14:10:36.000000000 -0800
+++ linux-2.2.8-pre5/fs/hfs/sysdep.c	2003-08-15 15:06:10.000000000 -0700
@@ -18,7 +18,7 @@
 #include <linux/hfs_fs_i.h>
 #include <linux/hfs_fs.h>
 
-static int hfs_revalidate_dentry(struct dentry *);
+static int hfs_revalidate_dentry(struct dentry *, int);
 static int hfs_hash_dentry(struct dentry *, struct qstr *);
 static int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
 static void hfs_dentry_iput(struct dentry *, struct inode *);
@@ -89,7 +89,7 @@
 	iput(inode);
 }
 
-static int hfs_revalidate_dentry(struct dentry *dentry)
+static int hfs_revalidate_dentry(struct dentry *dentry, int flags)
 {
 	struct inode *inode = dentry->d_inode;
 	int diff;
diff -urN linux-2.2.8-pre4/fs/namei.c linux-2.2.8-pre5/fs/namei.c
--- linux-2.2.8-pre4/fs/namei.c	1999-04-23 21:20:38.000000000 -0700
+++ linux-2.2.8-pre5/fs/namei.c	2003-08-15 15:06:10.000000000 -0700
@@ -23,18 +23,6 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-/*
- * The bitmask for a lookup event:
- *  - follow links at the end
- *  - require a directory
- *  - ending slashes ok even for nonexistent files
- *  - internal "there are more path compnents" flag
- */
-#define LOOKUP_FOLLOW		(1)
-#define LOOKUP_DIRECTORY	(2)
-#define LOOKUP_SLASHOK		(4)
-#define LOOKUP_CONTINUE		(8)
-
 #include <asm/namei.h>
 
 /* This can be removed after the beta phase. */
@@ -225,12 +213,12 @@
 /*
  * Internal lookup() using the new generic dcache.
  */
-static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name)
+static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
 {
 	struct dentry * dentry = d_lookup(parent, name);
 
 	if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-		if (!dentry->d_op->d_revalidate(dentry) && !d_invalidate(dentry)) {
+		if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
 			dput(dentry);
 			dentry = NULL;
 		}
@@ -245,7 +233,7 @@
  * We get the directory semaphore, and after getting that we also
  * make sure that nobody added the entry to the dcache in the meantime..
  */
-static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
+static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
 {
 	struct dentry * result;
 	struct inode *dir = parent->d_inode;
@@ -258,7 +246,7 @@
 	 * FIXME! This could use version numbering or similar to
 	 * avoid unnecessary cache lookups.
 	 */
-	result = cached_lookup(parent, name);
+	result = cached_lookup(parent, name, flags);
 	if (!result) {
 		struct dentry * dentry = d_alloc(parent, name);
 		result = ERR_PTR(-ENOMEM);
@@ -392,9 +380,9 @@
 		/* This does the actual lookups.. */
 		dentry = reserved_lookup(base, &this);
 		if (!dentry) {
-			dentry = cached_lookup(base, &this);
+			dentry = cached_lookup(base, &this, flags);
 			if (!dentry) {
-				dentry = real_lookup(base, &this);
+				dentry = real_lookup(base, &this, flags);
 				if (IS_ERR(dentry))
 					break;
 			}
diff -urN linux-2.2.8-pre4/fs/ncpfs/dir.c linux-2.2.8-pre5/fs/ncpfs/dir.c
--- linux-2.2.8-pre4/fs/ncpfs/dir.c	1999-04-26 09:26:55.000000000 -0700
+++ linux-2.2.8-pre5/fs/ncpfs/dir.c	2003-08-15 15:06:10.000000000 -0700
@@ -112,14 +112,14 @@
 /*
  * Dentry operations routines
  */
-static int ncp_lookup_validate(struct dentry *);
+static int ncp_lookup_validate(struct dentry *, int);
 static int ncp_hash_dentry(struct dentry *, struct qstr *);
 static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *);
 static void ncp_delete_dentry(struct dentry *);
 
 struct dentry_operations ncp_dentry_operations =
 {
-	ncp_lookup_validate,	/* d_validate(struct dentry *) */
+	ncp_lookup_validate,	/* d_revalidate(struct dentry *, int) */
 	ncp_hash_dentry,	/* d_hash */
 	ncp_compare_dentry,    	/* d_compare */
 	ncp_delete_dentry	/* d_delete(struct dentry *) */
@@ -345,7 +345,7 @@
 
 
 static int
-ncp_lookup_validate(struct dentry * dentry)
+ncp_lookup_validate(struct dentry * dentry, int flags)
 {
 	struct ncp_server *server;
 	struct inode *dir = dentry->d_parent->d_inode;
diff -urN linux-2.2.8-pre4/fs/nfs/dir.c linux-2.2.8-pre5/fs/nfs/dir.c
--- linux-2.2.8-pre4/fs/nfs/dir.c	2003-08-15 15:06:09.000000000 -0700
+++ linux-2.2.8-pre5/fs/nfs/dir.c	2003-08-15 15:06:10.000000000 -0700
@@ -72,9 +72,9 @@
 	NULL,			/* select - default */
 	NULL,			/* ioctl - default */
 	NULL,			/* mmap */
-	nfs_open,		/* open - revalidate the inode */
+	nfs_open,		/* open */
 	NULL,			/* flush */
-	NULL,			/* no special release code */
+	nfs_release,		/* release */
 	NULL			/* fsync */
 };
 
@@ -364,7 +364,43 @@
 	dentry->d_time = jiffies;
 }
 
-#define NFS_REVALIDATE_INTERVAL (5*HZ)
+static inline int nfs_dentry_force_reval(struct dentry *dentry, int flags)
+{
+	struct inode *inode = dentry->d_inode;
+	unsigned long timeout = NFS_ATTRTIMEO(inode);
+
+	/*
+	 * If it's the last lookup in a series, we use a stricter
+	 * cache consistency check!
+	 */
+	if (!(flags & LOOKUP_CONTINUE))
+		timeout = 0;
+	
+	return time_after(jiffies,dentry->d_time + timeout);
+}
+
+/*
+ * We judge how long we want to trust negative
+ * dentries by looking at the parent inode mtime.
+ *
+ * If mtime is close to present time, we revalidate
+ * more often.
+ */
+static inline int nfs_neg_need_reval(struct dentry *dentry)
+{
+	unsigned long timeout = 30 * HZ;
+	struct inode *dir = dentry->d_parent->d_inode;
+
+	if (dir) {
+		/* Modified in the last two minutes? */
+		long diff = CURRENT_TIME - dir->i_mtime;
+		if (diff < 2*60)
+			timeout = 1 * HZ;
+	}
+
+	return time_after(jiffies, dentry->d_time + timeout);
+}
+
 /*
  * This is called every time the dcache has a lookup hit,
  * and we should check whether we can really trust that
@@ -377,7 +413,7 @@
  * we do a new lookup and verify that the dentry is still
  * correct.
  */
-static int nfs_lookup_revalidate(struct dentry * dentry)
+static int nfs_lookup_revalidate(struct dentry * dentry, int flags)
 {
 	struct dentry * parent = dentry->d_parent;
 	struct inode * inode = dentry->d_inode;
@@ -386,11 +422,12 @@
 	struct nfs_fattr fattr;
 
 	/*
-	 * If we don't have an inode, let's just assume
-	 * a 5-second "live" time for negative dentries.
+	 * If we don't have an inode, let's look at the parent
+	 * directory mtime to get a hint about how often we
+	 * should validate things..
 	 */
 	if (!inode) {
-		if (time_after(jiffies, dentry->d_time + NFS_REVALIDATE_INTERVAL))
+		if (nfs_neg_need_reval(dentry))
 			goto out_bad;
 		goto out_valid;
 	}
@@ -401,16 +438,16 @@
 		goto out_bad;
 	}
 
-	if (time_before(jiffies,dentry->d_time+NFS_ATTRTIMEO(inode)))
+	if (IS_ROOT(dentry))
 		goto out_valid;
 
-	if (IS_ROOT(dentry))
+	if (!nfs_dentry_force_reval(dentry, flags))
 		goto out_valid;
 
 	/*
 	 * Do a new lookup and check the dentry attributes.
 	 */
-	error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent), 
+	error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent),
 				dentry->d_name.name, &fhandle, &fattr);
 	if (error)
 		goto out_bad;
@@ -489,7 +526,7 @@
 }
 
 struct dentry_operations nfs_dentry_operations = {
-	nfs_lookup_revalidate,	/* d_validate(struct dentry *) */
+	nfs_lookup_revalidate,	/* d_revalidate(struct dentry *, int) */
 	NULL,			/* d_hash */
 	NULL,			/* d_compare */
 	nfs_dentry_delete,	/* d_delete(struct dentry *) */
diff -urN linux-2.2.8-pre4/fs/nfs/file.c linux-2.2.8-pre5/fs/nfs/file.c
--- linux-2.2.8-pre4/fs/nfs/file.c	2003-08-15 15:06:09.000000000 -0700
+++ linux-2.2.8-pre5/fs/nfs/file.c	2003-08-15 15:06:10.000000000 -0700
@@ -46,9 +46,9 @@
 	NULL,			/* select - default */
 	NULL,			/* ioctl - default */
 	nfs_file_mmap,		/* mmap */
-	nfs_open,		/* open - revalidate the inode */
+	nfs_open,		/* open */
 	nfs_file_flush,		/* flush */
-	NULL,			/* release */
+	nfs_release,		/* release */
 	nfs_fsync,		/* fsync */
 	NULL,			/* fasync */
 	NULL,			/* check_media_change */
diff -urN linux-2.2.8-pre4/fs/nfs/inode.c linux-2.2.8-pre5/fs/nfs/inode.c
--- linux-2.2.8-pre4/fs/nfs/inode.c	2003-08-15 15:06:09.000000000 -0700
+++ linux-2.2.8-pre5/fs/nfs/inode.c	2003-08-15 15:06:10.000000000 -0700
@@ -696,25 +696,19 @@
 }
 
 /*
- * Revalidate the file on open (this
- * is separate from the path-revalidation
- * that we do on any lookup).
- *
- * When we actually open a file, we want
- * fairly strict consistency: make sure that
- * we've updated the attributes within the
- * last second or so..
+ * These are probably going to contain hooks for
+ * allocating and releasing RPC credentials for
+ * the file. I'll have to think about Tronds patch
+ * a bit more..
  */
 int nfs_open(struct inode *inode, struct file *filp)
 {
-	int retval = 0;
+	return 0;
+}
 
-	if (time_after(jiffies, NFS_READTIME(inode) + HZ/2)) {
-		struct dentry *dentry = filp->f_dentry;
-		struct nfs_server *server = NFS_DSERVER(dentry);
-		retval = _nfs_revalidate_inode(server, dentry);
-	}
-	return retval;
+int nfs_release(struct inode *inode, struct file *filp)
+{
+	return 0;
 }
 
 /*
diff -urN linux-2.2.8-pre4/fs/smbfs/dir.c linux-2.2.8-pre5/fs/smbfs/dir.c
--- linux-2.2.8-pre4/fs/smbfs/dir.c	1999-04-23 21:20:38.000000000 -0700
+++ linux-2.2.8-pre5/fs/smbfs/dir.c	2003-08-15 15:06:10.000000000 -0700
@@ -191,14 +191,14 @@
 /*
  * Dentry operations routines
  */
-static int smb_lookup_validate(struct dentry *);
+static int smb_lookup_validate(struct dentry *, int);
 static int smb_hash_dentry(struct dentry *, struct qstr *);
 static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
 static void smb_delete_dentry(struct dentry *);
 
 static struct dentry_operations smbfs_dentry_operations =
 {
-	smb_lookup_validate,	/* d_validate(struct dentry *) */
+	smb_lookup_validate,	/* d_revalidate(struct dentry *) */
 	smb_hash_dentry,	/* d_hash */
 	smb_compare_dentry,	/* d_compare */
 	smb_delete_dentry	/* d_delete(struct dentry *) */
@@ -208,7 +208,7 @@
  * This is the callback when the dcache has a lookup hit.
  */
 static int
-smb_lookup_validate(struct dentry * dentry)
+smb_lookup_validate(struct dentry * dentry, int flags)
 {
 	struct inode * inode = dentry->d_inode;
 	unsigned long age = jiffies - dentry->d_time;
diff -urN linux-2.2.8-pre4/fs/umsdos/dir.c linux-2.2.8-pre5/fs/umsdos/dir.c
--- linux-2.2.8-pre4/fs/umsdos/dir.c	1999-04-23 21:20:38.000000000 -0700
+++ linux-2.2.8-pre5/fs/umsdos/dir.c	2003-08-15 15:06:10.000000000 -0700
@@ -30,7 +30,7 @@
  */
 
 /* nothing for now ... */
-static int umsdos_dentry_validate(struct dentry *dentry)
+static int umsdos_dentry_validate(struct dentry *dentry, int flags)
 {
 	return 1;
 }
@@ -46,7 +46,7 @@
 
 struct dentry_operations umsdos_dentry_operations =
 {
-	umsdos_dentry_validate,	/* d_validate(struct dentry *) */
+	umsdos_dentry_validate,	/* d_revalidate(struct dentry *, int) */
 	NULL,			/* d_hash */
 	NULL,			/* d_compare */
 	umsdos_dentry_dput,	/* d_delete(struct dentry *) */
diff -urN linux-2.2.8-pre4/fs/vfat/namei.c linux-2.2.8-pre5/fs/vfat/namei.c
--- linux-2.2.8-pre4/fs/vfat/namei.c	1999-04-23 21:20:38.000000000 -0700
+++ linux-2.2.8-pre5/fs/vfat/namei.c	2003-08-15 15:06:10.000000000 -0700
@@ -71,7 +71,7 @@
 static int vfat_hash(struct dentry *parent, struct qstr *qstr);
 static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
 static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int vfat_revalidate(struct dentry *dentry);
+static int vfat_revalidate(struct dentry *dentry, int);
 
 static struct dentry_operations vfat_dentry_ops[4] = {
 	{
@@ -106,7 +106,7 @@
 	MOD_DEC_USE_COUNT;
 }
 
-static int vfat_revalidate(struct dentry *dentry)
+static int vfat_revalidate(struct dentry *dentry, int flags)
 {
 	PRINTK1(("vfat_revalidate: %s\n", dentry->d_name.name));
 	if (dentry->d_time == dentry->d_parent->d_inode->i_version) {
diff -urN linux-2.2.8-pre4/include/asm-arm/a.out.h linux-2.2.8-pre5/include/asm-arm/a.out.h
--- linux-2.2.8-pre4/include/asm-arm/a.out.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/a.out.h	2003-08-15 15:06:10.000000000 -0700
@@ -26,7 +26,9 @@
 
 #define M_ARM 103
 
+#ifdef __KERNEL__
 #include <asm/arch/a.out.h>
+#endif
 
 #ifndef LIBRARY_START_TEXT
 #define LIBRARY_START_TEXT	(0x00c00000)
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/a.out.h linux-2.2.8-pre5/include/asm-arm/arch-arc/a.out.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/a.out.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/a.out.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,16 +1,14 @@
 /*
  * linux/include/asm-arm/arch-arc/a.out.h
  *
- * Copyright (C) 1996 Russell King
- *
- * Acorn Archimedes/A5000 a.out.h specs
+ * Copyright (C) 1996-1999 Russell King
  */
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP		(0x01a00000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP	TASK_SIZE
 
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/hardware.h linux-2.2.8-pre5/include/asm-arm/arch-arc/hardware.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/hardware.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/hardware.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  * linux/include/asm-arm/arch-arc/hardware.h
  *
- * Copyright (C) 1996 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
  *
  * This file contains the hardware definitions of the
  * Acorn Archimedes/A5000 machines.
@@ -9,21 +9,20 @@
  * Modifications:
  *  04-04-1998	PJB/RMK	Merged arc and a5k versions
  */
-
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
 #include <linux/config.h>
 
+#include <asm/arch/memory.h>
+
 /*
  * What hardware must be present - these can be tested by the kernel
  * source.
  */
 #define HAS_IOC
-#include <asm/ioc.h>
 #define HAS_MEMC
 #include <asm/memc.h>
-#define HAS_MEMC1A
 #define HAS_VIDC
 
 /*
@@ -56,6 +55,12 @@
  * for use with inb/outb
  */
 #define IO_VIDC_BASE		0x80100000
+#ifdef CONFIG_ARCH_A5K
+#define IOEB_VID_CTL		0x800d4012
+#define IOEB_PRESENT		0x800d4014
+#define IOEB_PSCLR		0x800d4016
+#define IOEB_MONTYPE		0x800d401c
+#endif
 #ifdef CONFIG_ARCH_ARC
 #define LATCHAADDR		0x80094010
 #define LATCHBADDR		0x80094006
@@ -66,6 +71,14 @@
 #define IO_EC_IOC_BASE		0x80090000
 #define IO_EC_MEMC_BASE		0x80000000
 
+#ifdef CONFIG_ARCH_ARC
+/* A680 hardware */
+#define WD1973_BASE		0x03290000
+#define WD1973_LATCH		0x03350000
+#define Z8530_BASE		0x032b0008
+#define SCSI_BASE		0x03100000
+#endif
+
 /*
  * IO definitions
  */
@@ -77,11 +90,8 @@
 /*
  * RAM definitions
  */
-#define MAPTOPHYS(a)		(((unsigned long)a & 0x007fffff) + PAGE_OFFSET)
-#define KERNTOPHYS(a)		((((unsigned long)(&a)) & 0x007fffff) + PAGE_OFFSET)
 #define GET_MEMORY_END(p)	(PAGE_OFFSET + (p->u1.s.page_size) * (p->u1.s.nr_pages))
 #define PARAMS_BASE		(PAGE_OFFSET + 0x7c000)
-#define KERNEL_BASE		(PAGE_OFFSET + 0x80000)
 
 #else
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/irq.h linux-2.2.8-pre5/include/asm-arm/arch-arc/irq.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/irq.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/irq.h	2003-08-15 15:06:10.000000000 -0700
@@ -10,6 +10,9 @@
  *   11-01-1998	RMK	Added mask_and_ack_irq
  *   22-08-1998	RMK	Restructured IRQ routines
  */
+#include <asm/ioc.h>
+
+#define fixup_irq(x) (x)
 
 static void arc_mask_irq_ack_a(unsigned int irq)
 {
@@ -108,10 +111,17 @@
 	outb(0, IOC_FIQMASK);
 
 	for (irq = 0; irq < NR_IRQS; irq++) {
-		switch (irq & 0xf8) {
+		switch (irq) {
 		case 0 ... 6:
 			irq_desc[irq].probe_ok = 1;
+			irq_desc[irq].valid    = 1;
+			irq_desc[irq].mask_ack = arc_mask_irq_ack_a;
+			irq_desc[irq].mask     = arc_mask_irq_a;
+			irq_desc[irq].unmask   = arc_unmask_irq_a;
+			break;
+
 		case 7:
+			irq_desc[irq].noautoenable = 1;
 			irq_desc[irq].valid    = 1;
 			irq_desc[irq].mask_ack = arc_mask_irq_ack_a;
 			irq_desc[irq].mask     = arc_mask_irq_a;
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/keyboard.h linux-2.2.8-pre5/include/asm-arm/arch-arc/keyboard.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/keyboard.h	1999-04-26 10:56:18.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/keyboard.h	2003-08-15 15:06:10.000000000 -0700
@@ -11,7 +11,6 @@
 
 #define NR_SCANCODES 128
 
-extern int a5kkbd_translate(unsigned char scancode, unsigned char *keycode_p, char *up_flag_p);
 extern void a5kkbd_leds(unsigned char leds);
 extern void a5kkbd_init_hw(void);
 extern unsigned char a5kkbd_sysrq_xlate[NR_SCANCODES];
@@ -19,11 +18,7 @@
 #define kbd_setkeycode(sc,kc)		(-EINVAL)
 #define kbd_getkeycode(sc)		(-EINVAL)
 
-/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
- * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
- *            set to 0200 if scancode indicates release
- */
-#define kbd_translate(sc, kcp, ufp, rm)	a5kkbd_translate(sc, kcp, ufp)
+#define kbd_translate(sc, kcp, rm)	({ *(kcp) = (sc); 1; })
 #define kbd_unexpected_up(kc)		(0200)
 #define kbd_leds(leds)			a5kkbd_leds(leds)
 #define kbd_init_hw()			a5kkbd_init_hw()
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/memory.h linux-2.2.8-pre5/include/asm-arm/arch-arc/memory.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/memory.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/memory.h	2003-08-15 15:06:10.000000000 -0700
@@ -0,0 +1,41 @@
+/*
+ * linux/include/asm-arm/arch-arc/memory.h
+ *
+ * Copyright (c) 1996-1999 Russell King.
+ *
+ * Changelog:
+ *  22-Nov-1996	RMK	Created
+ *  21-Mar-1999	RMK	Renamed to memory.h
+ *		RMK	Moved PAGE_OFFSET and TASK_SIZE here
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * User space: 26MB
+ */
+#define TASK_SIZE	(0x01a00000UL)
+
+/*
+ * Page offset: 32MB
+ */
+#define PAGE_OFFSET	(0x02000000UL)
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) vpage
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ppage
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	(x)
+
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/mmu.h linux-2.2.8-pre5/include/asm-arm/arch-arc/mmu.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/mmu.h	1998-04-12 11:42:15.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/mmu.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,29 +0,0 @@
-/*
- * linux/include/asm-arm/arch-arc/mmu.h
- *
- * Copyright (c) 1996 Russell King.
- *
- * Changelog:
- *  22-11-1996	RMK	Created
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-#define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) vpage
-#define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ppage
-
-/*
- * Virtual view <-> DMA view memory address translations
- * virt_to_bus: Used to translate the virtual address to an
- *              address suitable to be passed to set_dma_addr
- * bus_to_virt: Used to convert an address for DMA operations
- *              to an address that the kernel can use.
- */
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)	(x)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)	(x)
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/oldlatches.h linux-2.2.8-pre5/include/asm-arm/arch-arc/oldlatches.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/oldlatches.h	1998-04-12 11:42:15.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/oldlatches.h	2003-08-15 15:06:10.000000000 -0700
@@ -34,6 +34,8 @@
 /* newval=(oldval & mask)|newdata */
 void oldlatch_aupdate(unsigned char mask,unsigned char newdata);
 
+void oldlatch_init(void);
+
 #elif defined(CONFIG_ARCH_A5K)
 
 #ifdef __need_oldlatches
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/processor.h linux-2.2.8-pre5/include/asm-arm/arch-arc/processor.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/processor.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/processor.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,15 +1,18 @@
 /*
  * linux/include/asm-arm/arch-arc/processor.h
  *
- * Copyright (c) 1996 Russell King.
+ * Copyright (c) 1996-1999 Russell King.
  *
  * Changelog:
- *  10-09-1996	RMK	Created
+ *  10-Sep-1996	RMK	Created
+ *  21-Mar-1999	RMK	Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
@@ -18,17 +21,9 @@
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 26MB
- */
-#define TASK_SIZE	(0x01a00000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/time.h linux-2.2.8-pre5/include/asm-arm/arch-arc/time.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/time.h	1998-01-20 16:39:42.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/time.h	2003-08-15 15:06:10.000000000 -0700
@@ -8,6 +8,9 @@
  *  10-Oct-1996	RMK	Brought up to date with arch-sa110eval
  *  04-Dec-1997	RMK	Updated for new arch/arm/time.c
  */
+#include <asm/ioc.h>
+
+static long last_rtc_update = 0;	/* last time the cmos clock got updated */
 
 extern __inline__ unsigned long gettimeoffset (void)
 {
@@ -51,46 +54,140 @@
 	return offset;
 }
 
-/*
- * No need to reset the timer at every irq
- */
-#define reset_timer() 1
+extern int iic_control (unsigned char, int, char *, int);
 
-/*
- * Updating of the RTC.  We don't currently write the time to the
- * CMOS clock.
- */
-#define update_rtc()
+static int set_rtc_time(unsigned long nowtime)
+{
+	char buf[5], ctrl;
+
+	if (iic_control(0xa1, 0, &ctrl, 1) != 0)
+		printk("RTC: failed to read control reg\n");
+
+	/*
+	 * Reset divider
+	 */
+	ctrl |= 0x80;
+
+	if (iic_control(0xa0, 0, &ctrl, 1) != 0)
+		printk("RTC: failed to stop the clock\n");
+
+	/*
+	 * We only set the time - we don't set the date.
+	 * This means that there is the possibility once
+	 * a day for the correction to disrupt the date.
+	 * We really ought to write the time and date, or
+	 * nothing at all.
+	 */
+	buf[0] = 0;
+	buf[1] = nowtime % 60;		nowtime /= 60;
+	buf[2] = nowtime % 60;		nowtime /= 60;
+	buf[3] = nowtime % 24;
+
+	BIN_TO_BCD(buf[1]);
+	BIN_TO_BCD(buf[2]);
+	BIN_TO_BCD(buf[3]);
+
+	if (iic_control(0xa0, 1, buf, 4) != 0)
+		printk("RTC: Failed to set the time\n");
+
+	/*
+	 * Re-enable divider
+	 */
+	ctrl &= ~0x80;
+
+	if (iic_control(0xa0, 0, &ctrl, 1) != 0)
+		printk("RTC: failed to start the clock\n");
+
+	return 0;
+}
+
+extern __inline__ unsigned long get_rtc_time(void)
+{
+	unsigned int year, i;
+	char buf[8];
+
+	/*
+	 * The year is not part of the RTC counter
+	 * registers, and is stored in RAM.  This
+	 * means that it will not be automatically
+	 * updated.
+	 */
+	if (iic_control(0xa1, 0xc0, buf, 1) != 0)
+		printk("RTC: failed to read the year\n");
+
+	/*
+	 * If the year is before 1970, then the year
+	 * is actually 100 in advance.  This gives us
+	 * a year 2070 bug...
+	 */
+	year = 1900 + buf[0];
+	if (year < 1970)
+		year += 100;
+
+	/*
+	 * Read the time and date in one go - this
+	 * will ensure that we don't get any effects
+	 * due to carry (the RTC latches the counters
+	 * during a read).
+	 */
+	if (iic_control(0xa1, 2, buf, 5) != 0) {
+		printk("RTC: failed to read the time and date\n");
+		memset(buf, 0, sizeof(buf));
+	}
+
+	/*
+	 * The RTC combines years with date and weekday
+	 * with month.  We need to mask off this extra
+	 * information before converting the date to
+	 * binary.
+	 */
+	buf[4] &= 0x1f;
+	buf[3] &= 0x3f;
+
+	for (i = 0; i < 5; i++)
+		BCD_TO_BIN(buf[i]);
+
+	return mktime(year, buf[4], buf[3], buf[2], buf[1], buf[0]);
+}
+
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_timer(regs);
+
+	/* If we have an externally synchronized linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 50000 - (tick >> 1) &&
+	    xtime.tv_usec < 50000 + (tick >> 1)) {
+		if (set_rtc_time(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+}
+
+static struct irqaction timerirq = {
+	timer_interrupt,
+	0,
+	0,
+	"timer",
+	NULL,
+	NULL
+};
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
  */
-extern __inline__ unsigned long setup_timer (void)
+extern __inline__ void setup_timer(void)
 {
-	extern int iic_control (unsigned char, int, char *, int);
-	unsigned int year, mon, day, hour, min, sec;
-	char buf[8];
-
 	outb(LATCH & 255, IOC_T0LTCHL);
 	outb(LATCH >> 8, IOC_T0LTCHH);
 	outb(0, IOC_T0GO);
 
-	iic_control (0xa0, 0xc0, buf, 1);
-	year = buf[0];
-	if ((year += 1900) < 1970)
-		year += 100;
-
-	iic_control (0xa0, 2, buf, 5);
-	mon  = buf[4] & 0x1f;
-	day  = buf[3] & 0x3f;
-	hour = buf[2];
-	min  = buf[1];
-	sec  = buf[0];
-	BCD_TO_BIN(mon);
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(hour);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(sec);
+	xtime.tv_sec = get_rtc_time();
 
-	return mktime(year, mon, day, hour, min, sec);
+	setup_arm_irq(IRQ_TIMER, &timerirq);
 }
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-arc/uncompress.h linux-2.2.8-pre5/include/asm-arm/arch-arc/uncompress.h
--- linux-2.2.8-pre4/include/asm-arm/arch-arc/uncompress.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-arc/uncompress.h	2003-08-15 15:06:10.000000000 -0700
@@ -5,8 +5,6 @@
  */
 #define VIDMEM ((char *)0x02000000)
  
-#include "../arch/arm/drivers/char/font.h"
-
 int video_num_columns, video_num_lines, video_size_row;
 int white, bytes_per_char_h;
 extern unsigned long con_charconvtable[256];
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/a.out.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/a.out.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/a.out.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/a.out.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,15 +1,16 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/a.out.h
  *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996-1999 Russell King
  */
-
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP		((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP \
+	((current->personality == PER_LINUX_32BIT) ? \
+	 TASK_SIZE : 0x04000000)
 
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/hardware.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/hardware.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/hardware.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/hardware.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,19 +1,13 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/hardware.h
  *
- * Copyright (C) 1996,1997,1998 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
  *
  * This file contains the hardware definitions of the EBSA-110.
  */
-
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
-/*
- * What hardware must be present
- */
-#define HAS_PCIO
-
 #ifndef __ASSEMBLER__
 
 /*
@@ -23,28 +17,28 @@
 #define PIT_T2			((volatile unsigned char *)0xf2000009)
 #define PIT_T1			((volatile unsigned char *)0xf2000005)
 #define PIT_T0			((volatile unsigned char *)0xf2000001)
-#define PCIO_BASE		0xf0000000
 
 /*
  * Mapping areas
  */
 #define IO_BASE			0xe0000000
-#define IO_SIZE			0x20000000
-#define IO_START		0xe0000000
 
 /*
  * RAM definitions
  */
-#define MAPTOPHYS(a)		((unsigned long)(a) - PAGE_OFFSET)
-#define KERNTOPHYS(a)		((unsigned long)(&a))
-#define KERNEL_BASE		(0xc0008000)
 #define FLUSH_BASE_PHYS		0x40000000
 
 #else
 
-#define PCIO_BASE		0xf0000000
 #define IO_BASE			0
 
 #endif
+
+#define IO_SIZE			0x20000000
+#define IO_START		0xe0000000
+
+#define FLUSH_BASE		0xdf000000
+#define PCIO_BASE		0xf0000000
+
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/irq.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/irq.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/irq.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/irq.h	2003-08-15 15:06:10.000000000 -0700
@@ -11,6 +11,8 @@
 #define IRQ_MSET	((volatile unsigned char *)0xf2c00000)
 #define IRQ_MASK	((volatile unsigned char *)0xf2c00000)
 
+#define fixup_irq(x) (x)
+
 static void ebsa110_mask_and_ack_irq(unsigned int irq)
 {
 	*IRQ_MCLR = 1 << irq;
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/memory.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/memory.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/memory.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/memory.h	2003-08-15 15:06:10.000000000 -0700
@@ -0,0 +1,35 @@
+/*
+ * linux/include/asm-arm/arch-ebsa110/memory.h
+ *
+ * Copyright (c) 1996-1999 Russell King.
+ *
+ * Changelog:
+ *  20-Oct-1996	RMK	Created
+ *  31-Dec-1997	RMK	Fixed definitions to reduce warnings
+ *  21-Mar-1999	RMK	Renamed to memory.h
+ *		RMK	Moved TASK_SIZE and PAGE_OFFSET here
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000UL)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	(0xc0000000UL)
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	__virt_to_phys(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	__phys_to_virt(x)
+
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/mm-init.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/mm-init.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/mm-init.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/mm-init.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmap.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/mmu.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/mmu.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/mmu.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/mmu.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,23 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmu.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- *
- * Changelog:
- *  20-10-1996	RMK	Created
- *  31-12-1997	RMK	Fixed definitions to reduce warnings
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-#define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
-#define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
-
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)	__virt_to_phys(x)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)	__phys_to_virt(x)
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/oldlatches.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/oldlatches.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/oldlatches.h	1998-01-20 16:39:42.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/oldlatches.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,9 +0,0 @@
-/*
- * Dummy oldlatches.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifdef __need_oldlatches
-#error "Old latches not present in this (rpc) machine"
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/processor.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/processor.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/processor.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/processor.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,12 +1,17 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/processor.h
  *
- * Copyright (C) 1996,1997,1998 Russell King
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * Changelog:
+ *  21-Mar-1999	RMK	Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
@@ -15,17 +20,9 @@
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 3GB
- */
-#define TASK_SIZE	(0xc0000000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/time.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/time.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa110/time.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa110/time.h	2003-08-15 15:06:10.000000000 -0700
@@ -38,63 +38,67 @@
 	return 0;
 }
 
-#ifndef DIVISOR
-extern __inline__ int reset_timer (void)
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	*PIT_T1 = (PIT1_COUNT) & 0xff;
 	*PIT_T1 = (PIT1_COUNT) >> 8;
-	return 1;
-}
-#else
-extern __inline__ int reset_timer (void)
-{
-	static unsigned int divisor;
-#ifdef CONFIG_LEDS	
-	static int count = 50;
-#endif
-
-	*PIT_T1 = (PIT1_COUNT) & 0xff;
-	*PIT_T1 = (PIT1_COUNT) >> 8;
 
 #ifdef CONFIG_LEDS
-	if (--count == 0) {
-		count = 50;
-		leds_event(led_timer);
+	{
+		static int count = 50;
+		if (--count == 0) {
+			count = 50;
+			leds_event(led_timer);
+		}
 	}
 #endif
 
-	if (divisor == 0) {
-		divisor = DIVISOR - 1;
-		return 1;
+	{
+#ifdef DIVISOR
+		static unsigned int divisor;
+
+		if (divisor-- == 0) {
+			divisor = DIVISOR - 1;
+#else
+		{
+#endif
+			do_timer(regs);
+		}
 	}
-	divisor -= 1;
-	return 0;
 }
-#endif
 
-/*
- * We don't have a RTC to update!
- */
-#define update_rtc()
+static struct irqaction timerirq = {
+	timer_interrupt,
+	0,
+	0,
+	"timer",
+	NULL,
+	NULL
+};
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
  */
-extern __inline__ unsigned long setup_timer (void)
+extern __inline__ void setup_timer(void)
 {
 	/*
 	 * Timer 1, mode 0, 16-bit, autoreload
 	 */
 	*PIT_CTRL = 0x70;
+
 	/*
 	 * Refresh counter clocked at 47.8MHz/7 = 146.4ns
 	 * We want centi-second interrupts
 	 */
-	reset_timer ();
+	*PIT_T1 = (PIT1_COUNT) & 0xff;
+	*PIT_T1 = (PIT1_COUNT) >> 8;
+
 	/*
 	 * Default the date to 1 Jan 1970 0:0:0
 	 * You will have to run a time daemon to set the
 	 * clock correctly at bootup
 	 */
-	return mktime(1970, 1, 1, 0, 0, 0);
+	xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0);
+
+	setup_arm_irq(IRQ_TIMER, &timerirq);
 }
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/a.out.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/a.out.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/a.out.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/a.out.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,15 +1,16 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/a.out.h
  *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996-1999 Russell King
  */
-
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP		((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP \
+	((current->personality == PER_LINUX_32BIT) ? \
+	 TASK_SIZE : 0x04000000)
 
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/dma.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/dma.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/dma.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/dma.h	2003-08-15 15:06:10.000000000 -0700
@@ -3,8 +3,8 @@
  *
  * Architecture DMA routines
  *
- * Copyright (C) 1998 Russell King
- * Copyright (C) 1998 Philip Blundell
+ * Copyright (C) 1998,1999 Russell King
+ * Copyright (C) 1998,1999 Philip Blundell
  */
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
@@ -15,12 +15,16 @@
 #define MAX_DMA_ADDRESS		0xffffffff
 
 /*
- * The 21285 has two internal DMA channels; we call these 0 and 1.
+ * The 21285 has two internal DMA channels; we call these 8 and 9.
  * On CATS hardware we have an additional eight ISA dma channels
- * numbered 2..9.
+ * numbered 0..7.
  */
+#define _ISA_DMA(x)		(0+(x))
+#define _DC21285_DMA(x)		(8+(x))
+
 #define MAX_DMA_CHANNELS	10
-#define DMA_ISA_BASE		2
-#define DMA_FLOPPY		(DMA_ISA_BASE + 2)
+
+#define DMA_FLOPPY		_ISA_DMA(2)
+#define DMA_ISA_CASCADE		_ISA_DMA(4)
 
 #endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/hardware.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/hardware.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/hardware.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/hardware.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,47 +1,135 @@
 /*
  * linux/include/asm-arm/arch-ebsa285/hardware.h
  *
- * Copyright (C) 1998 Russell King.
+ * Copyright (C) 1998-1999 Russell King.
  *
  * This file contains the hardware definitions of the EBSA-285.
  */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
 
+#include <linux/config.h>
+#include <asm/arch/memory.h>
 
-/*    Logical    Physical
+#ifdef CONFIG_HOST_FOOTBRIDGE
+/*   Virtual      Physical
  * 0xfff00000	0x40000000	X-Bus
- * 0xffe00000	0x7c000000	PCI I/O space
+ * 0xff000000	0x7c000000	PCI I/O space
  *
  * 0xfe000000	0x42000000	CSR
  * 0xfd000000	0x78000000	Outbound write flush
  * 0xfc000000	0x79000000	PCI IACK/special space
  *
- * 0xf9000000	0x7a010000	PCI Config type 1
- * 0xf8000000	0x7b010000	PCI Config type 0
+ * 0xf9000000	0x7a000000	PCI Config type 1
+ * 0xf8000000	0x7b000000	PCI Config type 0
  * 
  */
+#define XBUS_SIZE		0x00100000
+#define XBUS_BASE		0xfff00000
 
-#include <asm/dec21285.h>
- 
-#define IO_BASE			0xe0000000
-#define PCIO_BASE		0xffe00000
-#define PCI_IACK		0xfc000000 
+#define PCIO_SIZE		0x00100000
+#define PCIO_BASE		0xff000000
 
-#define XBUS_LEDS		((volatile unsigned char *)0xfff12000)
+#define ARMCSR_SIZE		0x01000000
+#define ARMCSR_BASE		0xfe000000
+
+#define WFLUSH_SIZE		0x01000000
+#define WFLUSH_BASE		0xfd000000
+
+#define PCIIACK_SIZE		0x01000000
+#define PCIIACK_BASE		0xfc000000
+
+#define PCICFG1_SIZE		0x01000000
+#define PCICFG1_BASE		0xf9000000
+
+#define PCICFG0_SIZE		0x01000000
+#define PCICFG0_BASE		0xf8000000
+
+#define PCIMEM_SIZE		0x18000000
+#define PCIMEM_BASE		0xe0000000
+
+#define FLUSH_SIZE		0x00100000
+#define FLUSH_BASE		0xdf000000
+
+#define FLASH_SIZE		0x00400000
+#define FLASH_BASE		0xd8000000
+
+#elif defined(CONFIG_ARCH_CO285)
+
+#define PCIMEM_SIZE		0x80000000
+#define PCIMEM_BASE		0x80000000
+
+#define FLASH_SIZE		0x01000000
+#define FLASH_BASE		0x7f000000
+
+#define FLUSH_SIZE		0x00100000
+#define FLUSH_BASE		0x7e000000
+
+#define WFLUSH_SIZE		0x01000000
+#define WFLUSH_BASE		0x7d000000
+
+#define ARMCSR_SIZE		0x00100000
+#define ARMCSR_BASE		0x7cf00000
+
+#define XBUS_SIZE		0x00020000
+#define XBUS_BASE		0x7cee0000
+
+#define PCIO_SIZE		0x00010000
+#define PCIO_BASE		0x7ced0000
+
+#else
+
+#error Add your add-in architecture here
+
+#endif
+
+#define XBUS_LEDS		((volatile unsigned char *)(XBUS_BASE + 0x12000))
 #define XBUS_LED_AMBER		(1 << 0)
 #define XBUS_LED_GREEN		(1 << 1)
 #define XBUS_LED_RED		(1 << 2)
 #define XBUS_LED_TOGGLE		(1 << 8)
 
-#define XBUS_SWITCH		((volatile unsigned char *)0xfff12000)
+#define XBUS_SWITCH		((volatile unsigned char *)(XBUS_BASE + 0x12000))
 #define XBUS_SWITCH_SWITCH	((*XBUS_SWITCH) & 15)
 #define XBUS_SWITCH_J17_13	((*XBUS_SWITCH) & (1 << 4))
 #define XBUS_SWITCH_J17_11	((*XBUS_SWITCH) & (1 << 5))
 #define XBUS_SWITCH_J17_9	((*XBUS_SWITCH) & (1 << 6))
 
-#define KERNTOPHYS(a)		((unsigned long)(&a))
-
 #define PARAMS_OFFSET		0x0100
 #define PARAMS_BASE		(PAGE_OFFSET + PARAMS_OFFSET)
 
 #define FLUSH_BASE_PHYS		0x50000000
 
+
+/* PIC irq control */
+#define PIC_LO			0x20
+#define PIC_MASK_LO		0x21
+#define PIC_HI			0xA0
+#define PIC_MASK_HI		0xA1
+
+/* GPIO pins */
+#define GPIO_CCLK		0x800
+#define GPIO_DSCLK		0x400
+#define GPIO_E2CLK		0x200
+#define GPIO_IOLOAD		0x100
+#define GPIO_RED_LED		0x080
+#define GPIO_WDTIMER		0x040
+#define GPIO_DATA		0x020
+#define GPIO_IOCLK		0x010
+#define GPIO_DONE		0x008
+#define GPIO_FAN		0x004
+#define GPIO_GREEN_LED		0x002
+#define GPIO_RESET		0x001
+
+/* CPLD pins */
+#define CPLD_DSRESET		8
+#define CPLD_UNMUTE		2
+
+#ifndef __ASSEMBLY__
+extern void gpio_modify_op(int mask, int set);
+extern void gpio_modify_io(int mask, int in);
+extern int  gpio_read(void);
+extern void cpld_modify(int mask, int set);
+#endif
+
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/io.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/io.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/io.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/io.h	2003-08-15 15:06:10.000000000 -0700
@@ -16,34 +16,37 @@
  * has the constant-optimised IO
  */
 #undef	ARCH_IO_DELAY
+#define ARCH_READWRITE
 
 /*
  * Dynamic IO functions - let the compiler
  * optimize the expressions
  */
-#define DECLARE_DYN_OUT(fnsuffix,instr,typ)					\
-extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port)	\
-{										\
-	__asm__ __volatile__(							\
-	"str%?" ##instr## "	%0, [%1, %2]		@ out"###fnsuffix	\
-	: 									\
-	: "r" (value), "r" (PCIO_BASE), typ (port));				\
-}
-
-#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ)					\
-extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)		\
-{										\
-	unsigned long value;							\
-	__asm__ __volatile__(							\
-	"ldr%?" ##instr## "	%0, [%1, %2]		@ in"###fnsuffix	\
-	: "=&r" (value)								\
-	: "r" (PCIO_BASE), typ (port));						\
-	return (unsigned sz)value;						\
-}
-
-extern __inline__ unsigned int __ioaddr (unsigned int port)			\
-{										\
-	return (unsigned int)(PCIO_BASE + port);				\
+#define DECLARE_DYN_OUT(fnsuffix,instr,typ)				\
+extern __inline__ void							\
+__out##fnsuffix (unsigned int value, unsigned int port)			\
+{									\
+	__asm__ __volatile__(						\
+	"str%?" ##instr## "	%0, [%1, %2]	@ out"###fnsuffix	\
+	: 								\
+	: "r" (value), "r" (PCIO_BASE), typ (port));			\
+}
+
+#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ)				\
+extern __inline__ unsigned sz						\
+__in##fnsuffix (unsigned int port)					\
+{									\
+	unsigned long value;						\
+	__asm__ __volatile__(						\
+	"ldr%?" ##instr## "	%0, [%1, %2]	@ in"###fnsuffix	\
+	: "=&r" (value)							\
+	: "r" (PCIO_BASE), typ (port));					\
+	return (unsigned sz)value;					\
+}
+
+extern __inline__ unsigned int __ioaddr (unsigned int port)		\
+{									\
+	return (unsigned int)(PCIO_BASE + port);			\
 }
 
 #define DECLARE_IO(sz,fnsuffix,instr,typ)	\
@@ -64,65 +67,65 @@
  * These have to be macros for the 'J' constraint to work -
  * +/-4096 immediate operand.
  */
-#define __outbc(value,port)							\
-({										\
-	__asm__ __volatile__(							\
-	"str%?b	%0, [%1, %2]				@ outbc"		\
-	:									\
-	: "r" (value), "r" (PCIO_BASE), "Jr" (port));				\
-})
-
-#define __inbc(port)								\
-({										\
-	unsigned char result;							\
-	__asm__ __volatile__(							\
-	"ldr%?b	%0, [%1, %2]				@ inbc"			\
-	: "=r" (result)								\
-	: "r" (PCIO_BASE), "Jr" (port));					\
-	result;									\
-})
-
-#define __outwc(value,port)							\
-({										\
-	__asm__ __volatile__(							\
-	"str%?h	%0, [%1, %2]				@ outwc"		\
-	:									\
-	: "r" (value), "r" (PCIO_BASE), "r" (port));				\
-})
-
-#define __inwc(port)								\
-({										\
-	unsigned short result;							\
-	__asm__ __volatile__(							\
-	"ldr%?h	%0, [%1, %2]				@ inwc"			\
-	: "=r" (result)								\
-	: "r" (PCIO_BASE), "r" (port));						\
-	result & 0xffff;							\
-})
-
-#define __outlc(value,port)							\
-({										\
-	__asm__ __volatile__(							\
-	"str%?	%0, [%1, %2]				@ outlc"		\
-	:									\
-	: "r" (value), "r" (PCIO_BASE), "Jr" (port));				\
-})
-
-#define __inlc(port)								\
-({										\
-	unsigned long result;							\
-	__asm__ __volatile__(							\
-	"ldr%?	%0, [%1, %2]				@ inlc"			\
-	: "=r" (result)								\
-	: "r" (PCIO_BASE), "Jr" (port));					\
-	result;									\
-})
-
-#define __ioaddrc(port)								\
-({										\
-	unsigned long addr;							\
-	addr = PCIO_BASE + port;						\
-	addr;									\
+#define __outbc(value,port)						\
+({									\
+	__asm__ __volatile__(						\
+	"str%?b	%0, [%1, %2]				@ outbc"	\
+	:								\
+	: "r" (value), "r" (PCIO_BASE), "Jr" (port));			\
+})
+
+#define __inbc(port)							\
+({									\
+	unsigned char result;						\
+	__asm__ __volatile__(						\
+	"ldr%?b	%0, [%1, %2]				@ inbc"		\
+	: "=r" (result)							\
+	: "r" (PCIO_BASE), "Jr" (port));				\
+	result;								\
+})
+
+#define __outwc(value,port)						\
+({									\
+	__asm__ __volatile__(						\
+	"str%?h	%0, [%1, %2]				@ outwc"	\
+	:								\
+	: "r" (value), "r" (PCIO_BASE), "r" (port));			\
+})
+
+#define __inwc(port)							\
+({									\
+	unsigned short result;						\
+	__asm__ __volatile__(						\
+	"ldr%?h	%0, [%1, %2]				@ inwc"		\
+	: "=r" (result)							\
+	: "r" (PCIO_BASE), "r" (port));					\
+	result & 0xffff;						\
+})
+
+#define __outlc(value,port)						\
+({									\
+	__asm__ __volatile__(						\
+	"str%?	%0, [%1, %2]				@ outlc"	\
+	:								\
+	: "r" (value), "r" (PCIO_BASE), "Jr" (port));			\
+})
+
+#define __inlc(port)							\
+({									\
+	unsigned long result;						\
+	__asm__ __volatile__(						\
+	"ldr%?	%0, [%1, %2]				@ inlc"		\
+	: "=r" (result)							\
+	: "r" (PCIO_BASE), "Jr" (port));				\
+	result;								\
+})
+
+#define __ioaddrc(port)							\
+({									\
+	unsigned long addr;						\
+	addr = PCIO_BASE + port;					\
+	addr;								\
 })
 
 /*
@@ -130,20 +133,22 @@
  *
  * IO address has already been translated to a virtual address
  */
-#define outb_t(v,p)								\
+#define outb_t(v,p)							\
 	(*(volatile unsigned char *)(p) = (v))
 
-#define inb_t(p)								\
+#define inb_t(p)							\
 	(*(volatile unsigned char *)(p))
 
-#define outl_t(v,p)								\
+#define outl_t(v,p)							\
 	(*(volatile unsigned long *)(p) = (v))
 
-#define inl_t(p)								\
+#define inl_t(p)							\
 	(*(volatile unsigned long *)(p))
 
 /*
- * ioremap support
+ * ioremap support - validate a PCI memory address,
+ * and convert a PCI memory address to a physical
+ * address for the page tables.
  */
 #define valid_ioaddr(iomem,size) ((iomem) < 0x80000000 && (iomem) + (size) <= 0x80000000)
 #define io_to_phys(iomem)	((iomem) + DC21285_PCI_MEM)
@@ -153,58 +158,48 @@
  * is using read*() and so on with addresses they didn't get from ioremap
  * this can go away.
  */
-#define IO_FUDGE_FACTOR		0xe0000000
+#define IO_FUDGE_FACTOR		PCIMEM_BASE
 
-extern inline void *ioremap(unsigned long iomem_addr, unsigned long size)
-{
-	unsigned long phys_addr;
-
-	if (!valid_ioaddr(iomem_addr, size))
-		return NULL;
-
-	phys_addr = io_to_phys(iomem_addr & PAGE_MASK);
-
-	return (void *)((unsigned long)__ioremap(phys_addr, size, 0) 
-			- IO_FUDGE_FACTOR);
-}
+/*
+ * ioremap takes a PCI memory address, as specified in
+ * linux/Documentation/IO-mapping.txt
+ */
+#define ioremap(iomem_addr,size)					\
+({									\
+	unsigned long _addr = (iomem_addr), _size = (size);		\
+	void *_ret = NULL;						\
+	if (valid_ioaddr(_addr, _size)) {				\
+		_addr = io_to_phys(_addr);				\
+		_ret = __ioremap(_addr, _size, 0) - IO_FUDGE_FACTOR;	\
+	}								\
+	_ret; })
 
 #define ioremap_nocache(iomem_addr,size) ioremap((iomem_addr),(size))
 
 extern void iounmap(void *addr);
 
-/*
- * We'd probably be better off with these as macros rather than functions.
- * Firstly that would be more efficient and secondly we could do with the
- * ability to stop GCC whinging about type conversions.  --philb
- */
-static inline void writeb(unsigned char b, unsigned int addr)
-{
-	*(volatile unsigned char *)(IO_FUDGE_FACTOR + (addr)) = b;
-}
-
-static inline unsigned char readb(unsigned int addr)
-{
-	return *(volatile unsigned char *)(IO_FUDGE_FACTOR + (addr));
+#define DECLARE_PCI_WRITE(typ,fnsuffix)					\
+static inline void write##fnsuffix(unsigned typ val, unsigned int addr)	\
+{									\
+	*(volatile unsigned typ *)(IO_FUDGE_FACTOR + addr) = val;	\
 }
 
-static inline void writew(unsigned short b, unsigned int addr)
-{
-	*(volatile unsigned short *)(IO_FUDGE_FACTOR + (addr)) = b;
+#define DECLARE_PCI_READ(typ,fnsuffix)					\
+static inline unsigned typ read##fnsuffix (unsigned int addr)		\
+{									\
+	return *(volatile unsigned typ *)(IO_FUDGE_FACTOR + addr);	\
 }
 
-static inline unsigned short readw(unsigned int addr)
-{
-	return *(volatile unsigned short *)(IO_FUDGE_FACTOR + (addr));
-}
+#define DECLARE_PCI(typ,fnsuffix)					\
+	DECLARE_PCI_WRITE(typ,fnsuffix)					\
+	DECLARE_PCI_READ(typ,fnsuffix)
 
-static inline void writel(unsigned long b, unsigned int addr)
-{
-	*(volatile unsigned long *)(IO_FUDGE_FACTOR + (addr)) = b;
-}
+DECLARE_PCI(char,b)
+DECLARE_PCI(short,w)
+DECLARE_PCI(long,l)
 
-static inline unsigned short readl(unsigned int addr)
-{
-	return *(volatile unsigned long *)(IO_FUDGE_FACTOR + (addr));
-}
+#undef DECLARE_PCI
+#undef DECLARE_PCI_READ
+#undef DECLARE_PCI_WRITE
 
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/irq.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/irq.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/irq.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/irq.h	2003-08-15 15:06:10.000000000 -0700
@@ -4,136 +4,205 @@
  * Copyright (C) 1996-1998 Russell King
  *
  * Changelog:
- *   22-08-1998	RMK	Restructured IRQ routines
- *   03-09-1998	PJB	Merged CATS support
+ *  22-Aug-1998	RMK	Restructured IRQ routines
+ *  03-Sep-1998	PJB	Merged CATS support
+ *  20-Jan-1998	RMK	Started merge of EBSA286, CATS and NetWinder
+ *  26-Jan-1999	PJB	Don't use IACK on CATS
+ *  16-Mar-1999	RMK	Added autodetect of ISA PICs
  */
-#include <linux/config.h>
+#include <asm/hardware.h>
+#include <asm/dec21285.h>
+#include <asm/irq.h>
 
-static void ebsa285_mask_irq(unsigned int irq)
+/*
+ * Footbridge IRQ translation table
+ *  Converts from our IRQ numbers into FootBridge masks
+ */
+static int dc21285_irq_mask[] = {
+	IRQ_MASK_UART_RX,	/*  0 */
+	IRQ_MASK_UART_TX,	/*  1 */
+	IRQ_MASK_TIMER1,	/*  2 */
+	IRQ_MASK_TIMER2,	/*  3 */
+	IRQ_MASK_TIMER3,	/*  4 */
+	IRQ_MASK_IN0,		/*  5 */
+	IRQ_MASK_IN1,		/*  6 */
+	IRQ_MASK_IN2,		/*  7 */
+	IRQ_MASK_IN3,		/*  8 */
+	IRQ_MASK_DOORBELLHOST,	/*  9 */
+	IRQ_MASK_DMA1,		/* 10 */
+	IRQ_MASK_DMA2,		/* 11 */
+	IRQ_MASK_PCI,		/* 12 */
+	IRQ_MASK_SDRAMPARITY,	/* 13 */
+	IRQ_MASK_I2OINPOST,	/* 14 */
+	IRQ_MASK_PCI_ERR	/* 15 */
+};
+
+static int isa_irq = -1;
+
+static inline int fixup_irq(unsigned int irq)
+{
+#ifdef CONFIG_HOST_FOOTBRIDGE
+	if (irq == isa_irq)
+		irq = *(unsigned char *)PCIIACK_BASE;
+#endif
+
+	return irq;
+}
+
+static void dc21285_mask_irq(unsigned int irq)
 {
-	*CSR_IRQ_DISABLE = 1 << irq;
+	*CSR_IRQ_DISABLE = dc21285_irq_mask[irq & 15];
 }
 
-static void ebsa285_unmask_irq(unsigned int irq)
+static void dc21285_unmask_irq(unsigned int irq)
 {
-	*CSR_IRQ_ENABLE = 1 << irq;
+	*CSR_IRQ_ENABLE = dc21285_irq_mask[irq & 15];
 }
 
-#ifdef CONFIG_CATS
+static void isa_mask_pic_lo_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq & 7);
 
-/*
- * This contains the irq mask for both 8259A irq controllers,
- */
-static unsigned int isa_irq_mask = 0xffff;
+	outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
+}
 
-#define cached_21	(isa_irq_mask & 0xff)
-#define cached_A1	((isa_irq_mask >> 8) & 0xff)
+static void isa_mask_ack_pic_lo_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq & 7);
 
-#define update_8259(_irq)			\
-	if ((_irq) & 8)				\
-		outb(cached_A1, 0xa1);		\
-	else					\
-		outb(cached_21, 0x21);
-
-static void isa_interrupt(int irq, void *h, struct pt_regs *regs)
-{
-	asmlinkage void do_IRQ(int irq, struct pt_regs * regs);
-	unsigned int irqbits = inb(0x20) | (inb(0xa0) << 8), irqnr = 0;
-	irqbits &= ~(1<<2);	/* don't try to service the cascade */
-	while (irqbits) {
-		if (irqbits & 1)
-			do_IRQ(32 + irqnr, regs);
-		irqbits >>= 1;
-		irqnr++;
-	}
+	outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
+	outb(0x20, PIC_LO);
 }
 
-static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+static void isa_unmask_pic_lo_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq & 7);
+
+	outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
+}
 
-static struct irqaction irq_isa = 
-		{ isa_interrupt, SA_INTERRUPT, 0, "ISA PIC", NULL, NULL };
-static struct irqaction irq_cascade = 
-		{ no_action, 0, 0, "cascade", NULL, NULL };
-
-static void cats_mask_and_ack_isa_irq(unsigned int irq)
-{
-	isa_irq_mask |= (1 << (irq - 32));
-	update_8259(irq);
-	if (irq & 8) {
-		inb(0xA1);	/* DUMMY */
-		outb(cached_A1,0xA1);
-		outb(0x62,0x20);	/* Specific EOI to cascade */
-		outb(0x20,0xA0);
-	} else {
-		inb(0x21);	/* DUMMY */
-		outb(cached_21,0x21);
-		outb(0x20,0x20);
-	}
+static void isa_mask_pic_hi_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq & 7);
+
+	outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
 }
 
-static void cats_mask_isa_irq(unsigned int irq)
+static void isa_mask_ack_pic_hi_irq(unsigned int irq)
 {
-	isa_irq_mask |= (1 << (irq - 32));
-	update_8259(irq);
+	unsigned int mask = 1 << (irq & 7);
+
+	outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
+	outb(0x62, PIC_LO);
+	outb(0x20, PIC_HI);
 }
 
-static void cats_unmask_isa_irq(unsigned int irq)
+static void isa_unmask_pic_hi_irq(unsigned int irq)
 {
-	isa_irq_mask &= ~(1 << (irq - 32));
-	update_8259(irq);
+	unsigned int mask = 1 << (irq & 7);
+
+	outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
 }
- 
-#endif 
+
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+}
+
+static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
 
 static __inline__ void irq_init_irq(void)
 {
 	int irq;
 
+	/*
+	 * setup DC21285 IRQs
+	 */
 	*CSR_IRQ_DISABLE = -1;
 	*CSR_FIQ_DISABLE = -1;
 
-	for (irq = 0; irq < NR_IRQS; irq++) {
+	for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(16); irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 1;
-#ifdef CONFIG_CATS
-		if (machine_is_cats() && IRQ_IS_ISA(irq)) {
-			irq_desc[irq].mask_ack	= cats_mask_and_ack_isa_irq;
-			irq_desc[irq].mask	= cats_mask_isa_irq;
-			irq_desc[irq].unmask	= cats_unmask_isa_irq;
+		irq_desc[irq].mask_ack	= dc21285_mask_irq;
+		irq_desc[irq].mask	= dc21285_mask_irq;
+		irq_desc[irq].unmask	= dc21285_unmask_irq;
+	}
+
+	/*
+	 * Determine the ISA settings for
+	 * the machine we're running on.
+	 */
+	switch (machine_arch_type) {
+	default:
+		isa_irq = -1;
+		break;
+
+	case MACH_TYPE_EBSA285:
+		/* The following is dependent on which slot
+		 * you plug the Southbridge card into.  We
+		 * currently assume that you plug it into
+		 * the right-hand most slot.
+		 */
+		isa_irq = IRQ_PCI;
+		break;
+
+	case MACH_TYPE_CATS:
+		isa_irq = IRQ_IN2;
+		break;
+
+	case MACH_TYPE_NETWINDER:
+		isa_irq = IRQ_IN3;
+		break;
+	}
+
+	if (isa_irq != -1) {
+		/*
+		 * Setup, and then probe for an ISA PIC
+		 */
+		outb(0x11, PIC_LO);
+		outb(_ISA_IRQ(0), PIC_MASK_LO);	/* IRQ number		*/
+		outb(0x04, PIC_MASK_LO);	/* Slave on Ch2		*/
+		outb(0x01, PIC_MASK_LO);	/* x86			*/
+		outb(0xf5, PIC_MASK_LO);	/* pattern: 11110101	*/
+
+		outb(0x11, PIC_HI);
+		outb(_ISA_IRQ(8), PIC_MASK_HI);	/* IRQ number		*/
+		outb(0x02, PIC_MASK_HI);	/* Slave on Ch1		*/
+		outb(0x01, PIC_MASK_HI);	/* x86			*/
+		outb(0xfa, PIC_MASK_HI);	/* pattern: 11111010	*/
+
+//		outb(0x68, PIC_LO);		/* enable special mode	*/
+//		outb(0x68, PIC_HI);		/* enable special mode	*/
+		outb(0x0b, PIC_LO);
+		outb(0x0b, PIC_HI);
+
+		if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) {
+			outb(0xff, PIC_MASK_LO);/* mask all IRQs	*/
+			outb(0xff, PIC_MASK_HI);/* mask all IRQs	*/
 		} else
-#endif
-		{
-			irq_desc[irq].mask_ack	= ebsa285_mask_irq;
-			irq_desc[irq].mask	= ebsa285_mask_irq;
-			irq_desc[irq].unmask	= ebsa285_unmask_irq;
-		}
+			isa_irq = -1;
 	}
 
-#ifdef CONFIG_CATS
-	if (machine_is_cats()) {
-		request_region(0x20, 2, "pic1");
-		request_region(0xa0, 2, "pic2");
-
-		/* set up master 8259 */
-		outb(0x11, 0x20);
-		outb(0, 0x21);
-		outb(1<<2, 0x21);
-		outb(0x1, 0x21);
-		outb(0xff, 0x21);
-		outb(0x68, 0x20);
-		outb(0xa, 0x20);
-		
-		/* set up slave 8259 */
-		outb(0x11, 0xa0);
-		outb(0, 0xa1);
-		outb(2, 0xa1);
-		outb(0x1, 0xa1);
-		outb(0xff, 0xa1);
-		outb(0x68, 0xa0);
-		outb(0xa, 0xa0);
+	if (isa_irq != -1) {
+		for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
+			irq_desc[irq].valid	= 1;
+			irq_desc[irq].probe_ok	= 1;
+			irq_desc[irq].mask_ack	= isa_mask_ack_pic_lo_irq;
+			irq_desc[irq].mask	= isa_mask_pic_lo_irq;
+			irq_desc[irq].unmask	= isa_unmask_pic_lo_irq;
+		}
+
+		for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
+			irq_desc[irq].valid	= 1;
+			irq_desc[irq].probe_ok	= 1;
+			irq_desc[irq].mask_ack	= isa_mask_ack_pic_hi_irq;
+			irq_desc[irq].mask	= isa_mask_pic_hi_irq;
+			irq_desc[irq].unmask	= isa_unmask_pic_hi_irq;
+		}
 
-		setup_arm_irq(IRQ_ISA_PIC, &irq_isa);
+		request_region(PIC_LO, 2, "pic1");
+		request_region(PIC_HI, 2, "pic2");
 		setup_arm_irq(IRQ_ISA_CASCADE, &irq_cascade);
+		setup_arm_irq(isa_irq, &irq_cascade);
 	}
-#endif
 }
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/irqs.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/irqs.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/irqs.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/irqs.h	2003-08-15 15:06:10.000000000 -0700
@@ -3,55 +3,85 @@
  *
  * Copyright (C) 1998 Russell King
  * Copyright (C) 1998 Phil Blundell
+ *
+ * Changelog:
+ *  20-Jan-1998	RMK	Started merge of EBSA286, CATS and NetWinder
+ *  01-Feb-1999	PJB	ISA IRQs start at 0 not 16
  */
 
-#define NR_IRQS			48
+#define NR_IRQS			32
+#define NR_DC21285_IRQS		16
+
+#define _ISA_IRQ(x)		(0 + (x))
+#define _DC21285_IRQ(x)		(16 + (x))
 
 /*
  * This is a list of all interrupts that the 21285
- * can generate
+ * can generate and we handle.
  */
-#define IRQ_RESERVED		0
-#define IRQ_SOFTIRQ		1
-#define IRQ_CONRX		2
-#define IRQ_CONTX		3
-#define IRQ_TIMER1		4
-#define IRQ_TIMER2		5
-#define IRQ_TIMER3		6
-#define IRQ_TIMER4		7
-#define IRQ_IN0			8
-#define IRQ_IN1			9
-#define IRQ_IN2			10
-#define IRQ_IN3			11
-#define IRQ_XCS0		12
-#define IRQ_XCS1		13
-#define IRQ_XCS2		14
-#define IRQ_DOORBELLHOST	15
-#define IRQ_DMA1		16
-#define IRQ_DMA2		17
-#define IRQ_PCI			18
-#define IRQ_BIST		22
-#define IRQ_SERR		23
-#define IRQ_SDRAMPARITY		24
-#define IRQ_I2OINPOST		25
-#define IRQ_DISCARDTIMER	27
-#define IRQ_PCIDATAPARITY	28
-#define IRQ_PCIMASTERABORT	29
-#define IRQ_PCITARGETABORT	30
-#define IRQ_PCIPARITY		31
-
-/* IRQs 32-47 are the 16 ISA interrupts on a CATS board.  */
-#define IRQ_ISA_PIC	IRQ_IN2
-#define IRQ_IS_ISA(_x)	(((_x) >= 32) && ((_x) <= 47))
-#define IRQ_ISA(_x)	((_x) + 0x20)
-#define IRQ_ISA_CASCADE		IRQ_ISA(2)
+#define IRQ_CONRX		_DC21285_IRQ(0)
+#define IRQ_CONTX		_DC21285_IRQ(1)
+#define IRQ_TIMER1		_DC21285_IRQ(2)
+#define IRQ_TIMER2		_DC21285_IRQ(3)
+#define IRQ_TIMER3		_DC21285_IRQ(4)
+#define IRQ_IN0			_DC21285_IRQ(5)
+#define IRQ_IN1			_DC21285_IRQ(6)
+#define IRQ_IN2			_DC21285_IRQ(7)
+#define IRQ_IN3			_DC21285_IRQ(8)
+#define IRQ_DOORBELLHOST	_DC21285_IRQ(9)
+#define IRQ_DMA1		_DC21285_IRQ(10)
+#define IRQ_DMA2		_DC21285_IRQ(11)
+#define IRQ_PCI			_DC21285_IRQ(12)
+#define IRQ_SDRAMPARITY		_DC21285_IRQ(13)
+#define IRQ_I2OINPOST		_DC21285_IRQ(14)
+#define IRQ_PCI_ERR		_DC21285_IRQ(15)
+
+#define IRQ_ISA_TIMER		_ISA_IRQ(0)
+#define IRQ_ISA_KEYBOARD	_ISA_IRQ(1)
+#define IRQ_ISA_CASCADE		_ISA_IRQ(2)
+#define IRQ_ISA_UART2		_ISA_IRQ(3)
+#define IRQ_ISA_UART		_ISA_IRQ(4)
+#define IRQ_ISA_FLOPPY		_ISA_IRQ(6)
+#define IRQ_ISA_PRINTER		_ISA_IRQ(7)
+#define IRQ_ISA_RTC_ALARM	_ISA_IRQ(8)
+#define IRQ_ISA_2		_ISA_IRQ(9)
+#define IRQ_ISA_PS2MOUSE	_ISA_IRQ(12)
+#define IRQ_ISA_HARDDISK1	_ISA_IRQ(14)
+#define IRQ_ISA_HARDDISK2	_ISA_IRQ(15)
+
+#define IRQ_MASK_UART_RX	(1 << 2)
+#define IRQ_MASK_UART_TX	(1 << 3)
+#define IRQ_MASK_TIMER1		(1 << 4)
+#define IRQ_MASK_TIMER2		(1 << 5)
+#define IRQ_MASK_TIMER3		(1 << 6)
+#define IRQ_MASK_IN0		(1 << 8)
+#define IRQ_MASK_IN1		(1 << 9)
+#define IRQ_MASK_IN2		(1 << 10)
+#define IRQ_MASK_IN3		(1 << 11)
+#define IRQ_MASK_DOORBELLHOST	(1 << 15)
+#define IRQ_MASK_DMA1		(1 << 16)
+#define IRQ_MASK_DMA2		(1 << 17)
+#define IRQ_MASK_PCI		(1 << 18)
+#define IRQ_MASK_SDRAMPARITY	(1 << 24)
+#define IRQ_MASK_I2OINPOST	(1 << 25)
+#define IRQ_MASK_PCI_ERR	((1 <<23) | (1 << 27) | (1 << 28) | (1 << 29) | (1 << 30) | (1 << 31))
 
 /*
- * Now map them to the Linux interrupts
+ * Netwinder interrupt allocations
  */
-#define IRQ_TIMER		IRQ_TIMER1
-#define IRQ_FLOPPYDISK		IRQ_ISA(6)
-#define IRQ_HARDDISK		IRQ_ISA(14)
-#define IRQ_HARDDISK_SECONDARY	IRQ_ISA(15)
+#define IRQ_NETWINDER_ETHER10	IRQ_IN0
+#define IRQ_NETWINDER_ETHER100	IRQ_IN1
+#define IRQ_NETWINDER_VIDCOMP	IRQ_IN2
+#define IRQ_NETWINDER_PS2MOUSE	_ISA_IRQ(5)
+#define IRQ_NETWINDER_IR	_ISA_IRQ(6)
+#define IRQ_NETWINDER_BUTTON	_ISA_IRQ(10)
+#define IRQ_NETWINDER_VGA	_ISA_IRQ(11)
+#define IRQ_NETWINDER_SOUND	_ISA_IRQ(12)
+
+#undef RTC_IRQ
+#define RTC_IRQ		IRQ_ISA_RTC_ALARM
+#undef AUX_IRQ
+#define AUX_IRQ		(machine_is_netwinder() ? IRQ_NETWINDER_PS2MOUSE : IRQ_ISA_PS2MOUSE)
+#define IRQ_FLOPPYDISK	IRQ_ISA_FLOPPY
 
-#define irq_cannonicalize(_i)	(((_i) == IRQ_ISA_CASCADE) ? IRQ_ISA(9) : _i)
+#define irq_cannonicalize(_i)	(((_i) == IRQ_ISA_CASCADE) ? IRQ_ISA_2 : _i)
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/keyboard.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/keyboard.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/keyboard.h	1999-04-26 10:56:18.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/keyboard.h	2003-08-15 15:06:10.000000000 -0700
@@ -6,16 +6,10 @@
  * (C) 1998 Russell King
  * (C) 1998 Phil Blundell
  */
-
-#include <linux/config.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 
-#define NR_SCANCODES 128
-
-#ifdef CONFIG_CATS
-
-#define KEYBOARD_IRQ		IRQ_ISA(1)
+extern int have_isa_bridge;
 
 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
 extern int pckbd_getkeycode(unsigned int scancode);
@@ -26,40 +20,52 @@
 extern void pckbd_init_hw(void);
 extern unsigned char pckbd_sysrq_xlate[128];
 
-#define kbd_setkeycode			pckbd_setkeycode
-#define kbd_getkeycode			pckbd_getkeycode
-#define kbd_translate(sc, kcp, ufp, rm) ({ *ufp = sc & 0200; \
-		pckbd_translate(sc & 0x7f, kcp, rm);})
+#define KEYBOARD_IRQ			IRQ_ISA_KEYBOARD
 
-#define kbd_unexpected_up		pckbd_unexpected_up
-#define kbd_leds			pckbd_leds
-#define kbd_init_hw()			\
-		do { if (machine_is_cats()) pckbd_init_hw(); } while (0)
-#define kbd_sysrq_xlate			pckbd_sysrq_xlate
-#define kbd_disable_irq()
-#define kbd_enable_irq()
+#define NR_SCANCODES 128
 
-#define SYSRQ_KEY	0x54
+#define kbd_setkeycode(sc,kc)				\
+	({						\
+		int __ret;				\
+		if (have_isa_bridge)			\
+			__ret = pckbd_setkeycode(sc,kc);\
+		else					\
+			__ret = -EINVAL;		\
+		__ret;					\
+	})
+
+#define kbd_getkeycode(sc)				\
+	({						\
+		int __ret;				\
+		if (have_isa_bridge)			\
+			__ret = pckbd_getkeycode(sc);	\
+		else					\
+			__ret = -EINVAL;		\
+		__ret;					\
+	})
+
+#define kbd_translate(sc, kcp, rm)			\
+	({						\
+		pckbd_translate(sc, kcp, rm);		\
+	})
 
-#else
+#define kbd_unexpected_up		pckbd_unexpected_up
 
-/* Dummy keyboard definitions */
+#define kbd_leds(leds)					\
+	do {						\
+		if (have_isa_bridge)			\
+			pckbd_leds(leds);		\
+	} while (0)
+
+#define kbd_init_hw()					\
+	do {						\
+		if (have_isa_bridge)			\
+			pckbd_init_hw();		\
+	} while (0)
 
-#define kbd_setkeycode(sc,kc)		(-EINVAL)
-#define kbd_getkeycode(sc)		(-EINVAL)
+#define kbd_sysrq_xlate			pckbd_sysrq_xlate
 
-/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
- * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
- *            set to 0200 if scancode indicates release
- */
-#define kbd_translate(sc, kcp, ufp, rm)	(1)
-#define kbd_unexpected_up(kc)		(0200)
-#define kbd_leds(leds)
-#define kbd_init_hw()
-//#define kbd_sysrq_xlate			ps2kbd_sysrq_xlate
 #define kbd_disable_irq()
 #define kbd_enable_irq()
 
-#define SYSRQ_KEY	13
-
-#endif
+#define SYSRQ_KEY	0x54
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/memory.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/memory.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/memory.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/memory.h	2003-08-15 15:06:10.000000000 -0700
@@ -0,0 +1,72 @@
+/*
+ * linux/include/asm-arm/arch-ebsa285/memory.h
+ *
+ * Copyright (c) 1996-1999 Russell King.
+ *
+ * Changelog:
+ *  20-Oct-1996	RMK	Created
+ *  31-Dec-1997	RMK	Fixed definitions to reduce warnings.
+ *  17-May-1998	DAG	Added __virt_to_bus and __bus_to_virt functions.
+ *  21-Nov-1998	RMK	Changed __virt_to_bus and __bus_to_virt to macros.
+ *  21-Mar-1999	RMK	Added PAGE_OFFSET for co285 architecture.
+ *			Renamed to memory.h
+ *			Moved PAGE_OFFSET and TASK_SIZE here
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#if defined(CONFIG_HOST_FOOTBRIDGE)
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE		(0xc0000000UL)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET		(0xc0000000UL)
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)	((x) - 0xe0000000)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)	((x) + 0xe0000000)
+
+#elif defined(CONFIG_ADDIN_FOOTBRIDGE)
+
+#if defined(CONFIG_ARCH_CO285)
+
+/*
+ * Task size: 1.5GB
+ */
+#define TASK_SIZE		(0x60000000UL)
+
+/*
+ * Page offset: 1.5GB
+ */
+#define PAGE_OFFSET		(0x60000000UL)
+
+#else
+
+#error Add in your architecture here
+
+#endif
+
+#ifndef __ASSEMBLY__
+extern unsigned long __virt_to_bus(unsigned long);
+extern unsigned long __bus_to_virt(unsigned long);
+#endif
+
+#endif
+
+/*
+ * On Footbridge machines, the dram is contiguous.
+ * On Host Footbridge, these conversions are constant.
+ * On an add-in footbridge, these depend on register settings.
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((unsigned long)(vpage) - PAGE_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((unsigned long)(ppage) + PAGE_OFFSET)
+
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/mm-init.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/mm-init.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/mm-init.h	1998-04-12 11:42:15.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/mm-init.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmap.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/mmu.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/mmu.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/mmu.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/mmu.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa285/mmu.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- *
- * Changelog:
- *  20-10-1996	RMK	Created
- *  31-12-1997	RMK	Fixed definitions to reduce warnings
- *  17-05-1998	DAG	Added __virt_to_bus and __bus_to_virt functions.
- *  21-11-1998	RMK	Changed __virt_to_bus and __bus_to_virt to macros.
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-/*
- * On ebsa285, the dram is contiguous
- */
-#define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) ((unsigned long)(vpage) - PAGE_OFFSET)
-#define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ((unsigned long)(ppage) + PAGE_OFFSET)
-
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)	((x) - 0xe0000000)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)	((x) + 0xe0000000)
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/oldlatches.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/oldlatches.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/oldlatches.h	1998-04-12 11:42:15.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/oldlatches.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,9 +0,0 @@
-/*
- * Dummy oldlatches.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifdef __need_oldlatches
-#error "Old latches not present in this (rpc) machine"
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/processor.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/processor.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/processor.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/processor.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,12 +1,17 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/processor.h
  *
- * Copyright (C) 1996,1997,1998 Russell King
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * Changelog:
+ *  21-Mar-1999	RMK	Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
@@ -15,17 +20,9 @@
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 3GB
- */
-#define TASK_SIZE	(0xc0000000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/serial.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/serial.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/serial.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/serial.h	2003-08-15 15:06:10.000000000 -0700
@@ -10,8 +10,6 @@
 #ifndef __ASM_ARCH_SERIAL_H
 #define __ASM_ARCH_SERIAL_H
 
-#include <linux/config.h>
-
 #include <asm/irq.h>
 
 /*
@@ -23,13 +21,8 @@
  */
 #define BASE_BAUD (1843200 / 16)
 
-#ifdef CONFIG_CATS
-#define _SER_IRQ0	IRQ_ISA(4)
-#define _SER_IRQ1	IRQ_ISA(3)
-#else
-#define _SER_IRQ0	0
-#define _SER_IRQ1	0
-#endif
+#define _SER_IRQ0	IRQ_ISA_UART
+#define _SER_IRQ1	IRQ_ISA_UART2
 
 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/system.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/system.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/system.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/system.h	2003-08-15 15:06:10.000000000 -0700
@@ -3,6 +3,8 @@
  *
  * Copyright (c) 1996,1997,1998 Russell King.
  */
+#include <asm/dec21285.h>
+#include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/leds.h>
 
@@ -16,14 +18,37 @@
 		 mov	r0, #0x130
 		 mcr	p15, 0, r0, c1, c0	@ MMU off
 		 mcr	p15, 0, ip, c7, c7	@ flush caches
-		 mov	pc, lr");
+		 mov	pc, lr" : : : "cc");
 	} else {
-		/* To reboot, we set up the 21285 watchdog and enable it.
-		 * We then wait for it to timeout.
-		 */
-		*CSR_TIMER4_LOAD = 0x8000;
-		*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
-		*CSR_SA110_CNTL |= 1 << 13;
+		if (machine_is_ebsa285() || machine_is_co285()) {
+			/* To reboot, we set up the 21285 watchdog and
+			 * enable it.  We then wait for it to timeout.
+			 */
+			*CSR_TIMER4_LOAD = 0x8000;
+			*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE |
+					   TIMER_CNTL_AUTORELOAD |
+					   TIMER_CNTL_DIV16;
+			*CSR_SA110_CNTL |= 1 << 13;
+		} else if (machine_is_netwinder()) {
+			/* open up the SuperIO chip
+			 */
+			outb(0x87, 0x370);
+			outb(0x87, 0x370);
+
+			/* aux function group 1 (logical device 7)
+			 */
+			outb(0x07, 0x370);
+			outb(0x07, 0x371);
+
+			/* set GP16 for WD-TIMER output
+			 */
+			outb(0xe6, 0x370);
+			outb(0x00, 0x371);
+
+			/* set a RED LED and toggle WD_TIMER for rebooting
+			 */
+			outb(0xc4, 0x338);
+		}
 	}
 }
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/time.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/time.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/time.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/time.h	2003-08-15 15:06:10.000000000 -0700
@@ -10,116 +10,346 @@
  *  21-Mar-1998	RMK	Created
  *  27-Aug-1998	PJB	CATS support
  *  28-Dec-1998	APH	Made leds optional
+ *  20-Jan-1999	RMK	Started merge of EBSA285, CATS and NetWinder
+ *  16-Mar-1999	RMK	More support for EBSA285-like machines with RTCs in
  */
 
-#define RTC_PORT(x)		(0x72+(x))
-#define RTC_ALWAYS_BCD		1
+#define RTC_PORT(x)		(rtc_base+(x))
+#define RTC_ALWAYS_BCD		0
 
 #include <linux/config.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/dec21285.h>
 #include <asm/leds.h>
 #include <asm/system.h>
-#include <linux/mc146818rtc.h>
 
-extern __inline__ unsigned long gettimeoffset (void)
+static int rtc_base;
+static unsigned long (*gettimeoffset)(void);
+static int (*set_rtc_mmss)(unsigned long nowtime);
+static long last_rtc_update = 0;	/* last time the cmos clock got updated */
+
+#ifdef CONFIG_LEDS
+static void do_leds(void)
+{
+	static unsigned int count = 50;
+	static int last_pid;
+
+	if (current->pid != last_pid) {
+		last_pid = current->pid;
+		if (last_pid)
+			leds_event(led_idle_end);
+		else
+			leds_event(led_idle_start);
+	}
+		
+	if (--count == 0) {
+		count = 50;
+		leds_event(led_timer);
+	}
+}
+#else
+#define do_leds()
+#endif
+
+#define mSEC_10_from_14 ((14318180 + 100) / 200)
+
+static unsigned long isa_gettimeoffset(void)
+{
+	int count;
+
+	static int count_p = (mSEC_10_from_14/6);    /* for the first call after boot */
+	static unsigned long jiffies_p = 0;
+
+	/*
+	 * cache volatile jiffies temporarily; we have IRQs turned off. 
+	 */
+	unsigned long jiffies_t;
+
+	/* timer count may underflow right here */
+	outb_p(0x00, 0x43);	/* latch the count ASAP */
+
+	count = inb_p(0x40);	/* read the latched count */
+
+	/*
+	 * We do this guaranteed double memory access instead of a _p 
+	 * postfix in the previous port access. Wheee, hackady hack
+	 */
+ 	jiffies_t = jiffies;
+
+	count |= inb_p(0x40) << 8;
+
+	/* Detect timer underflows.  If we haven't had a timer tick since 
+	   the last time we were called, and time is apparently going
+	   backwards, the counter must have wrapped during this routine. */
+	if ((jiffies_t == jiffies_p) && (count > count_p))
+		count -= (mSEC_10_from_14/6);
+	else
+		jiffies_p = jiffies_t;
+
+	count_p = count;
+
+	count = (((mSEC_10_from_14/6)-1) - count) * tick;
+	count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
+
+	return count;
+}
+
+static void isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (machine_is_netwinder())
+		do_leds();
+
+	do_timer(regs);
+
+	/* If we have an externally synchronized linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec > 50000 - (tick >> 1) &&
+	    xtime.tv_usec < 50000 + (tick >> 1)) {
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+}
+
+static struct irqaction isa_timer_irq = {
+	isa_timer_interrupt,
+	0,
+	0,
+	"timer",
+	NULL,
+	NULL
+};
+
+__initfunc(static unsigned long
+get_isa_cmos_time(void))
+{
+	unsigned int year, mon, day, hour, min, sec;
+	int i;
+
+	// check to see if the RTC makes sense.....
+	if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0)
+		return mktime(1970, 1, 1, 0, 0, 0);
+
+	/* The Linux interpretation of the CMOS clock register contents:
+	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+	 * RTC registers show the second which has precisely just started.
+	 * Let's hope other operating systems interpret the RTC the same way.
+	 */
+	/* read RTC exactly on falling edge of update flag */
+	for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
+		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+			break;
+
+	for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
+		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+			break;
+
+	do { /* Isn't this overkill ? UIP above should guarantee consistency */
+		sec  = CMOS_READ(RTC_SECONDS);
+		min  = CMOS_READ(RTC_MINUTES);
+		hour = CMOS_READ(RTC_HOURS);
+		day  = CMOS_READ(RTC_DAY_OF_MONTH);
+		mon  = CMOS_READ(RTC_MONTH);
+		year = CMOS_READ(RTC_YEAR);
+	} while (sec != CMOS_READ(RTC_SECONDS));
+
+	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hour);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(mon);
+		BCD_TO_BIN(year);
+	}
+	if ((year += 1900) < 1970)
+		year += 100;
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+static int
+set_isa_cmos_time(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	unsigned char save_control, save_freq_select;
+
+	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+	cmos_minutes = CMOS_READ(RTC_MINUTES);
+	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+		BCD_TO_BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;		/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+			BIN_TO_BCD(real_seconds);
+			BIN_TO_BCD(real_minutes);
+		}
+		CMOS_WRITE(real_seconds,RTC_SECONDS);
+		CMOS_WRITE(real_minutes,RTC_MINUTES);
+	} else
+		retval = -1;
+
+	/* The following flags have to be released exactly in this order,
+	 * otherwise the DS12887 (popular MC146818A clone with integrated
+	 * battery and quartz) will not reset the oscillator and will not
+	 * update precisely 500 ms later. You won't find this mentioned in
+	 * the Dallas Semiconductor data sheets, but who believes data
+	 * sheets anyway ...                           -- Markus Kuhn
+	 */
+	CMOS_WRITE(save_control, RTC_CONTROL);
+	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+	return retval;
+}
+
+
+
+static unsigned long __ebsa285_text timer1_gettimeoffset (void)
 {
 	unsigned long value = LATCH - *CSR_TIMER1_VALUE;
 
 	return (tick * value) / LATCH;
 }
 
-extern __inline__ int reset_timer (void)
+static void __ebsa285_text timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	*CSR_TIMER1_CLR = 0;
 
-#ifdef CONFIG_LEDS
-	/*
-	 * Do the LEDs thing on EBSA-285 hardware.
+	/* Do the LEDs things on non-CATS hardware.
 	 */
-	if (!machine_is_cats()) {
-		static unsigned int count = 50;
-		static int last_pid;
-
-		if (current->pid != last_pid) {
-			last_pid = current->pid;
-			if (last_pid)
-				leds_event(led_idle_end);
-			else
-				leds_event(led_idle_start);
-		}
-		
-		if (--count == 0) {
-			count = 50;
-			leds_event(led_timer);
-		}
+	if (!machine_is_cats())
+		do_leds();
+
+	do_timer(regs);
+
+	/* If we have an externally synchronized linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec > 50000 - (tick >> 1) &&
+	    xtime.tv_usec < 50000 + (tick >> 1)) {
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
 	}
-#endif
-	
-	return 1;
 }
 
-/*
- * We don't have a RTC to update!
- */
-#define update_rtc()
+static struct irqaction __ebsa285_data timer1_irq = {
+	timer1_interrupt,
+	0,
+	0,
+	"timer",
+	NULL,
+	NULL
+};
+
+static int
+set_dummy_time(unsigned long secs)
+{
+	return 1;
+}
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
  */
-extern __inline__ unsigned long setup_timer (void)
+extern __inline__ void setup_timer(void)
 {
-	int year, mon, day, hour, min, sec;
+	switch(machine_arch_type) {
+	case MACH_TYPE_CO285:
+		/*
+		 * Add-in 21285s shouldn't access the RTC
+		 */
+		rtc_base = 0;
+		break;
 
-	/*
-	 * Default the date to 1 Jan 1970 0:0:0
-	 */
-	year = 1970; mon = 1; day = 1;
-	hour = 0; min = 0; sec = 0;
+	default:
+		rtc_base = 0x70;
+		break;
+	}
+
+	if (rtc_base) {
+		int reg_d, reg_b;
+
+		reg_d = CMOS_READ(RTC_REG_D);
 
-	*CSR_TIMER1_CLR  = 0;
-	*CSR_TIMER1_LOAD = LATCH;
-	*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
-
-	if (machine_is_cats()) 
-	{
-		int i;
 		/*
-		 * Read the real time from the Dallas chip.  (Code borrowed
-		 * from arch/i386/kernel/time.c).
+		 * make sure the divider is set
 		 */
-		
-		/* The Linux interpretation of the CMOS clock register contents:
-		 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-		 * RTC registers show the second which has precisely just started.
-		 * Let's hope other operating systems interpret the RTC the same way.
+		CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A);
+
+		/*
+		 * Set control reg B
+		 *   (24 hour mode, update enabled)
 		 */
+		reg_b = CMOS_READ(RTC_REG_B) & 0x7f;
+		reg_b |= 2;
+		CMOS_WRITE(reg_b, RTC_REG_B);
+
+		if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ &&
+		    CMOS_READ(RTC_REG_B) == reg_b) {
+
+			/*
+			 * Check the battery
+			 */
+			if ((reg_d & 0x80) == 0)
+				printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n");
+
+			xtime.tv_sec = get_isa_cmos_time();
+			set_rtc_mmss = set_isa_cmos_time;
+		} else
+			rtc_base = 0;
+	}
 
-		/* read RTC exactly on falling edge of update flag */
-		for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
-			if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-				break;
-		for (i = 0 ; i < 1000000 ; i++)	/* must try at least 2.228 ms */
-			if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-				break;
-		do { /* Isn't this overkill ? UIP above should guarantee consistency */
-			sec = CMOS_READ(RTC_SECONDS);
-			min = CMOS_READ(RTC_MINUTES);
-			hour = CMOS_READ(RTC_HOURS);
-			day = CMOS_READ(RTC_DAY_OF_MONTH);
-			mon = CMOS_READ(RTC_MONTH);
-			year = CMOS_READ(RTC_YEAR);
-		} while (sec != CMOS_READ(RTC_SECONDS));
-		if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-		{
-			BCD_TO_BIN(sec);
-			BCD_TO_BIN(min);
-			BCD_TO_BIN(hour);
-			BCD_TO_BIN(day);
-			BCD_TO_BIN(mon);
-			BCD_TO_BIN(year);
-		}
-		if ((year += 1900) < 1970)
-			year += 100;
+	if (!rtc_base) {
+		/*
+		 * Default the date to 1 Jan 1970 0:0:0
+		 */
+		xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0);
+		set_rtc_mmss = set_dummy_time;
 	}
 
-	return mktime(year, mon, day, hour, min, sec);
+	if (machine_is_ebsa285()) {
+		gettimeoffset = timer1_gettimeoffset;
+
+		*CSR_TIMER1_CLR  = 0;
+		*CSR_TIMER1_LOAD = LATCH;
+		*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
+
+		setup_arm_irq(IRQ_TIMER1, &timer1_irq);
+	} else {
+		/* enable PIT timer */
+		/* set for periodic (4) and LSB/MSB write (0x30) */
+		outb(0x34, 0x43);
+		outb((mSEC_10_from_14/6) & 0xFF, 0x40);
+		outb((mSEC_10_from_14/6) >> 8, 0x40);
+
+		gettimeoffset = isa_gettimeoffset;
+
+		setup_arm_irq(IRQ_ISA_TIMER, &isa_timer_irq);
+	}
 }
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/timex.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/timex.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/timex.h	1998-04-12 11:42:15.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/timex.h	2003-08-15 15:06:10.000000000 -0700
@@ -7,8 +7,8 @@
  */
 
 /*
- * On the EBSA, the clock ticks at weird rates.
- * This is therefore not used to calculate the
- * divisor.
+ * On EBSA285 boards, the clock runs at 50MHz and is
+ * divided by a 4-bit prescaler.  Other boards use an
+ * ISA derived timer, and this is unused.
  */
 #define CLOCK_TICK_RATE		(50000000 / 16)
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/uncompress.h linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/uncompress.h
--- linux-2.2.8-pre4/include/asm-arm/arch-ebsa285/uncompress.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-ebsa285/uncompress.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,9 +1,12 @@
 /*
- * linux/include/asm-arm/arch-ebsa110/uncompress.h
+ * linux/include/asm-arm/arch-ebsa285/uncompress.h
  *
  * Copyright (C) 1996,1997,1998 Russell King
  */
 
+/*
+ * Note! This could cause problems on the NetWinder
+ */
 #define BASE 0x42000160
 
 static __inline__ void putc(char c)
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/a.out.h linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/a.out.h
--- linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/a.out.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/a.out.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,15 +1,16 @@
 /*
  * linux/include/asm-arm/arch-nexuspci/a.out.h
  *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996-1999 Russell King
  */
-
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP		((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP \
+	((current->personality == PER_LINUX_32BIT) ? \
+	 TASK_SIZE : 0x04000000)
 
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/hardware.h linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/hardware.h
--- linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/hardware.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/hardware.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,10 +1,12 @@
 /*
  * linux/include/asm-arm/arch-nexuspci/hardware.h
  *
- * Copyright (C) 1998 Philip Blundell
+ * Copyright (C) 1998-1999 Philip Blundell
  *
  * This file contains the hardware definitions of the Nexus PCI card.
  */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
 
 /*    Logical    Physical
  * 0xfff00000	0x10000000	SCC2691 DUART
@@ -13,27 +15,17 @@
  * 0xffc00000	0x60000000	PLX registers
  * 0xfe000000	0x70000000	PCI I/O
  */
- 
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-/*
- * What hardware must be present
- */
-
-#define HAS_PCIO
-#define PCIO_BASE		0xfe000000
 
 /*
  * Mapping areas
  */
-#define IO_BASE			0xfe000000
+#define PCIO_BASE		0xfe000000
+#define FLUSH_BASE		0xdf000000
 
 /*
  * RAM definitions
  */
 #define RAM_BASE		0x40000000
-#define KERNTOPHYS(a)		((unsigned long)(&a))
 #define FLUSH_BASE_PHYS		0x40000000
 
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/irq.h linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/irq.h
--- linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/irq.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/irq.h	2003-08-15 15:06:10.000000000 -0700
@@ -9,6 +9,8 @@
 
 #include <asm/io.h>
 
+#define fixup_irq(x) (x)
+
 #define INTCONT		0xffe00000
 
 extern unsigned long soft_irq_mask;
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/memory.h linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/memory.h
--- linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/memory.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/memory.h	2003-08-15 15:06:10.000000000 -0700
@@ -0,0 +1,37 @@
+/*
+ * linux/include/asm-arm/arch-nexuspci/memory.h
+ *
+ * Copyright (c) 1997, 1998 Philip Blundell.
+ * Copyright (c) 1999 Russell King
+ *
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000UL)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	(0xc0000000UL)
+
+/*
+ * On NexusPCI, the DRAM is contiguous
+ */
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + 0x40000000)
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - 0x40000000)
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+
+/*
+ * On the PCI bus the DRAM appears at address 0
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
+
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/mm-init.h linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/mm-init.h
--- linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/mm-init.h	1998-04-12 11:42:15.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/mm-init.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-nexuspci/mmap.h
- *
- * Copyright (C) 1998 Philip Blundell
- */
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/mmu.h linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/mmu.h
--- linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/mmu.h	1998-07-18 11:55:25.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/mmu.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,26 +0,0 @@
-/*
- * linux/include/asm-arm/arch-nexuspci/mmu.h
- *
- * Copyright (c) 1997, 1998 Philip Blundell.
- *
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-/*
- * On NexusPCI, the DRAM is contiguous
- */
-#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + 0x40000000)
-#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - 0x40000000)
-#define __virt_to_phys__is_a_macro
-#define __phys_to_virt__is_a_macro
-
-/*
- * On the PCI bus the DRAM appears at address 0
- */
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/processor.h linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/processor.h
--- linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/processor.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/processor.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,13 +1,18 @@
 /*
- * linux/include/asm-arm/arch-ebsa110/processor.h
+ * linux/include/asm-arm/arch-nexuspci/processor.h
  *  from linux/include/asm-arm/arch-ebsa110/processor.h
  *
- * Copyright (C) 1996,1997,1998 Russell King
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * Changelog:
+ *  21-Mar-1999	RMK	Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
@@ -16,17 +21,9 @@
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 3GB
- */
-#define TASK_SIZE	(0xc0000000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/time.h linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/time.h
--- linux-2.2.8-pre4/include/asm-arm/arch-nexuspci/time.h	1998-07-18 11:55:25.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-nexuspci/time.h	2003-08-15 15:06:10.000000000 -0700
@@ -17,37 +17,53 @@
 	return 0;
 }
 
-extern __inline__ int reset_timer (void)
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	static int count = 50;
+
 	writeb(0x90, UART_BASE + 8);
-	if (--count == 0)
-	{
+
+	if (--count == 0) {
 		static int state = 1;
 		state ^= 1;
 		writeb(0x1a + state, INTCONT);
 		count = 50;
 	}
+
 	readb(UART_BASE + 0x14);
 	readb(UART_BASE + 0x14);
 	readb(UART_BASE + 0x14);
 	readb(UART_BASE + 0x14);
 	readb(UART_BASE + 0x14);
 	readb(UART_BASE + 0x14);
-	return 1;
+
+	do_timer(regs);	
 }
 
-extern __inline__ unsigned long setup_timer (void)
+static struct irqaction timerirq = {
+	timer_interrupt,
+	0,
+	0,
+	"timer",
+	NULL,
+	NULL
+};
+
+extern __inline__ void setup_timer(void)
 {
 	int tick = 3686400 / 16 / 2 / 100;
+
 	writeb(tick & 0xff, UART_BASE + 0x1c);
 	writeb(tick >> 8, UART_BASE + 0x18);
 	writeb(0x80, UART_BASE + 8);
 	writeb(0x10, UART_BASE + 0x14);
+
 	/*
 	 * Default the date to 1 Jan 1970 0:0:0
 	 * You will have to run a time daemon to set the
 	 * clock correctly at bootup
 	 */
-	return mktime(1970, 1, 1, 0, 0, 0);
+	xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0);
+
+	setup_arm_irq(IRQ_TIMER, &timerirq);
 }
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/a.out.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/a.out.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/a.out.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/a.out.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,15 +1,16 @@
 /*
  * linux/include/asm-arm/arch-rpc/a.out.h
  *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996-1999 Russell King
  */
-
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP		((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP \
+	((current->personality == PER_LINUX_32BIT) ? \
+	 TASK_SIZE : 0x04000000)
 
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/hardware.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/hardware.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/hardware.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/hardware.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,19 +1,19 @@
 /*
  * linux/include/asm-arm/arch-rpc/hardware.h
  *
- * Copyright (C) 1996 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
  *
  * This file contains the hardware definitions of the RiscPC series machines.
  */
-
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
+#include <asm/arch/memory.h>
+
 /*
  * What hardware must be present
  */
 #define HAS_IOMD
-#include <asm/iomd.h>
 #define HAS_VIDC20
 
 /* Hardware addresses of major areas.
@@ -26,7 +26,7 @@
 
 #define EASI_SIZE		0x08000000	/* EASI I/O */
 #define EASI_START		0x08000000
-#define EASI_BASE		0xe8000000
+#define EASI_BASE		0xe5000000
 
 #define IO_START		0x03000000	/* I/O */
 #define IO_SIZE			0x01000000
@@ -38,6 +38,8 @@
 #define SCREEN1_END		0xd8000000
 #define SCREEN1_BASE		0xd0000000
 
+#define FLUSH_BASE		0xdf000000
+
 
 #ifndef __ASSEMBLER__
 
@@ -47,8 +49,9 @@
 #define IO_VIDC_AUDIO_BASE	0x80140000
 #define IO_VIDC_BASE		0x80100000
 #define IO_IOMD_BASE		0x80080000
+#define IOC_BASE		0x80080000
 
-#define IO_EC_EASI_BASE		0x82000000
+#define IO_EC_EASI_BASE		0x81400000
 #define IO_EC_IOC4_BASE		0x8009c000
 #define IO_EC_IOC_BASE		0x80090000
 #define IO_EC_MEMC8_BASE	0x8000ac00
@@ -59,7 +62,6 @@
  */
 #define EXPMASK_BASE		((volatile unsigned char *)0xe0360000)
 #define IOEB_BASE		((volatile unsigned char *)0xe0350050)
-#define IOC_BASE		((volatile unsigned char *)0xe0200000)
 #define PCIO_FLOPPYDMABASE	((volatile unsigned char *)0xe002a000)
 #define PCIO_BASE		0xe0010000
 
@@ -67,23 +69,19 @@
  * Offsets from RAM base
  */
 #define PARAMS_OFFSET		0x0100
-#define KERNEL_OFFSET		0x8000
 
 /*
  * RAM definitions
  */
-#define MAPTOPHYS(x)		(x)
-#define KERNTOPHYS(x)		((unsigned long)(&x))
 #define GET_MEMORY_END(p)	(PAGE_OFFSET + p->u1.s.page_size * \
 						(p->u1.s.pages_in_bank[0] + \
 						 p->u1.s.pages_in_bank[1] + \
 						 p->u1.s.pages_in_bank[2] + \
 						 p->u1.s.pages_in_bank[3]))
 
-#define KERNEL_BASE		(PAGE_OFFSET + KERNEL_OFFSET)
 #define PARAMS_BASE		(PAGE_OFFSET + PARAMS_OFFSET)
 #define Z_PARAMS_BASE		(RAM_START + PARAMS_OFFSET)
-#define SAFE_ADDR		0x00000000	/* ROM */
+#define FLUSH_BASE_PHYS		0x00000000	/* ROM */
 
 #else
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/irq.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/irq.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/irq.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/irq.h	2003-08-15 15:06:10.000000000 -0700
@@ -7,6 +7,9 @@
  *   10-10-1996	RMK	Brought up to date with arch-sa110eval
  *   22-08-1998	RMK	Restructured IRQ routines
  */
+#include <asm/iomd.h>
+
+#define fixup_irq(x) (x)
 
 static void rpc_mask_irq_ack_a(unsigned int irq)
 {
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/keyboard.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/keyboard.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/keyboard.h	1999-04-26 10:55:47.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/keyboard.h	2003-08-15 15:06:10.000000000 -0700
@@ -10,7 +10,6 @@
 
 #define NR_SCANCODES 128
 
-extern int ps2kbd_translate(unsigned char scancode, unsigned char *keycode_p, char *up_flag_p);
 extern void ps2kbd_leds(unsigned char leds);
 extern void ps2kbd_init_hw(void);
 extern unsigned char ps2kbd_sysrq_xlate[NR_SCANCODES];
@@ -18,15 +17,7 @@
 #define kbd_setkeycode(sc,kc)		(-EINVAL)
 #define kbd_getkeycode(sc)		(-EINVAL)
 
-/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
- * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
- *            set to 0200 if scancode indicates release
- */
-#ifdef NEW_KEYBOARD
-#define kbd_translate(sc, kcp, ufp, rm)	ps2kbd_translate(sc, kcp, ufp)
-#else
-#define kbd_translate(sc, kcp, rm) ({ unsigned int up_flag; ps2kbd_translate(sc, kcp, &up_flag); })
-#endif
+#define kbd_translate(sc, kcp, rm)	({ *(kcp) = (sc); 1; })
 #define kbd_unexpected_up(kc)		(0200)
 #define kbd_leds(leds)			ps2kbd_leds(leds)
 #define kbd_init_hw()			ps2kbd_init_hw()
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/memory.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/memory.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/memory.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/memory.h	2003-08-15 15:06:10.000000000 -0700
@@ -0,0 +1,41 @@
+/*
+ * linux/include/asm-arm/arch-rpc/memory.h
+ *
+ * Copyright (c) 1996,1997,1998 Russell King.
+ *
+ * Changelog:
+ *  20-Oct-1996	RMK	Created
+ *  31-Dec-1997	RMK	Fixed definitions to reduce warnings
+ *  11-Jan-1998	RMK	Uninlined to reduce hits on cache
+ *  08-Feb-1998	RMK	Added __virt_to_bus and __bus_to_virt
+ *  21-Mar-1999	RMK	Renamed to memory.h
+ *		RMK	Added TASK_SIZE and PAGE_OFFSET
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE	(0xc0000000UL)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET	(0xc0000000UL)
+
+#ifndef __ASSEMBLY__
+extern unsigned long __virt_to_phys(unsigned long vpage);
+extern unsigned long __phys_to_virt(unsigned long ppage);
+#endif
+
+/*
+ * These are exactly the same on the RiscPC as the
+ * physical memory view.
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x) __phys_to_virt(x)
+
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/mmu.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/mmu.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/mmu.h	1998-04-12 11:42:16.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/mmu.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,27 +0,0 @@
-/*
- * linux/include/asm-arm/arch-rpc/mmu.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- *
- * Changelog:
- *  20-10-1996	RMK	Created
- *  31-12-1997	RMK	Fixed definitions to reduce warnings
- *  11-01-1998	RMK	Uninlined to reduce hits on cache
- *  08-02-1998	RMK	Added __virt_to_bus and __bus_to_virt
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-extern unsigned long __virt_to_phys(unsigned long vpage);
-extern unsigned long __phys_to_virt(unsigned long ppage);
-
-/*
- * These are exactly the same on the RiscPC as the
- * physical memory view.
- */
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x) __virt_to_phys(x)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x) __phys_to_virt(x)
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/oldlatches.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/oldlatches.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/oldlatches.h	1998-01-20 16:39:42.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/oldlatches.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,9 +0,0 @@
-/*
- * Dummy oldlatches.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifdef __need_oldlatches
-#error "Old latches not present in this (rpc) machine"
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/processor.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/processor.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/processor.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/processor.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,15 +1,18 @@
 /*
  * linux/include/asm-arm/arch-rpc/processor.h
  *
- * Copyright (c) 1996 Russell King.
+ * Copyright (c) 1996-1999 Russell King.
  *
  * Changelog:
- *  10-09-1996	RMK	Created
+ *  10-Sep-1996	RMK	Created
+ *  21-Mar-1999	RMK	Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
@@ -18,17 +21,9 @@
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 3GB
- */
-#define TASK_SIZE	(0xc0000000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/system.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/system.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/system.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/system.h	2003-08-15 15:06:10.000000000 -0700
@@ -6,7 +6,7 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <asm/proc-fns.h>
+#include <asm/iomd.h>
 
 #define arch_reset(mode) {						\
 	extern void ecard_reset (int card);				\
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/time.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/time.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/time.h	1998-01-20 16:39:42.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/time.h	2003-08-15 15:06:10.000000000 -0700
@@ -8,6 +8,9 @@
  *  10-Oct-1996	RMK	Brought up to date with arch-sa110eval
  *  04-Dec-1997	RMK	Updated for new arch/arm/time.c
  */
+#include <asm/iomd.h>
+
+static long last_rtc_update = 0;	/* last time the cmos clock got updated */
 
 extern __inline__ unsigned long gettimeoffset (void)
 {
@@ -51,46 +54,148 @@
 	return offset;
 }
 
-/*
- * No need to reset the timer at every irq
- */
-#define reset_timer() 1
+extern int iic_control(unsigned char, int, char *, int);
 
-/*
- * Updating of the RTC.  We don't currently write the time to the
- * CMOS clock.
- */
-#define update_rtc()
+static int set_rtc_time(unsigned long nowtime)
+{
+	char buf[5], ctrl;
+
+	if (iic_control(0xa1, 0, &ctrl, 1) != 0)
+		printk("RTC: failed to read control reg\n");
+
+	/*
+	 * Reset divider
+	 */
+	ctrl |= 0x80;
+
+	if (iic_control(0xa0, 0, &ctrl, 1) != 0)
+		printk("RTC: failed to stop the clock\n");
+
+	/*
+	 * We only set the time - we don't set the date.
+	 * This means that there is the possibility once
+	 * a day for the correction to disrupt the date.
+	 * We really ought to write the time and date, or
+	 * nothing at all.
+	 */
+	buf[0] = 0;
+	buf[1] = nowtime % 60;		nowtime /= 60;
+	buf[2] = nowtime % 60;		nowtime /= 60;
+	buf[3] = nowtime % 24;
+
+	BIN_TO_BCD(buf[1]);
+	BIN_TO_BCD(buf[2]);
+	BIN_TO_BCD(buf[3]);
+
+	if (iic_control(0xa0, 1, buf, 4) != 0)
+		printk("RTC: Failed to set the time\n");
+
+	/*
+	 * Re-enable divider
+	 */
+	ctrl &= ~0x80;
+
+	if (iic_control(0xa0, 0, &ctrl, 1) != 0)
+		printk("RTC: failed to start the clock\n");
+
+	return 0;
+}
+
+extern __inline__ unsigned long get_rtc_time(void)
+{
+	unsigned int year, i;
+	char buf[8];
+
+	/*
+	 * The year is not part of the RTC counter
+	 * registers, and is stored in RAM.  This
+	 * means that it will not be automatically
+	 * updated.
+	 */
+	if (iic_control(0xa1, 0xc0, buf, 1) != 0)
+		printk("RTC: failed to read the year\n");
+
+	/*
+	 * If the year is before 1970, then the year
+	 * is actually 100 in advance.  This gives us
+	 * a year 2070 bug...
+	 */
+	year = 1900 + buf[0];
+	if (year < 1970)
+		year += 100;
+
+	/*
+	 * Read the time and date in one go - this
+	 * will ensure that we don't get any effects
+	 * due to carry (the RTC latches the counters
+	 * during a read).
+	 */
+	if (iic_control(0xa1, 2, buf, 5) != 0) {
+		printk("RTC: failed to read the time and date\n");
+		memset(buf, 0, sizeof(buf));
+	}
+
+	/*FIXME:
+	 * This doesn't seem to work.  Does RISC OS
+	 * actually use the RTC year?  It doesn't
+	 * seem to.  In that case, how does it update
+	 * the CMOS year?
+	 */
+	/*year += (buf[3] >> 6) & 3;*/
+
+	/*
+	 * The RTC combines years with date and weekday
+	 * with month.  We need to mask off this extra
+	 * information before converting the date to
+	 * binary.
+	 */
+	buf[4] &= 0x1f;
+	buf[3] &= 0x3f;
+printk("Year %4d mon %02X day %02X hour %02X min %02X sec %02X\n", year, buf[4], buf[3], buf[2], buf[1], buf[0]);
+	for (i = 0; i < 5; i++)
+		BCD_TO_BIN(buf[i]);
+
+	return mktime(year, buf[4], buf[3], buf[2], buf[1], buf[0]);
+}
+
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	do_timer(regs);
+
+	/* If we have an externally synchronized linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    xtime.tv_usec >= 50000 - (tick >> 1) &&
+	    xtime.tv_usec < 50000 + (tick >> 1)) {
+		if (set_rtc_time(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+}
+
+static struct irqaction timerirq = {
+	timer_interrupt,
+	0,
+	0,
+	"timer",
+	NULL,
+	NULL
+};
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
  */
-extern __inline__ unsigned long setup_timer (void)
+extern __inline__ void setup_timer(void)
 {
-	extern int iic_control (unsigned char, int, char *, int);
-	unsigned int year, mon, day, hour, min, sec;
-	char buf[8];
-
 	outb(LATCH & 255, IOMD_T0LTCHL);
 	outb(LATCH >> 8, IOMD_T0LTCHH);
 	outb(0, IOMD_T0GO);
 
-	iic_control (0xa0, 0xc0, buf, 1);
-	year = buf[0];
-	if ((year += 1900) < 1970)
-		year += 100;
-
-	iic_control (0xa0, 2, buf, 5);
-	mon  = buf[4] & 0x1f;
-	day  = buf[3] & 0x3f;
-	hour = buf[2];
-	min  = buf[1];
-	sec  = buf[0];
-	BCD_TO_BIN(mon);
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(hour);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(sec);
+	xtime.tv_sec = get_rtc_time();
 
-	return mktime(year, mon, day, hour, min, sec);
+	setup_arm_irq(IRQ_TIMER, &timerirq);
 }
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-rpc/uncompress.h linux-2.2.8-pre5/include/asm-arm/arch-rpc/uncompress.h
--- linux-2.2.8-pre4/include/asm-arm/arch-rpc/uncompress.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-rpc/uncompress.h	2003-08-15 15:06:10.000000000 -0700
@@ -5,7 +5,6 @@
  */
 #define VIDMEM ((char *)SCREEN_START)
  
-#include "../arch/arm/drivers/char/font.h"
 #include <asm/hardware.h>
 #include <asm/io.h>
 
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/a.out.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/a.out.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/a.out.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/a.out.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,14 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/a.out.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifndef __ASM_ARCH_A_OUT_H
-#define __ASM_ARCH_A_OUT_H
-
-#ifdef __KERNEL__
-#define STACK_TOP		((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/dma.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/dma.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/dma.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/dma.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,19 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/dma.h
- *
- * Architecture DMA routes
- *
- * Copyright (C) 1997.1998 Russell King
- */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-/*
- * This is the maximum DMA address that can be DMAd to.
- * There should not be more than (0xd0000000 - 0xc0000000)
- * bytes of RAM.
- */
-#define MAX_DMA_ADDRESS		0xd0000000
-#define MAX_DMA_CHANNELS	8
-
-#endif /* _ASM_ARCH_DMA_H */
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/hardware.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/hardware.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/hardware.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/hardware.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,74 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/hardware.h
- *
- * Copyright (C) 1998 Corel Computer/Russell King.
- *
- * This file contains the hardware definitions of the VNC.
- */
-
-/*    Logical    Physical
- * 0xffe00000	0x7c000000	PCI I/O space
- * 0xfe000000	0x42000000	CSR
- * 0xfd000000	0x78000000	Outbound write flush
- * 0xfc000000	0x79000000	PCI IACK/special space
- * 0xf9000000	0x7a000000	PCI Config type 1
- * 0xf8000000	0x7b000000	PCI Config type 0
- * 
- */
-
-#include <asm/dec21285.h>
-
-#define IO_BASE_ARM_CSR		0xfe000000
-#define PCI_IACK		0xfc000000
- 
-/* LEDs */
-#define XBUS_LEDS		((volatile unsigned char *)0xfff12000)
-#define XBUS_LED_AMBER		(1 << 0)
-#define XBUS_LED_GREEN		(1 << 1)
-#define XBUS_LED_RED		(1 << 2)
-#define XBUS_LED_TOGGLE		(1 << 8)
-
-/* PIC irq control */
-#define PIC_LO			0x20
-#define PIC_MASK_LO		0x21
-#define PIC_HI			0xA0
-#define PIC_MASK_HI		0xA1
-
-#define IO_END			0xffffffff
-#define IO_BASE			0xe0000000
-#define IO_SIZE			(IO_END - IO_BASE)
-
-#define HAS_PCIO
-#define PCIO_BASE		0xffe00000
-
-#define KERNTOPHYS(a)		((unsigned long)(&a))
-
-//#define PARAMS_OFFSET		0x0100
-//#define PARAMS_BASE		(PAGE_OFFSET + PARAMS_OFFSET)
-
-#define FLUSH_BASE_PHYS		0x50000000
-
-/* GPIO pins */
-#define GPIO_CCLK		0x800
-#define GPIO_DSCLK		0x400
-#define GPIO_E2CLK		0x200
-#define GPIO_IOLOAD		0x100
-#define GPIO_RED_LED		0x080
-#define GPIO_WDTIMER		0x040
-#define GPIO_DATA		0x020
-#define GPIO_IOCLK		0x010
-#define GPIO_DONE		0x008
-#define GPIO_FAN		0x004
-#define GPIO_GREEN_LED		0x002
-#define GPIO_RESET		0x001
-
-/* CPLD pins */
-#define CPLD_DSRESET		8
-#define CPLD_UNMUTE		2
-
-#ifndef __ASSEMBLY__
-extern void gpio_modify_op(int mask, int set);
-extern void gpio_modify_io(int mask, int in);
-extern int  gpio_read(void);
-extern void cpld_modify(int mask, int set);
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/ide.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/ide.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/ide.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/ide.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,42 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/ide.h
- *
- * Copyright (c) 1998 Russell King
- *
- * Modifications:
- *  29-07-1998	RMK	Major re-work of IDE architecture specific code
- */
-#include <asm/irq.h>
-
-/*
- * Set up a hw structure for a specified data port, control port and IRQ.
- * This should follow whatever the default interface uses.
- */
-static __inline__ void
-ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int irq)
-{
-	ide_ioreg_t reg = (ide_ioreg_t) data_port;
-	int i;
-
-	memset(hw, 0, sizeof(*hw));
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = reg;
-		reg += 1;
-	}
-	hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
-	hw->irq = irq;
-}
-
-/*
- * This registers the standard ports for this architecture with the IDE
- * driver.
- */
-static __inline__ void
-ide_init_default_hwifs(void)
-{
-	hw_regs_t hw;
-
-	ide_init_hwif_ports(&hw, 0x1f0, 0x3f6, IRQ_HARDDISK);
-	ide_register_hw(&hw, NULL);
-}
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/io.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/io.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/io.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/io.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,176 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/io.h
- *
- * Copyright (C) 1997,1998 Russell King
- *
- * Modifications:
- *  06-Dec-1997	RMK	Created.
- */
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-/*
- * This architecture does not require any delayed IO, and
- * has the constant-optimised IO
- */
-#undef	ARCH_IO_DELAY
-
-/*
- * Dynamic IO functions - let the compiler
- * optimize the expressions
- */
-#define DECLARE_DYN_OUT(fnsuffix,instr,typ)					\
-extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port)	\
-{										\
-	__asm__ __volatile__(							\
-	"str%?" ##instr## "	%0, [%1, %2]		@ out"###fnsuffix	\
-	: 									\
-	: "r" (value), "r" (PCIO_BASE), typ (port));				\
-}
-
-#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ)					\
-extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)		\
-{										\
-	unsigned long value;							\
-	__asm__ __volatile__(							\
-	"ldr%?" ##instr## "	%0, [%1, %2]		@ in"###fnsuffix	\
-	: "=&r" (value)								\
-	: "r" (PCIO_BASE), typ (port));						\
-	return (unsigned sz)value;						\
-}
-
-extern __inline__ unsigned int __ioaddr (unsigned int port)			\
-{										\
-	return (unsigned int)(PCIO_BASE + port);				\
-}
-
-#define DECLARE_IO(sz,fnsuffix,instr,typ)	\
-	DECLARE_DYN_OUT(fnsuffix,instr,typ)	\
-	DECLARE_DYN_IN(sz,fnsuffix,instr,typ)
-
-DECLARE_IO(char,b,"b","Jr")
-DECLARE_IO(short,w,"h","r")
-DECLARE_IO(long,l,"","Jr")
-
-#undef DECLARE_IO
-#undef DECLARE_DYN_OUT
-#undef DECLARE_DYN_IN
-
-/*
- * Constant address IO functions
- *
- * These have to be macros for the 'J' constraint to work -
- * +/-4096 immediate operand.
- */
-#define __outbc(value,port)							\
-({										\
-	__asm__ __volatile__(							\
-	"strb	%0, [%1, %2]				@ outbc"		\
-	:									\
-	: "r" (value), "r" (PCIO_BASE), "Jr" (port));				\
-})
-
-#define __inbc(port)								\
-({										\
-	unsigned char result;							\
-	__asm__ __volatile__(							\
-	"ldrb	%0, [%1, %2]				@ inbc"			\
-	: "=r" (result)								\
-	: "r" (PCIO_BASE), "Jr" (port));					\
-	result;									\
-})
-
-#define __outwc(value,port)							\
-({										\
-	__asm__ __volatile__(							\
-	"strh	%0, [%1, %2]				@ outwc"		\
-	:									\
-	: "r" (value), "r" (PCIO_BASE), "r" (port));				\
-})
-
-#define __inwc(port)								\
-({										\
-	unsigned short result;							\
-	__asm__ __volatile__(							\
-	"ldrh	%0, [%1, %2]				@ inwc"			\
-	: "=r" (result)								\
-	: "r" (PCIO_BASE), "r" (port));						\
-	result & 0xffff;							\
-})
-
-#define __outlc(value,port)							\
-({										\
-	__asm__ __volatile__(							\
-	"str	%0, [%1, %2]				@ outlc"		\
-	:									\
-	: "r" (value), "r" (PCIO_BASE), "Jr" (port));				\
-})
-
-#define __inlc(port)								\
-({										\
-	unsigned long result;							\
-	__asm__ __volatile__(							\
-	"ldr	%0, [%1, %2]				@ inlc"			\
-	: "=r" (result)								\
-	: "r" (PCIO_BASE), "Jr" (port));					\
-	result;									\
-})
-
-#define __ioaddrc(port)								\
-({										\
-	unsigned long addr;							\
-	addr = PCIO_BASE + port;						\
-	addr;									\
-})
-
-/*
- * Translated address IO functions
- *
- * IO address has already been translated to a virtual address
- */
-#define outb_t(v,p)								\
-	(*(volatile unsigned char *)(p) = (v))
-
-#define inb_t(p)								\
-	(*(volatile unsigned char *)(p))
-
-#define outl_t(v,p)								\
-	(*(volatile unsigned long *)(p) = (v))
-
-#define inl_t(p)								\
-	(*(volatile unsigned long *)(p))
-
-/*
- * This is not sufficient... (and it's a hack anyway)
- */
-static inline void writeb(unsigned char b, unsigned int addr)
-{
-	*(volatile unsigned char *)(0xe0000000 + (addr)) = b;
-}
-
-static inline unsigned char readb(unsigned int addr)
-{
-	return *(volatile unsigned char *)(0xe0000000 + (addr));
-}
-
-static inline void writew(unsigned short b, unsigned int addr)
-{
-	*(volatile unsigned short *)(0xe0000000 + (addr)) = b;
-}
-
-static inline unsigned short readw(unsigned int addr)
-{
-	return *(volatile unsigned short *)(0xe0000000 + (addr));
-}
-
-static inline void writel(unsigned long b, unsigned int addr)
-{
-	*(volatile unsigned long *)(0xe0000000 + (addr)) = b;
-}
-
-static inline unsigned long readl(unsigned int addr)
-{
-	return *(volatile unsigned long *)(0xe0000000 + (addr));
-}
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/irq.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/irq.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/irq.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/irq.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,156 +0,0 @@
-/*
- * include/asm-arm/arch-vnc/irq.h
- *
- * Copyright (C) 1998 Russell King
- *
- * Changelog:
- *   22-08-1998	RMK	Restructured IRQ routines
- */
-
-#include <asm/dec21285.h>
-#include <asm/irq.h>
-
-/*
- * FootBridge IRQ translation table
- *  Converts form our IRQ numbers into FootBridge masks (defined in irqs.h)
- */
-static int fb_irq_mask[16] = {
-	0,
-	IRQ_MASK_SOFTIRQ,
-	IRQ_MASK_UART_DEBUG,
-	0,
-	IRQ_MASK_TIMER0,
-	IRQ_MASK_TIMER1,
-	IRQ_MASK_TIMER2,
-	IRQ_MASK_WATCHDOG,
-	IRQ_MASK_ETHER10,
-	IRQ_MASK_ETHER100,
-	IRQ_MASK_VIDCOMP,
-	IRQ_MASK_EXTERN_IRQ,
-	IRQ_MASK_DMA1,
-	0,
-	0,
-	IRQ_MASK_PCI_ERR
-};
-
-static void vnc_mask_csr_irq(unsigned int irq)
-{
-	*CSR_IRQ_DISABLE = fb_irq_mask[irq];
-}
-
-static void vnc_unmask_csr_irq(unsigned int irq)
-{
-	*CSR_IRQ_ENABLE = fb_irq_mask[irq];
-}
-
-static void vnc_mask_pic_lo_irq(unsigned int irq)
-{
-	unsigned int mask = 1 << (irq & 7);
-
-	outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
-}
-
-static void vnc_mask_ack_pic_lo_irq(unsigned int irq)
-{
-	unsigned int mask = 1 << (irq & 7);
-
-	outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
-	outb(0x20, PIC_LO);
-}
-
-static void vnc_unmask_pic_lo_irq(unsigned int irq)
-{
-	unsigned int mask = ~(1 << (irq & 7));
-
-	outb(inb(PIC_MASK_LO) & mask, PIC_MASK_LO);
-}
-
-static void vnc_mask_pic_hi_irq(unsigned int irq)
-{
-	unsigned int mask = 1 << (irq & 7);
-
-	outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
-}
-
-static void vnc_mask_ack_pic_hi_irq(unsigned int irq)
-{
-	unsigned int mask = 1 << (irq & 7);
-
-	outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
-	outb(0x62, PIC_LO);
-	outb(0x20, PIC_HI);
-}
-
-static void vnc_unmask_pic_hi_irq(unsigned int irq)
-{
-	unsigned int mask = 1 << (irq & 7);
-
-	outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
-}
-
-static void no_action(int irq, void *dev_id, struct pt_regs *regs)
-{
-}
-
-static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
-
-static __inline__ void irq_init_irq(void)
-{
-	unsigned int irq;
-
-	outb(0x11, PIC_LO);
-	outb(0x10, PIC_MASK_LO);
-	outb(0x04, PIC_MASK_LO);
-	outb(1, PIC_MASK_LO);
-
-	outb(0x11, PIC_HI);
-	outb(0x18, PIC_MASK_HI);
-	outb(0x02, PIC_MASK_HI);
-	outb(1, PIC_MASK_HI);
-
-	*CSR_IRQ_DISABLE = ~IRQ_MASK_EXTERN_IRQ;
-	*CSR_IRQ_ENABLE  = IRQ_MASK_EXTERN_IRQ;
-	*CSR_FIQ_DISABLE = -1;
-
-	for (irq = 0; irq < NR_IRQS; irq++) {
-		irq_desc[irq].valid	= 1;
-		irq_desc[irq].probe_ok	= 1;
-
-		if (irq < 16) {
-			irq_desc[irq].mask_ack	= vnc_mask_csr_irq;
-			irq_desc[irq].mask	= vnc_mask_csr_irq;
-			irq_desc[irq].unmask	= vnc_unmask_csr_irq;
-		} else if (irq < 24) {
-irq_desc[irq].probe_ok = 0;
-			irq_desc[irq].mask_ack	= vnc_mask_ack_pic_lo_irq;
-			irq_desc[irq].mask	= vnc_mask_pic_lo_irq;
-			irq_desc[irq].unmask	= vnc_unmask_pic_lo_irq;
-		} else {
-irq_desc[irq].probe_ok = 0;
-			irq_desc[irq].mask_ack	= vnc_mask_ack_pic_hi_irq;
-			irq_desc[irq].mask	= vnc_mask_pic_hi_irq;
-			irq_desc[irq].unmask	= vnc_unmask_pic_hi_irq;
-		}
-	}
-
-	irq_desc[0].probe_ok = 0;
-	irq_desc[IRQ_SOFTIRQ].probe_ok = 0;
-	irq_desc[IRQ_CONRX].probe_ok = 0;
-	irq_desc[IRQ_CONTX].probe_ok = 0;
-	irq_desc[IRQ_TIMER0].probe_ok = 0;
-	irq_desc[IRQ_TIMER1].probe_ok = 0;
-	irq_desc[IRQ_TIMER2].probe_ok = 0;
-	irq_desc[IRQ_WATCHDOG].probe_ok = 0;
-	irq_desc[IRQ_DMA1].probe_ok = 0;
-	irq_desc[13].probe_ok = 0;
-	irq_desc[14].probe_ok = 0;
-	irq_desc[IRQ_PCI_ERR].probe_ok = 0;
-	irq_desc[IRQ_PIC_HI].probe_ok = 0;
-	irq_desc[29].probe_ok = 0;
-	irq_desc[31].probe_ok = 0;
-
-	outb(0xff, PIC_MASK_LO);
-	outb(0xff, PIC_MASK_HI);
-
-	setup_arm_irq(IRQ_PIC_HI, &irq_cascade);
-}
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/irqs.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/irqs.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/irqs.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/irqs.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,67 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/irqs.h
- *
- * Copyright (C) 1998 Russell King
- */
-
-#define NR_IRQS			32
-
-/*
- * This is a list of all interrupts that the 21285
- * can generate
- */
-#define IRQ_SOFTIRQ		1	/* from FB.1 */
-#define IRQ_CONRX		2	/* from FB.2 */
-#define IRQ_CONTX		3	/* from FB.3 */
-#define IRQ_TIMER0		4	/* from FB.4 */
-#define IRQ_TIMER1		5	/* from FB.5 */
-#define IRQ_TIMER2		6	/* from FB.6 */
-#define IRQ_WATCHDOG		7	/* from FB.7 */
-#define IRQ_ETHER10		8	/* from FB.8 */
-#define IRQ_ETHER100		9	/* from FB.9 */
-#define IRQ_VIDCOMP		10	/* from FB.10 */
-#define IRQ_EXTERN_IRQ		11	/* from FB.11: chain to IDE irq's */
-#define IRQ_DMA1		12	/* from future */
-#define IRQ_PCI_ERR		15	/* from FB.[28:31] */
-
-#define IRQ_TIMER4		16	/* from 553.0 */
-#define IRQ_KEYBOARD		17	/* from 553.1 */
-#define IRQ_PIC_HI		18	/* from 533.2: chained to 553.[8:15] */
-#define IRQ_UART2		19	/* from 553.3 */
-#define IRQ_UART		20	/* from 553.4 */
-#define IRQ_MOUSE		21	/* from 553.5 */
-#define IRQ_UART_IR		22	/* from 553.6 */
-#define IRQ_PRINTER		23	/* from 553.7 */
-#define IRQ_RTC_ALARM		24	/* from 553.8 */
-#define IRQ_POWERLOW		26	/* from 553.10 */
-#define IRQ_VGA			27	/* from 553.11 */
-#define IRQ_SOUND		28	/* from 553.12 */
-#define IRQ_HARDDISK		30	/* from 553.14 */
-
-/* These defines handle the translation from the above FB #defines
- * into physical bits for the FootBridge IRQ registers
- */
-#define IRQ_MASK_SOFTIRQ	0x00000002
-#define IRQ_MASK_UART_DEBUG	0x0000000C
-#define IRQ_MASK_TIMER0		0x00000010
-#define IRQ_MASK_TIMER1		0x00000020
-#define IRQ_MASK_TIMER2		0x00000040
-#define IRQ_MASK_WATCHDOG	0x00000080
-#define IRQ_MASK_ETHER10	0x00000100
-#define IRQ_MASK_ETHER100	0x00000200
-#define IRQ_MASK_VIDCOMP	0x00000400
-#define IRQ_MASK_EXTERN_IRQ	0x00000800
-#define IRQ_MASK_DMA1		0x00030000
-#define IRQ_MASK_PCI_ERR	0xf8800000
-
-/*
- * Now map them to the Linux interrupts
- */
-#undef IRQ_TIMER
-#define IRQ_TIMER		IRQ_TIMER0
-#undef RTC_IRQ
-#define RTC_IRQ			IRQ_RTC_ALARM
-#undef AUX_IRQ
-#define AUX_IRQ			IRQ_MOUSE
-
-#define irq_cannonicalize(i)	(i)
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/keyboard.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/keyboard.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/keyboard.h	1999-04-26 10:56:18.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/keyboard.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,36 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/keyboard.h
- *
- * Keyboard driver definitions for VNC architecture
- *
- * (C) 1998 Russell King
- */
-
-#include <asm/irq.h>
-
-#define NR_SCANCODES 128
-
-#define KEYBOARD_IRQ			IRQ_KEYBOARD
-
-extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
-			   char raw_mode);
-extern char pckbd_unexpected_up(unsigned char keycode);
-extern void pckbd_leds(unsigned char leds);
-extern void pckbd_init_hw(void);
-extern unsigned char pckbd_sysrq_xlate[128];
-
-#define kbd_setkeycode			pckbd_setkeycode
-#define kbd_getkeycode			pckbd_getkeycode
-#define kbd_translate(sc, kcp, ufp, rm) ({ *ufp = sc & 0200; \
-		pckbd_translate(sc & 0x7f, kcp, rm);})
-
-#define kbd_unexpected_up		pckbd_unexpected_up
-#define kbd_leds			pckbd_leds
-#define kbd_init_hw()			pckbd_init_hw()
-#define kbd_sysrq_xlate			pckbd_sysrq_xlate
-#define kbd_disable_irq()
-#define kbd_enable_irq()
-
-#define SYSRQ_KEY 0x54
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/mm-init.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/mm-init.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/mm-init.h	1998-07-18 11:55:25.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/mm-init.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmap.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/mmu.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/mmu.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/mmu.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/mmu.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,26 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmu.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- *
- * Changelog:
- *  20-10-1996	RMK	Created
- *  31-12-1997	RMK	Fixed definitions to reduce warnings
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-/*
- * On ebsa, the dram is contiguous
- */
-#define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
-#define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
-
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)	(x - 0xe0000000)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)	(x + 0xe0000000)
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/oldlatches.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/oldlatches.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/oldlatches.h	1998-07-18 11:55:25.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/oldlatches.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,9 +0,0 @@
-/*
- * Dummy oldlatches.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifdef __need_oldlatches
-#error "Old latches not present in this (rpc) machine"
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/param.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/param.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/param.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/param.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,8 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/param.h
- *
- * Copyright (C) 1996 Russell King
- * Copyright (C) 1998 Philip Blundell
- */
-
-#define HZ 100
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/processor.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/processor.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/processor.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/processor.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,31 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/processor.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
-
-#ifndef __ASM_ARCH_PROCESSOR_H
-#define __ASM_ARCH_PROCESSOR_H
-
-/*
- * Bus types
- */
-#define EISA_bus 0
-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
-/*
- * User space: 3GB
- */
-#define TASK_SIZE	(0xc0000000UL)
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
-
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/serial.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/serial.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/serial.h	1998-07-18 11:55:25.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/serial.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,43 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/serial.h
- *
- * Copyright (c) 1996 Russell King.
- *
- * Changelog:
- *  15-10-1996	RMK	Created
- *  03-05-1998	RMK	Modified for Corel Video NC
- */
-#ifndef __ASM_ARCH_SERIAL_H
-#define __ASM_ARCH_SERIAL_H
-
-#include <asm/irq.h>
-
-/*
- * This assumes you have a 1.8432 MHz clock for your UART.
- *
- * It'd be nice if someone built a serial card with a 24.576 MHz
- * clock, since the 16550A is capable of handling a top speed of 1.5
- * megabits/second; but this requires the faster clock.
- */
-#define BASE_BAUD (1843200 / 16)
-
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-     /* UART CLK        PORT  IRQ     FLAGS        */
-#define SERIAL_PORT_DFNS \
-	{ 0, BASE_BAUD, 0x3F8, IRQ_UART	, STD_COM_FLAGS },	/* ttyS0 */	\
-	{ 0, BASE_BAUD, 0x2F8, IRQ_UART2, STD_COM_FLAGS },	/* ttyS1 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS2 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS3 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0    , 0	, STD_COM_FLAGS },	/* ttyS13 */
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/shmparam.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/shmparam.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/shmparam.h	1998-07-18 11:55:25.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/shmparam.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/shmparam.h
- *
- * Copyright (c) 1996 Russell King.
- */
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/system.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/system.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/system.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/system.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,37 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/system.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- * Copyright (c) 1998 Corel Computer Corp.
- */
-#include <asm/hardware.h>
-#include <asm/dec21285.h>
-#include <asm/leds.h>
-#include <asm/io.h>
-
-extern __inline__ void arch_reset(char mode)
-{
-	cli();
-
-	/* open up the SuperIO chip
-	 */
-	outb(0x87, 0x370);
-	outb(0x87, 0x370);
-
-	/* aux function group 1 (Logical Device 7)
-	 */
-	outb(0x07, 0x370);
-	outb(0x07, 0x371);
-
-	/* set GP16 for WD-TIMER output
-	 */
-	outb(0xE6, 0x370);
-	outb(0x00, 0x371);
-
-	/* set a RED LED and toggle WD_TIMER for rebooting...
-	 */
-	outb(0xC4, 0x338);
-}
-
-#define arch_start_idle()	leds_event(led_idle_start)
-#define arch_end_idle()		leds_event(led_idle_end)
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/time.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/time.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/time.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/time.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,232 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/time.h
- *
- * Copyright (c) 1997 Corel Computer Corp.
- * Slight modifications to bring in line with ebsa285 port.
- *  -- Russell King.
- *  Added LED driver (based on the ebsa285 code) - Alex Holden 28/12/98.
- */
-
-#include <linux/config.h>
-#include <linux/mc146818rtc.h>
-
-#include <asm/leds.h>
-#include <asm/system.h>
-
-#undef IRQ_TIMER
-#define IRQ_TIMER		IRQ_TIMER4
-
-#define mSEC_10_from_14 ((14318180 + 100) / 200)
-
-extern __inline__ unsigned long gettimeoffset (void)
-{
-	int count;
-
-	static int count_p = (mSEC_10_from_14/6);    /* for the first call after boot */
-	static unsigned long jiffies_p = 0;
-
-	/*
-	 * cache volatile jiffies temporarily; we have IRQs turned off. 
-	 */
-	unsigned long jiffies_t;
-
-	/* timer count may underflow right here */
-	outb_p(0x00, 0x43);	/* latch the count ASAP */
-
-	count = inb_p(0x40);	/* read the latched count */
-
-	/*
-	 * We do this guaranteed double memory access instead of a _p 
-	 * postfix in the previous port access. Wheee, hackady hack
-	 */
- 	jiffies_t = jiffies;
-
-	count |= inb_p(0x40) << 8;
-
-	/* Detect timer underflows.  If we haven't had a timer tick since 
-	   the last time we were called, and time is apparently going
-	   backwards, the counter must have wrapped during this routine. */
-	if ((jiffies_t == jiffies_p) && (count > count_p))
-		count -= (mSEC_10_from_14/6);
-	else
-		jiffies_p = jiffies_t;
-
-	count_p = count;
-
-	count = (((mSEC_10_from_14/6)-1) - count) * tick;
-	count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
-
-	return count;
-}
-
-extern __inline__ int reset_timer (void)
-{
-#ifdef CONFIG_LEDS
-	static unsigned int count = 50;
-	static int last_pid;
-
-	if (current->pid != last_pid) {
-		last_pid = current->pid;
-		if (last_pid)
-			leds_event(led_idle_end);
-		else
-			leds_event(led_idle_start);
-	}
-
-	if (--count == 0) {
-		count = 50;
-		leds_event(led_timer);
-	}
-#endif
-	return 1;
-}
-
-unsigned long set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	unsigned char save_control, save_freq_select;
-
-	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-	cmos_minutes = CMOS_READ(RTC_MINUTES);
-	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-		BCD_TO_BIN(cmos_minutes);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-		real_minutes += 30;		/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-			BIN_TO_BCD(real_seconds);
-			BIN_TO_BCD(real_minutes);
-		}
-		CMOS_WRITE(real_seconds,RTC_SECONDS);
-		CMOS_WRITE(real_minutes,RTC_MINUTES);
-	} else
-		retval = -1;
-
-	/* The following flags have to be released exactly in this order,
-	 * otherwise the DS12887 (popular MC146818A clone with integrated
-	 * battery and quartz) will not reset the oscillator and will not
-	 * update precisely 500 ms later. You won't find this mentioned in
-	 * the Dallas Semiconductor data sheets, but who believes data
-	 * sheets anyway ...                           -- Markus Kuhn
-	 */
-	CMOS_WRITE(save_control, RTC_CONTROL);
-	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
-	return retval;
-}
-
-/*
- * We don't have a RTC to update!
- */
-extern __inline__ void update_rtc(void)
-{
-	static long last_rtc_update = 0;	/* last time the cmos clock got updated */
-
-	/* If we have an externally synchronized linux clock, then update
-	 * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
-	 * called as close as possible to 500 ms before the new second starts.
-	 */
-	if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
-	    xtime.tv_usec > 50000 - (tick >> 1) &&
-	    xtime.tv_usec < 50000 + (tick >> 1)) {
-		if (set_rtc_mmss(xtime.tv_sec) == 0)
-			last_rtc_update = xtime.tv_sec;
-		else
-			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
-	}
-}
-
-extern __inline__ unsigned long get_cmos_time(void)
-{
-	unsigned int year, mon, day, hour, min, sec;
-	int i;
-
-	// check to see if the RTC makes sense.....
-	if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0)
-		return mktime(1970, 1, 1, 0, 0, 0);
-
-	/* The Linux interpretation of the CMOS clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-	/* read RTC exactly on falling edge of update flag */
-	for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
-		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-			break;
-
-	for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
-		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-			break;
-
-	do { /* Isn't this overkill ? UIP above should guarantee consistency */
-		sec = CMOS_READ(RTC_SECONDS);
-		min = CMOS_READ(RTC_MINUTES);
-		hour = CMOS_READ(RTC_HOURS);
-		day = CMOS_READ(RTC_DAY_OF_MONTH);
-		mon = CMOS_READ(RTC_MONTH);
-		year = CMOS_READ(RTC_YEAR);
-	} while (sec != CMOS_READ(RTC_SECONDS));
-
-	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-		BCD_TO_BIN(sec);
-		BCD_TO_BIN(min);
-		BCD_TO_BIN(hour);
-		BCD_TO_BIN(day);
-		BCD_TO_BIN(mon);
-		BCD_TO_BIN(year);
-	}
-	if ((year += 1900) < 1970)
-		year += 100;
-	return mktime(year, mon, day, hour, min, sec);
-}
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-extern __inline__ unsigned long setup_timer (void)
-{
-	unsigned int c;
-
-	/* Turn on the RTC */
-	outb(13, 0x70);
-	if ((inb(0x71) & 0x80) == 0)
-		printk("RTC: *** warning: CMOS battery bad\n");
-
-	outb(10, 0x70);		/* select control reg */
-	outb(32, 0x71);		/* make sure the divider is set */
-	outb(11, 0x70);		/* select other control reg */
-	c = inb(0x71) & 0xfb;	/* read it */
-	outb(11, 0x70);
-	outb(c | 2, 0x71);	/* turn on BCD counting and 24 hour clock mode */
-	
-	/* enable PIT timer */
-	/* set for periodic (4) and LSB/MSB write (0x30) */
-	outb(0x34, 0x43);
-	outb((mSEC_10_from_14/6) & 0xFF, 0x40);
-	outb((mSEC_10_from_14/6) >> 8, 0x40);
-
-	/*
-	 * Default the date to 1 Jan 1970 00:00:00
-	 * You will have to run a time daemon to set the
-	 * clock correctly at bootup
-	 */
-	return get_cmos_time();
-}
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/timex.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/timex.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/timex.h	1998-07-18 11:55:25.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/timex.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,13 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/timex.h
- *
- * Corel Video NC architecture timex specifications
- *
- * Copyright (C) 1998 Corel Computer/Russell King
- */
-
-/*
- * On the VNC, the clock runs at 66MHz and is divided
- * by a 4-bit prescaler.
- */
-#define CLOCK_TICK_RATE		(66000000 / 16)
diff -urN linux-2.2.8-pre4/include/asm-arm/arch-vnc/uncompress.h linux-2.2.8-pre5/include/asm-arm/arch-vnc/uncompress.h
--- linux-2.2.8-pre4/include/asm-arm/arch-vnc/uncompress.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/arch-vnc/uncompress.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,34 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/uncompress.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
-
-/*
- * This does not append a newline
- */
-static void puts(const char *s)
-{
-	__asm__ __volatile__("
-	ldrb	%0, [%2], #1
-	teq	%0, #0
-	beq	3f
-1:	strb	%0, [%3]
-2:	ldrb	%1, [%3, #0x14]
-	and	%1, %1, #0x60
-	teq	%1, #0x60
-	bne	2b
-	teq	%0, #'\n'
-	moveq	%0, #'\r'
-	beq	1b
-	ldrb	%0, [%2], #1
-	teq	%0, #0
-	bne	1b
-3:	" : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc");
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
-#define arch_decomp_wdog()
diff -urN linux-2.2.8-pre4/include/asm-arm/dec21285.h linux-2.2.8-pre5/include/asm-arm/dec21285.h
--- linux-2.2.8-pre4/include/asm-arm/dec21285.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/dec21285.h	2003-08-15 15:06:10.000000000 -0700
@@ -15,17 +15,20 @@
 #define DC21285_PCI_MEM			0x80000000
 
 #ifndef __ASSEMBLY__
-#define DC21285_IO(x)		((volatile unsigned long *)(0xfe000000+(x)))
+#include <asm/arch/hardware.h>
+#define DC21285_IO(x)		((volatile unsigned long *)(ARMCSR_BASE+(x)))
 #else
 #define DC21285_IO(x)		(x)
 #endif
 
 #define CSR_PCICMD		DC21285_IO(0x0004)
+#define CSR_CLASSREV		DC21285_IO(0x0008)
 #define CSR_PCICACHELINESIZE	DC21285_IO(0x000c)
 #define CSR_PCICSRBASE		DC21285_IO(0x0010)
 #define CSR_PCICSRIOBASE	DC21285_IO(0x0014)
 #define CSR_PCISDRAMBASE	DC21285_IO(0x0018)
 #define CSR_PCIROMBASE		DC21285_IO(0x0030)
+#define CSR_ROMWRITEREG		DC21285_IO(0x0068)
 #define CSR_CSRBASEMASK		DC21285_IO(0x00f8)
 #define CSR_CSRBASEOFFSET	DC21285_IO(0x00fc)
 #define CSR_SDRAMBASEMASK	DC21285_IO(0x0100)
@@ -44,6 +47,33 @@
 #define CSR_I2O_OUTPOSTCOUNT	DC21285_IO(0x0134)
 #define CSR_I2O_INPOSTCOUNT	DC21285_IO(0x0138)
 #define CSR_SA110_CNTL		DC21285_IO(0x013c)
+#define SA110_CNTL_INITCMPLETE		(1 << 0)
+#define SA110_CNTL_ASSERTSERR		(1 << 1)
+#define SA110_CNTL_RXSERR		(1 << 3)
+#define SA110_CNTL_SA110DRAMPARITY	(1 << 4)
+#define SA110_CNTL_PCISDRAMPARITY	(1 << 5)
+#define SA110_CNTL_DMASDRAMPARITY	(1 << 6)
+#define SA110_CNTL_DISCARDTIMER		(1 << 8)
+#define SA110_CNTL_PCINRESET		(1 << 9)
+#define SA110_CNTL_I2O_256		(0 << 10)
+#define SA110_CNTL_I20_512		(1 << 10)
+#define SA110_CNTL_I2O_1024		(2 << 10)
+#define SA110_CNTL_I2O_2048		(3 << 10)
+#define SA110_CNTL_I2O_4096		(4 << 10)
+#define SA110_CNTL_I2O_8192		(5 << 10)
+#define SA110_CNTL_I2O_16384		(6 << 10)
+#define SA110_CNTL_I2O_32768		(7 << 10)
+#define SA110_CNTL_WATCHDOG		(1 << 13)
+#define SA110_CNTL_ROMWIDTH_UNDEF	(0 << 14)
+#define SA110_CNTL_ROMWIDTH_16		(1 << 14)
+#define SA110_CNTL_ROMWIDTH_32		(2 << 14)
+#define SA110_CNTL_ROMWIDTH_8		(3 << 14)
+#define SA110_CNTL_ROMACCESSTIME(x)	((x)<<16)
+#define SA110_CNTL_ROMBURSTTIME(x)	((x)<<20)
+#define SA110_CNTL_ROMTRISTATETIME(x)	((x)<<24)
+#define SA110_CNTL_XCSDIR(x)		((x)<<28)
+#define SA110_CNTL_PCICFN		(1 << 31)
+
 #define CSR_PCIADDR_EXTN	DC21285_IO(0x0140)
 #define CSR_PREFETCHMEMRANGE	DC21285_IO(0x0144)
 #define CSR_XBUS_CYCLE		DC21285_IO(0x0148)
diff -urN linux-2.2.8-pre4/include/asm-arm/dma.h linux-2.2.8-pre5/include/asm-arm/dma.h
--- linux-2.2.8-pre4/include/asm-arm/dma.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/dma.h	2003-08-15 15:06:10.000000000 -0700
@@ -6,20 +6,20 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <asm/irq.h>
-#include <asm/system.h>
 #include <asm/spinlock.h>
 #include <asm/arch/dma.h>
 
 /*
- * DMA modes - we have two, IN and OUT
+ * DMA modes
  */
 typedef unsigned int dmamode_t;
 
-#define DMA_MODE_MASK	1
+#define DMA_MODE_MASK	3
 
-#define DMA_MODE_READ	0
-#define DMA_MODE_WRITE	1
-#define DMA_AUTOINIT	2
+#define DMA_MODE_READ	 0
+#define DMA_MODE_WRITE	 1
+#define DMA_MODE_CASCADE 2
+#define DMA_AUTOINIT	 4
 
 typedef struct {
 	unsigned long address;
diff -urN linux-2.2.8-pre4/include/asm-arm/ecard.h linux-2.2.8-pre5/include/asm-arm/ecard.h
--- linux-2.2.8-pre4/include/asm-arm/ecard.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/ecard.h	2003-08-15 15:06:10.000000000 -0700
@@ -47,6 +47,9 @@
 #define MANU_ICS		0x003c
 #define PROD_ICS_IDE			0x00ae
 
+#define MANU_ICS2		0x003d
+#define PROD_ICS2_IDE			0x00ae
+
 #define MANU_SERPORT		0x003f
 #define PROD_SERPORT_DSPORT		0x00b9
 
@@ -76,7 +79,7 @@
 #define CONST const
 #endif
 
-#define MAX_ECARDS	8
+#define MAX_ECARDS	9
 
 typedef enum {				/* Cards address space		*/
 	ECARD_IOC,
@@ -116,14 +119,18 @@
 typedef struct {			/* Card handler routines	*/
 	void (*irqenable)(ecard_t *ec, int irqnr);
 	void (*irqdisable)(ecard_t *ec, int irqnr);
+	int  (*irqpending)(ecard_t *ec);
 	void (*fiqenable)(ecard_t *ec, int fiqnr);
 	void (*fiqdisable)(ecard_t *ec, int fiqnr);
+	int  (*fiqpending)(ecard_t *ec);
 } expansioncard_ops_t;
 
 /*
  * This contains all the info needed on an expansion card
  */
 struct expansion_card {
+	struct expansion_card  *next;
+
 	/* Public data */
 	volatile unsigned char *irqaddr;	/* address of IRQ register	*/
 	volatile unsigned char *fiqaddr;	/* address of FIQ register	*/
@@ -135,10 +142,10 @@
 	void			*fiq_data;	/* Data for use for FIQ by card	*/
 	expansioncard_ops_t	*ops;		/* Enable/Disable Ops for card	*/
 
-	CONST unsigned char	slot_no;	/* Slot number			*/
-	CONST unsigned char	dma;		/* DMA number (for request_dma)	*/
-	CONST unsigned char	irq;		/* IRQ number (for request_irq)	*/
-	CONST unsigned char	fiq;		/* FIQ number (for request_irq)	*/
+	CONST unsigned int	slot_no;	/* Slot number			*/
+	CONST unsigned int	dma;		/* DMA number (for request_dma)	*/
+	CONST unsigned int	irq;		/* IRQ number (for request_irq)	*/
+	CONST unsigned int	fiq;		/* FIQ number (for request_irq)	*/
 	CONST card_type_t	type;		/* Type of card			*/
 	CONST struct in_ecid	cid;		/* Card Identification		*/
 
diff -urN linux-2.2.8-pre4/include/asm-arm/fiq.h linux-2.2.8-pre5/include/asm-arm/fiq.h
--- linux-2.2.8-pre4/include/asm-arm/fiq.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/fiq.h	2003-08-15 15:06:10.000000000 -0700
@@ -30,5 +30,6 @@
 extern void release_fiq(struct fiq_handler *f);
 extern void set_fiq_handler(void *start, unsigned int length);
 extern void set_fiq_regs(struct pt_regs *regs);
+extern void get_fiq_regs(struct pt_regs *regs);
 
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/floppy.h linux-2.2.8-pre5/include/asm-arm/floppy.h
--- linux-2.2.8-pre4/include/asm-arm/floppy.h	1998-06-13 13:11:12.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/floppy.h	2003-08-15 15:06:10.000000000 -0700
@@ -120,5 +120,20 @@
 #define FLOPPY_MOTOR_MASK 0xf0
 
 #define CROSS_64KB(a,s) (0)
+
+/*
+ * This allows people to reverse the order of
+ * fd0 and fd1, in case their hardware is
+ * strangely connected (as some RiscPCs
+ * and A5000s seem to be).
+ */
+static void driveswap(int *ints, int dummy, int dummy2)
+{
+	floppy_selects[0][0] ^= floppy_selects[0][1];
+	floppy_selects[0][1] ^= floppy_selects[0][0];
+	floppy_selects[0][0] ^= floppy_selects[0][1];
+}
+
+#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 }
 	
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/hardware.h linux-2.2.8-pre5/include/asm-arm/hardware.h
--- linux-2.2.8-pre4/include/asm-arm/hardware.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/hardware.h	2003-08-15 15:06:10.000000000 -0700
@@ -11,10 +11,6 @@
 
 #include <asm/arch/hardware.h>
 
-#ifndef FLUSH_BASE
-#define FLUSH_BASE	0xdf000000
-#endif
-
 #ifdef HAS_EXPMASK
 #ifndef __ASSEMBLER__
 #define __EXPMASK(offset)	(((volatile unsigned char *)EXPMASK_BASE)[offset])
diff -urN linux-2.2.8-pre4/include/asm-arm/init.h linux-2.2.8-pre5/include/asm-arm/init.h
--- linux-2.2.8-pre4/include/asm-arm/init.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/init.h	2003-08-15 15:06:10.000000000 -0700
@@ -5,7 +5,7 @@
 
 /* C routines */
 
-#ifdef CONFIG_TEXT_INIT_SECTION
+#ifdef CONFIG_TEXT_SECTIONS
 
 #define __init __attribute__ ((__section__ (".text.init")))
 #define __initfunc(__arginit) \
diff -urN linux-2.2.8-pre4/include/asm-arm/ioc.h linux-2.2.8-pre5/include/asm-arm/ioc.h
--- linux-2.2.8-pre4/include/asm-arm/ioc.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/ioc.h	2003-08-15 15:06:10.000000000 -0700
@@ -3,6 +3,8 @@
  * read/write.
  */
 
+#ifndef IOC_CONTROL
+
 #ifndef __ASSEMBLER__
 #define __IOC(offset)	(IOC_BASE + (offset >> 2))
 #else
@@ -54,3 +56,4 @@
 #define IOC_T3GO	__IOC(0x78)
 #define IOC_T3LATCH	__IOC(0x7c)
 
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/io.h linux-2.2.8-pre5/include/asm-arm/io.h
--- linux-2.2.8-pre4/include/asm-arm/io.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/io.h	2003-08-15 15:06:10.000000000 -0700
@@ -8,12 +8,35 @@
  *			constant addresses and variable addresses.
  *  04-Dec-1997	RMK	Moved a lot of this stuff to the new architecture
  *			specific IO header files.
+ *  27-Mar-1999	PJB	Second parameter of memcpy_toio is const..
+ *  04-Apr-1999	PJB	Added check_signature.
  */
 #ifndef __ASM_ARM_IO_H
 #define __ASM_ARM_IO_H
 
+#ifdef __KERNEL__
+
+#ifndef NULL
+#define NULL	((void *) 0)
+#endif
+
+extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
+/*
+ * String version of IO memory access ops:
+ */
+extern void _memcpy_fromio(void *, unsigned long, unsigned long);
+extern void _memcpy_toio(unsigned long, const void *, unsigned long);
+extern void _memset_io(unsigned long, int, unsigned long);
+
+#define memcpy_fromio(to,from,len)	_memcpy_fromio((to),(unsigned long)(from),(len))
+#define memcpy_toio(to,from,len)	_memcpy_toio((unsigned long)(to),(from),(len))
+#define memset_io(addr,c,len)		_memset_io((unsigned long)(addr),(c),(len))
+
+#endif
+
 #include <asm/hardware.h>
-#include <asm/arch/mmu.h>
+#include <asm/arch/memory.h>
 #include <asm/arch/io.h>
 #include <asm/proc/io.h>
 
@@ -168,25 +191,43 @@
 
 #endif
 
-#undef ARCH_IO_DELAY
-#undef ARCH_IO_CONSTANT
+#ifndef ARCH_READWRITE
 
-#ifdef __KERNEL__
+/* for panic */
+#include <linux/kernel.h>
 
-extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+#define readb(p)	(panic("readb called, but not implemented"),0)
+#define readw(p)	(panic("readw called, but not implemented"),0)
+#define readl(p)	(panic("readl called, but not implemented"),0)
+#define writeb(v,p)	panic("writeb called, but not implemented")
+#define writew(v,p)	panic("writew called, but not implemented")
+#define writel(v,p)	panic("writel called, but not implemented")
 
-/*
- * String version of IO memory access ops:
- */
-extern void _memcpy_fromio(void *, unsigned long, unsigned long);
-extern void _memcpy_toio(unsigned long, void *, unsigned long);
-extern void _memset_io(unsigned long, int, unsigned long);
+#endif
 
-#define memcpy_fromio(to,from,len)	_memcpy_fromio((to),(unsigned long)(from),(len))
-#define memcpy_toio(to,from,len)	_memcpy_toio((unsigned long)(to),(from),(len))
-#define memset_io(addr,c,len)		_memset_io((unsigned long)(addr),(c),(len))
+/*
+ * This isn't especially architecture dependent so it seems like it
+ * might as well go here as anywhere.
+ */
+static inline int check_signature(unsigned long io_addr,
+                                  const unsigned char *signature, int length)
+{
+	int retval = 0;
+	do {
+		if (readb(io_addr) != *signature)
+			goto out;
+		io_addr++;
+		signature++;
+		length--;
+	} while (length);
+	retval = 1;
+out:
+	return retval;
+}
 
-#endif
+#undef ARCH_READWRITE
+#undef ARCH_IO_DELAY
+#undef ARCH_IO_CONSTANT
 
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/iomd.h linux-2.2.8-pre5/include/asm-arm/iomd.h
--- linux-2.2.8-pre4/include/asm-arm/iomd.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/iomd.h	2003-08-15 15:06:10.000000000 -0700
@@ -125,6 +125,8 @@
 #define DMA_ST_OFL	4
 #define DMA_ST_INT	2
 #define DMA_ST_AB	1
+
+#ifndef IOC_CONTROL
 /*
  * IOC compatability
  */
@@ -155,6 +157,7 @@
 #define IOC_T1LTCHH	IOMD_T1LTCHH
 #define IOC_T1GO	IOMD_T1GO
 #define IOC_T1LATCH	IOMD_T1LATCH
+#endif
 
 /*
  * DMA (MEMC) compatability
diff -urN linux-2.2.8-pre4/include/asm-arm/irq.h linux-2.2.8-pre5/include/asm-arm/irq.h
--- linux-2.2.8-pre4/include/asm-arm/irq.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/irq.h	2003-08-15 15:06:10.000000000 -0700
@@ -16,9 +16,11 @@
  * capability
  */
 #ifndef NO_IRQ
-#define NO_IRQ	255
+#define NO_IRQ	((unsigned int)(-1))
 #endif
 
+#define disable_irq_nosync(i) disable_irq(i)
+
 extern void disable_irq(unsigned int);
 extern void enable_irq(unsigned int);
 
diff -urN linux-2.2.8-pre4/include/asm-arm/leds.h linux-2.2.8-pre5/include/asm-arm/leds.h
--- linux-2.2.8-pre4/include/asm-arm/leds.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/leds.h	2003-08-15 15:06:10.000000000 -0700
@@ -10,15 +10,32 @@
 #ifndef ASM_ARM_LEDS_H
 #define ASM_ARM_LEDS_H
 
+#include <linux/config.h>
+
 typedef enum {
 	led_idle_start,
 	led_idle_end,
 	led_timer,
 	led_start,
-	led_stop
+	led_stop,
+	led_claim,		/* override idle & timer leds */
+	led_release,		/* restore idle & timer leds */
+	led_green_on,
+	led_green_off,
+	led_amber_on,
+	led_amber_off,
+	led_red_on,
+	led_red_off
 } led_event_t;
 
 /* Use this routine to handle LEDs */
-extern void leds_event(led_event_t);
+
+#ifdef CONFIG_LEDS
+extern void (*leds_event)(led_event_t);
+#define set_leds_event(r)	leds_event = r
+#else
+#define leds_event(e)
+#define set_leds_event(r)
+#endif
 
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/memc.h linux-2.2.8-pre5/include/asm-arm/memc.h
--- linux-2.2.8-pre4/include/asm-arm/memc.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/memc.h	2003-08-15 15:06:10.000000000 -0700
@@ -4,6 +4,9 @@
 #define VDMA_START	1
 #define VDMA_END	2
 
+#ifndef __ASSEMBLER__
+extern void memc_write(unsigned int reg, unsigned long val);
+
 #define video_set_dma(start,end,offset)				\
 do {								\
 	memc_write (VDMA_START, (start >> 2));			\
@@ -11,3 +14,4 @@
 	memc_write (VDMA_INIT, (offset >> 2));			\
 } while (0)
 
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/mm-init.h linux-2.2.8-pre5/include/asm-arm/mm-init.h
--- linux-2.2.8-pre4/include/asm-arm/mm-init.h	1998-01-20 16:39:42.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/mm-init.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,46 +0,0 @@
-/*
- * linux/include/asm-arm/mm-init.h
- *
- * Copyright (C) 1997,1998 Russell King
- *
- * Contained within are structures to describe how to set up the
- * initial memory map.  It includes both a processor-specific header
- * for parsing these structures, and an architecture-specific header
- * to fill out the structures.
- */
-#ifndef __ASM_MM_INIT_H
-#define __ASM_MM_INIT_H
-
-typedef enum {
-	// physical address is absolute
-	init_mem_map_absolute,
-	/* physical address is relative to start_mem
-	 *  as passed in paging_init
-	 */
-	init_mem_map_relative_start_mem
-} init_memmap_type_t;
-
-typedef struct {
-	init_memmap_type_t type;
-	unsigned long physical_address;
-	unsigned long virtual_address;
-	unsigned long size;
-} init_memmap_t;
-
-#define INIT_MEM_MAP_SENTINEL { init_mem_map_absolute, 0, 0, 0 }
-#define INIT_MEM_MAP_ABSOLUTE(p,l,s) { init_mem_map_absolute,p,l,s }
-#define INIT_MEM_MAP_RELATIVE(o,l,s) { init_mem_map_relative_start_mem,o,l,s }
-
-/*
- * Within this file, initialise an array of init_mem_map_t's
- * to describe your initial memory mapping structure.
- */
-#include <asm/arch/mm-init.h>
-
-/*
- * Contained within this file is code to read the array
- * of init_mem_map_t's created above.
- */
-#include <asm/proc/mm-init.h>
-
-#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/page.h linux-2.2.8-pre5/include/asm-arm/page.h
--- linux-2.2.8-pre4/include/asm-arm/page.h	1998-05-08 00:42:40.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/page.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,15 +1,15 @@
 #ifndef _ASMARM_PAGE_H
 #define _ASMARM_PAGE_H
 
-#include <asm/arch/mmu.h>
+#include <asm/arch/memory.h>
 #include <asm/proc/page.h>
 
 #ifdef __KERNEL__
 
 #define get_user_page(vaddr)		__get_free_page(GFP_KERNEL)
 #define free_user_page(page, addr)	free_page(addr)
-#define clear_page(page)	memzero((void *)(page), PAGE_SIZE)
-#define copy_page(to,from)	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+#define clear_page(page)		memzero((void *)(page), PAGE_SIZE)
+#define copy_page(to,from)		memcpy((void *)(to), (void *)(from), PAGE_SIZE)
 
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/posix_types.h linux-2.2.8-pre5/include/asm-arm/posix_types.h
--- linux-2.2.8-pre4/include/asm-arm/posix_types.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/posix_types.h	2003-08-15 15:06:10.000000000 -0700
@@ -45,6 +45,8 @@
 #endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
 } __kernel_fsid_t;
 
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
 #undef	__FD_SET
 #define __FD_SET(fd, fdsetp) \
 		(((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31)))
@@ -62,3 +64,5 @@
 		(memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp)))
 
 #endif
+
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armo/mm-init-flat.h linux-2.2.8-pre5/include/asm-arm/proc-armo/mm-init-flat.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armo/mm-init-flat.h	1998-01-20 16:39:42.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armo/mm-init-flat.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,82 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/mmap.h
- *
- * Copyright (C) 1996 Russell King
- *
- * This contains the code to setup the memory map on an ARM2/ARM250/ARM3
- * machine. This is both processor & architecture specific, and requires
- * some more work to get it to fit into our separate processor and
- * architecture structure.
- */
-
-static unsigned long phys_screen_end;
-int page_nr;
-
-#define setup_processor_functions()
-
-/*
- * This routine needs more work to make it dynamically release/allocate mem!
- */
-unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update)
-{
-	static int updated = 0;
-	unsigned long address = SCREEN_START, i;
-	pgd_t *pg_dir;
-	pmd_t *pm_dir;
-	pte_t *pt_entry;
-
-	if (updated)
-		return 0;
-	updated = update;
-
-	pg_dir = swapper_pg_dir + (SCREEN1_BASE >> PGDIR_SHIFT);
-	pm_dir = pmd_offset(pg_dir, SCREEN1_BASE);
-	pt_entry = pte_offset(pm_dir, SCREEN1_BASE);
-
-	for (i = SCREEN1_BASE; i < SCREEN1_END; i += PAGE_SIZE) {
-		if (i >= log_start) {
-			*pt_entry = mk_pte(address, __pgprot(_PAGE_PRESENT));
-			address += PAGE_SIZE;
-		} else
-			*pt_entry = mk_pte(0, __pgprot(0));
-		pt_entry++;
-	}
-	phys_screen_end = address;
-	if (update)
-		flush_tlb_all ();
-	return kmem;
-}
-
-static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem)
-{
-	unsigned long address;
-	unsigned int spi;
-
-	page_nr = MAP_NR(end_mem);
-
-	/* Allocate zero page */
-	address = PAGE_OFFSET + 480*1024;
-	for (spi = 0; spi < 32768 >> PAGE_SHIFT; spi++) {
-		pgd_val(swapper_pg_dir[spi]) = pte_val(mk_pte(address, PAGE_READONLY));
-		address += PAGE_SIZE;
-	}
-
-	while (spi < (PAGE_OFFSET >> PGDIR_SHIFT))
-		pgd_val(swapper_pg_dir[spi++]) = 0;
-
-	map_screen_mem (SCREEN1_END - 480*1024, 0, 0);
-	return start_mem;
-}
-
-static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem)
-{
-	unsigned long smem = PAGE_ALIGN(*start_mem);
-
-	while (smem < end_mem) {
-		clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
-		smem += PAGE_SIZE;
-	}
-
-	for (smem = phys_screen_end; smem < SCREEN2_END; smem += PAGE_SIZE)
-		clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
-}
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armo/mm-init.h linux-2.2.8-pre5/include/asm-arm/proc-armo/mm-init.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armo/mm-init.h	1998-05-08 00:42:40.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/proc-armo/mm-init.h	2003-08-15 15:06:10.000000000 -0700
@@ -8,8 +8,8 @@
  * some more work to get it to fit into our separate processor and
  * architecture structure.
  */
-extern unsigned long phys_screen_end;
-extern unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update);
+#include <asm/arch/memory.h>
+
 int page_nr;
 
 #define setup_processor_functions()
@@ -20,10 +20,11 @@
 	set_pmd (pmd_offset (swapper_pg_dir + index, 0), mk_pmd (ptep));
 }
 
-static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem)
+static inline unsigned long
+setup_pagetables(unsigned long start_mem, unsigned long end_mem)
 {
 	unsigned int i;
-	union {unsigned long l; pte_t *pte; } u;
+	union { unsigned long l; pte_t *pte; } u;
 
 	page_nr = MAP_NR(end_mem);
 
@@ -37,14 +38,11 @@
 	for (i = 1; i < PTRS_PER_PGD; i++)
 		pgd_val(swapper_pg_dir[i]) = 0;
 
-	/* now map screen mem in */
-	phys_screen_end = SCREEN2_END;
-	map_screen_mem (SCREEN1_END - 480*1024, 0, 0);
-
 	return start_mem;
 }
 
-static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem)
+static inline void
+mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem)
 {
 	unsigned long smem;
 
@@ -54,7 +52,4 @@
 		clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
 		smem += PAGE_SIZE;
 	}
-
-	for (smem = phys_screen_end; smem < SCREEN2_END; smem += PAGE_SIZE)
-		clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
 }
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armo/page.h linux-2.2.8-pre5/include/asm-arm/proc-armo/page.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armo/page.h	1998-05-08 00:42:40.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/proc-armo/page.h	2003-08-15 15:06:10.000000000 -0700
@@ -68,7 +68,6 @@
 #define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 /* This handles the memory map.. */
-#define PAGE_OFFSET		0x02000000
 #define MAP_NR(addr)		(((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
 
 #endif /* __KERNEL__ */
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armo/pgtable-flat.h linux-2.2.8-pre5/include/asm-arm/proc-armo/pgtable-flat.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armo/pgtable-flat.h	1998-01-20 16:39:42.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armo/pgtable-flat.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,307 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/pgtable.h
- *
- * Copyright (C) 1995, 1996 Russell King
- */
-#ifndef __ASM_PROC_PGTABLE_H
-#define __ASM_PROC_PGTABLE_H
-
-#include <asm/arch/mmu.h>
-
-#define LIBRARY_TEXT_START 0x0c000000
-
-/*
- * Cache flushing...
- */
-#define flush_cache_all()			do { } while (0)
-#define flush_cache_mm(mm)			do { } while (0)
-#define flush_cache_range(mm,start,end)		do { } while (0)
-#define flush_cache_page(vma,vmaddr)		do { } while (0)
-#define flush_page_to_ram(page)			do { } while (0)
-
-/*
- * TLB flushing:
- *
- *  - flush_tlb() flushes the current mm struct TLBs
- *  - flush_tlb_all() flushes all processes TLBs
- *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
- *  - flush_tlb_page(vma, vmaddr) flushes one page
- *  - flush_tlb_range(mm, start, end) flushes a range of pages
- */
-
-#define flush_tlb() flush_tlb_mm(current->mm)
-
-extern __inline__ void flush_tlb_all(void)
-{
-	struct task_struct *p;
-
-	p = &init_task;
-	do {
-		processor.u.armv2._update_map(p);
-		p = p->next_task;
-	} while (p != &init_task);
-
-	processor.u.armv2._remap_memc (current);
-}
-
-extern __inline__ void flush_tlb_mm(struct mm_struct *mm)
-{
-	struct task_struct *p;
-
-	p = &init_task;
-	do {
-		if (p->mm == mm)
-			processor.u.armv2._update_map(p);
-		p = p->next_task;
-	} while (p != &init_task);
-
-	if (current->mm == mm)
-		processor.u.armv2._remap_memc (current);
-}
-
-#define flush_tlb_range(mm, start, end) flush_tlb_mm(mm)
-#define flush_tlb_page(vma, vmaddr) flush_tlb_mm(vma->vm_mm)
-
-#define __flush_entry_to_ram(entry)
-
-/* Certain architectures need to do special things when pte's
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
-#define PMD_SHIFT       PAGE_SHIFT
-#define PMD_SIZE        (1UL << PMD_SHIFT)
-#define PMD_MASK        (~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT     PAGE_SHIFT
-#define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK      (~(PGDIR_SIZE-1))
-
-/*
- * entries per page directory level: the arm3 is one-level, so
- * we don't really have any PMD or PTE directory physically.
- */
-#define PTRS_PER_PTE    1
-#define PTRS_PER_PMD    1
-#define PTRS_PER_PGD    1024
-
-/* Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 8MB value just means that there will be a 8MB "hole" after the
- * physical memory until the kernel virtual memory starts.  That means that
- * any out-of-bounds memory accesses will hopefully be caught.
- * The vmalloc() routines leaves a hole of 4kB between each vmalloced
- * area for the same reason. ;)
- */
-#define VMALLOC_START	0x01a00000
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-
-#define _PAGE_PRESENT   0x001
-#define _PAGE_RW        0x002
-#define _PAGE_USER      0x004
-#define _PAGE_PCD       0x010
-#define _PAGE_ACCESSED  0x020
-#define _PAGE_DIRTY     0x040
-
-#define _PAGE_TABLE     (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
-#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
-
-#define PAGE_NONE       __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_KERNEL     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
-
-/*
- * The arm can't do page protection for execute, and considers that the same are read.
- * Also, write permissions imply read permissions. This is the closest we can get..
- */
-#define __P000  PAGE_NONE
-#define __P001  PAGE_READONLY
-#define __P010  PAGE_COPY
-#define __P011  PAGE_COPY
-#define __P100  PAGE_READONLY
-#define __P101  PAGE_READONLY
-#define __P110  PAGE_COPY
-#define __P111  PAGE_COPY
-
-#define __S000  PAGE_NONE
-#define __S001  PAGE_READONLY
-#define __S010  PAGE_SHARED
-#define __S011  PAGE_SHARED
-#define __S100  PAGE_READONLY
-#define __S101  PAGE_READONLY
-#define __S110  PAGE_SHARED
-#define __S111  PAGE_SHARED
-
-#undef TEST_VERIFY_AREA
-
-/*
- * BAD_PAGE is used for a bogus page.
- *
- * ZERO_PAGE is a global shared page that is always zero: used
- * for zero-mapped memory areas etc..
- */
-extern pte_t __bad_page(void);
-extern unsigned long *empty_zero_page;
-
-#define BAD_PAGE __bad_page()
-#define ZERO_PAGE ((unsigned long) empty_zero_page)
-
-/* number of bits that fit into a memory pointer */
-#define BYTES_PER_PTR			(sizeof(unsigned long))
-#define BITS_PER_PTR                    (8*BYTES_PER_PTR)
-
-/* to align the pointer to a pointer address */
-#define PTR_MASK                        (~(sizeof(void*)-1))
-
-/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
-#define SIZEOF_PTR_LOG2                 2
-
-/* to find an entry in a page-table */
-#define PAGE_PTR(address) \
-((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-
-/* to set the page-dir */
-#define SET_PAGE_DIR(tsk,pgdir)						\
-do {									\
-	tsk->tss.memmap = (unsigned long)pgdir;				\
-	processor.u.armv2._update_map(tsk);				\
-	if ((tsk) == current)						\
-		processor.u.armv2._remap_memc (current);		\
-} while (0)
-
-extern unsigned long physical_start;
-extern unsigned long physical_end;
-
-extern inline int pte_none(pte_t pte)           { return !pte_val(pte); }
-extern inline int pte_present(pte_t pte)        { return pte_val(pte) & _PAGE_PRESENT; }
-extern inline void pte_clear(pte_t *ptep)       { pte_val(*ptep) = 0; }
-
-extern inline int pmd_none(pmd_t pmd)           { return 0; }
-extern inline int pmd_bad(pmd_t pmd)            { return 0; }
-extern inline int pmd_present(pmd_t pmd)        { return 1; }
-extern inline void pmd_clear(pmd_t * pmdp)      { }
-
-/*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-extern inline int pgd_none(pgd_t pgd)           { return 0; }
-extern inline int pgd_bad(pgd_t pgd)            { return 0; }
-extern inline int pgd_present(pgd_t pgd)        { return 1; }
-extern inline void pgd_clear(pgd_t * pgdp)      { }
-
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-extern inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
-extern inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_RW; }
-extern inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
-extern inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_DIRTY; }
-extern inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
-#define pte_cacheable(pte) 1
-
-extern inline pte_t pte_nocache(pte_t pte)	{ return pte; }
-extern inline pte_t pte_wrprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_RW; return pte; }
-extern inline pte_t pte_rdprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
-extern inline pte_t pte_exprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
-extern inline pte_t pte_mkclean(pte_t pte)      { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkold(pte_t pte)        { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte)      { pte_val(pte) |= _PAGE_RW; return pte; }
-extern inline pte_t pte_mkread(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
-extern inline pte_t pte_mkexec(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte)      { pte_val(pte) |= _PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte)      { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = virt_to_phys(page) | pgprot_val(pgprot); return pte; }
-
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
-
-extern inline unsigned long pte_page(pte_t pte)
-{ return phys_to_virt(pte_val(pte) & PAGE_MASK); }
-
-extern inline unsigned long pmd_page(pmd_t pmd)
-{ return phys_to_virt(pmd_val(pmd) & PAGE_MASK); }
-
-/* to find an entry in a page-table-directory */
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
-{
-        return mm->pgd + (address >> PGDIR_SHIFT);
-}
-
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, address) ((pmd_t *)(dir))
-
-/* Find an entry in the third-level page table.. */
-#define pte_offset(dir, address) ((pte_t *)(dir))
-
-/*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
- */
-extern inline void pte_free_kernel(pte_t * pte)
-{
-	pte_val(*pte) = 0;
-}
-
-extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address)
-{
-	return (pte_t *) pmd;
-}
-
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-#define pmd_free_kernel(pmdp)
-#define pmd_alloc_kernel(pgd,address) ((pmd_t *)(pgd))
-
-#define pte_free(ptep)
-#define pte_alloc(pmd,address) ((pte_t *)(pmd))
-
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-#define pmd_free(pmd)
-#define pmd_alloc(pgd,address) ((pmd_t *)(pgd))
-
-extern inline void pgd_free(pgd_t * pgd)
-{
-	extern void kfree(void *);
-	kfree((void *)pgd);
-}
-
-extern inline pgd_t * pgd_alloc(void)
-{
-	pgd_t *pgd;
-	extern void *kmalloc(unsigned int, int);
-	
-	pgd = (pgd_t *) kmalloc(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL);
-	if (pgd)
-		memset(pgd, 0, PTRS_PER_PGD * BYTES_PER_PTR);
-	return pgd;
-}
-
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
-#define update_mmu_cache(vma,address,pte) processor.u.armv2._update_mmu_cache(vma,address,pte)
-
-#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
-#define SWP_OFFSET(entry) ((entry) >> 8)
-#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) <<  8))
-
-#endif /* __ASM_PROC_PAGE_H */
-
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armo/pgtable.h linux-2.2.8-pre5/include/asm-arm/proc-armo/pgtable.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armo/pgtable.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armo/pgtable.h	2003-08-15 15:06:10.000000000 -0700
@@ -7,9 +7,9 @@
 #ifndef __ASM_PROC_PGTABLE_H
 #define __ASM_PROC_PGTABLE_H
 
-#include <asm/arch/mmu.h>
+#include <linux/config.h>
 #include <linux/slab.h>
-#include <asm/arch/processor.h>		/* For TASK_SIZE */
+#include <asm/arch/memory.h>		/* For TASK_SIZE */
 
 #define LIBRARY_TEXT_START 0x0c000000
 
@@ -280,13 +280,17 @@
 	return __phys_to_virt(pte_val(pte) & PAGE_MASK);
 }
 
-extern __inline__ pmd_t mk_pmd (pte_t *ptep)
+extern __inline__ pmd_t mk_pmd(pte_t *ptep)
 {
 	pmd_t pmd;
 	pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_TABLE;
 	return pmd;
 }
 
+/* these are aliases for the above function */
+#define mk_user_pmd(ptep)   mk_pmd(ptep)
+#define mk_kernel_pmd(ptep) mk_pmd(ptep)
+
 #define set_pmd(pmdp,pmd) ((*(pmdp)) = (pmd))
 
 extern __inline__ unsigned long pmd_page(pmd_t pmd)
@@ -319,6 +323,7 @@
  */
 
 #ifndef __SMP__
+#ifndef CONFIG_NO_PGT_CACHE
 extern struct pgtable_cache_struct {
 	unsigned long *pgd_cache;
 	unsigned long *pte_cache;
@@ -329,13 +334,16 @@
 #define pte_quicklist (quicklists.pte_cache)
 #define pgd_quicklist (quicklists.pgd_cache)
 #define pgtable_cache_size (quicklists.pgtable_cache_sz)
+#endif
 
 #else
 #error Pgtable caches have to be per-CPU, so that no locking is needed.
 #endif
 
 extern pgd_t *get_pgd_slow(void);
+extern void free_table(void *table);
 
+#ifndef CONFIG_NO_PGT_CACHE
 extern __inline__ pgd_t *get_pgd_fast(void)
 {
 	unsigned long *ret;
@@ -355,14 +363,17 @@
 	pgd_quicklist = (unsigned long *) pgd;
 	pgtable_cache_size++;
 }
+#endif
 
+/* keep this as an inline so we get type checking */
 extern __inline__ void free_pgd_slow(pgd_t *pgd)
 {
-	kfree(pgd);
+	free_table((void *)pgd);
 }
 
 extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
 
+#ifndef CONFIG_NO_PGT_CACHE
 extern __inline__ pte_t *get_pte_fast(void)
 {
 	unsigned long *ret;
@@ -381,10 +392,12 @@
 	pte_quicklist = (unsigned long *) pte;
 	pgtable_cache_size++;
 }
+#endif
 
+/* keep this as an inline so we get type checking */
 extern __inline__ void free_pte_slow(pte_t *pte)
 {
-	kfree(pte);
+	free_table((void *)pte);
 }
 
 /* We don't use pmd cache, so this is a dummy routine */
@@ -404,6 +417,26 @@
 extern void __bad_pmd(pmd_t *pmd);
 extern void __bad_pmd_kernel(pmd_t *pmd);
 
+#ifdef CONFIG_NO_PGT_CACHE
+#define pte_free_kernel(pte)    free_pte_slow(pte)
+#define pte_free(pte)           free_pte_slow(pte)
+#define pgd_free(pgd)           free_pgd_slow(pgd)
+#define pgd_alloc()             get_pgd_slow()
+
+extern __inline__ pte_t *pte_alloc(pmd_t * pmd, unsigned long address)
+{
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+
+	if (pmd_none (*pmd)) {
+		return get_pte_slow(pmd, address);
+	}
+	if (pmd_bad (*pmd)) {
+		__bad_pmd(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+#else
 #define pte_free_kernel(pte)    free_pte_fast(pte)
 #define pte_free(pte)           free_pte_fast(pte)
 #define pgd_free(pgd)           free_pgd_fast(pgd)
@@ -427,6 +460,7 @@
 	}
 	return (pte_t *) pmd_page(*pmd) + address;
 }
+#endif
 
 /*
  * allocating and freeing a pmd is trivial: the 1-entry pmd is
@@ -448,7 +482,6 @@
 extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
 {
 	struct task_struct * p;
-	pgd_t *pgd;
 
 	read_lock(&tasklist_lock);
 	for_each_task(p) {
@@ -457,8 +490,14 @@
 		*pgd_offset(p->mm,address) = entry;
 	}
 	read_unlock(&tasklist_lock);
-	for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-		pgd[address >> PGDIR_SHIFT] = entry;
+#ifndef CONFIG_NO_PGT_CACHE
+	{
+		pgd_t *pgd;
+		for (pgd = (pgd_t *)pgd_quicklist; pgd;
+		     pgd = (pgd_t *)*(unsigned long *)pgd)
+			pgd[address >> PGDIR_SHIFT] = entry;
+	}
+#endif
 }
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armo/processor.h linux-2.2.8-pre5/include/asm-arm/proc-armo/processor.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armo/processor.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armo/processor.h	2003-08-15 15:06:10.000000000 -0700
@@ -14,8 +14,6 @@
 #ifndef __ASM_PROC_PROCESSOR_H
 #define __ASM_PROC_PROCESSOR_H
 
-#ifdef __KERNEL__
-
 #include <asm/assembler.h>
 #include <linux/string.h>
 
@@ -32,6 +30,8 @@
 	unsigned long pc;
 };
 
+#define INIT_CSS (struct context_save_struct){ 0, 0, 0, 0, 0, 0, 0, SVC26_MODE }
+
 typedef struct {
 	void (*put_byte)(void);			/* Special calling convention */
 	void (*get_byte)(void);			/* Special calling convention */
@@ -50,50 +50,13 @@
 
 #define EXTRA_THREAD_STRUCT							\
 	uaccess_t	*uaccess;		/* User access functions*/	\
-	struct context_save_struct *save;					\
-	unsigned long	memmap;							\
 	unsigned long	memcmap[256];
 
 #define EXTRA_THREAD_STRUCT_INIT		\
-	&uaccess_kernel,			\
-	0,					\
-	(unsigned long) swapper_pg_dir,		\
+	,&uaccess_kernel,			\
 	{ 0, }
 
-DECLARE_THREAD_STRUCT;
-
-/*
- * Return saved PC of a blocked thread.
- */
-extern __inline__ unsigned long thread_saved_pc (struct thread_struct *t)
-{
-	if (t->save)
-		return t->save->pc & ~PCMASK;
-	else
-		return 0;
-}
-
-extern __inline__ unsigned long get_css_fp (struct thread_struct *t)
-{
-	if (t->save)
-		return t->save->fp;
-	else
-		return 0;
-}
-
-asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
-
-extern __inline__ void copy_thread_css (struct context_save_struct *save)
-{
-	save->r4 =
-	save->r5 =
-	save->r6 =
-	save->r7 =
-	save->r8 =
-	save->r9 =
-	save->fp = 0;
-	save->pc = ((unsigned long)ret_from_sys_call) | SVC26_MODE;
-}
+#define SWAPPER_PG_DIR ((unsigned long)swapper_pg_dir)
 
 #define start_thread(regs,pc,sp)					\
 ({									\
@@ -105,18 +68,16 @@
 	regs->ARM_r2 = stack[2];	/* r2 (envp) */			\
 	regs->ARM_r1 = stack[1];	/* r1 (argv) */			\
 	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\
-	flush_tlb_mm(current->mm);					\
 })
 
 /* Allocation and freeing of basic task resources. */
 /*
  * NOTE! The task struct and the stack go together
  */
-#define alloc_task_struct() \
-	((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
-#define free_task_struct(p)    free_pages((unsigned long)(p),1)
-
+extern unsigned long get_page_8k(int priority);
+extern void free_page_8k(unsigned long page);
 
-#endif
+#define ll_alloc_task_struct()	((struct task_struct *)get_page_8k(GFP_KERNEL))
+#define ll_free_task_struct(p)  free_page_8k((unsigned long)(p))
 
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armo/ptrace.h linux-2.2.8-pre5/include/asm-arm/proc-armo/ptrace.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armo/ptrace.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/proc-armo/ptrace.h	2003-08-15 15:06:10.000000000 -0700
@@ -68,8 +68,13 @@
 /* Are the current registers suitable for user mode?
  * (used to maintain security in signal handlers)
  */
-#define valid_user_regs(regs) \
-	(user_mode(regs) && ((regs)->ARM_sp & 3) == 0)
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+	if (!user_mode(regs) || regs->ARM_pc & (F_BIT | I_BIT))
+		return 1;
+
+	return 0;
+}
 
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armo/semaphore.h linux-2.2.8-pre5/include/asm-arm/proc-armo/semaphore.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armo/semaphore.h	1998-01-20 16:39:42.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armo/semaphore.h	2003-08-15 15:06:10.000000000 -0700
@@ -13,17 +13,19 @@
 	__asm__ __volatile__ ("
 	@ atomic down operation
 	mov	r0, pc
-	orr	r1, r0, #0x08000000
+	orr	lr, r0, #0x08000000
 	and	r0, r0, #0x0c000003
-	teqp	r1, #0
-	ldr	r1, [%0]
-	subs	r1, r1, #1
-	str	r1, [%0]
-	mov	r1, pc, lsr #28
-	teqp	r0, r1, lsl #28
+	teqp	lr, #0
+	ldr	lr, [%0]
+	subs	lr, lr, #1
+	str	lr, [%0]
+	mov	lr, pc, lsr #28
+	teqp	r0, lr, lsl #28
 	movmi	r0, %0
-	blmi	" SYMBOL_NAME_STR(__down)
-		: : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc");
+	blmi	" SYMBOL_NAME_STR(__down_failed)
+		:
+		: "r" (sem)
+		: "r0", "lr", "cc");
 }
 
 /*
@@ -36,22 +38,47 @@
 	__asm__ __volatile__ ("
 	@ atomic down operation
 	mov	r0, pc
-	orr	r1, r0, #0x08000000
+	orr	lr, r0, #0x08000000
 	and	r0, r0, #0x0c000003
-	teqp	r1, #0
-	ldr	r1, [%1]
-	subs	r1, r1, #1
-	str	r1, [%1]
-	mov	r1, pc, lsr #28
+	teqp	lr, #0
+	ldr	lr, [%1]
+	subs	lr, lr, #1
+	str	lr, [%1]
+	mov	lr, pc, lsr #28
 	orrmi	r0, r0, #0x80000000	@ set N
-	teqp	r0, r1, lsl #28
+	teqp	r0, lr, lsl #28
 	movmi	r0, %1
 	movpl	r0, #0
-	blmi	" SYMBOL_NAME_STR(__down_interruptible) "
+	blmi	" SYMBOL_NAME_STR(__down_interruptible_failed) "
 	mov	%0, r0"
 		: "=r" (result)
 		: "r" (sem)
-		: "r0", "r1", "r2", "r3", "ip", "lr", "cc");
+		: "r0", "lr", "cc");
+	return result;
+}
+
+extern inline int down_trylock(struct semaphore * sem)
+{
+	int result;
+	__asm__ __volatile__ ("
+	@ atomic down operation
+	mov	r0, pc
+	orr	lr, r0, #0x08000000
+	and	r0, r0, #0x0c000003
+	teqp	lr, #0
+	ldr	lr, [%1]
+	subs	lr, lr, #1
+	str	lr, [%1]
+	mov	lr, pc, lsr #28
+	orrmi	r0, r0, #0x80000000	@ set N
+	teqp	r0, lr, lsl #28
+	movmi	r0, %1
+	movpl	r0, #0
+	blmi	" SYMBOL_NAME_STR(__down_trylock_failed) "
+	mov	%0, r0"
+		: "=r" (result)
+		: "r" (sem)
+		: "r0", "lr", "cc");
 	return result;
 }
 
@@ -66,18 +93,20 @@
 	__asm__ __volatile__ ("
 	@ atomic up operation
 	mov	r0, pc
-	orr	r1, r0, #0x08000000
+	orr	lr, r0, #0x08000000
 	and	r0, r0, #0x0c000003
-	teqp	r1, #0
-	ldr	r1, [%0]
-	adds	r1, r1, #1
-	str	r1, [%0]
-	mov	r1, pc, lsr #28
+	teqp	lr, #0
+	ldr	lr, [%0]
+	adds	lr, lr, #1
+	str	lr, [%0]
+	mov	lr, pc, lsr #28
 	orrls	r0, r0, #0x80000000	@ set N
-	teqp	r0, r1, lsl #28
+	teqp	r0, lr, lsl #28
 	movmi	r0, %0
-	blmi	" SYMBOL_NAME_STR(__up)
-		: : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc");
+	blmi	" SYMBOL_NAME_STR(__up_wakeup)
+		:
+		: "r" (sem)
+		: "r0", "lr", "cc");
 }
 
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armv/io.h linux-2.2.8-pre5/include/asm-arm/proc-armv/io.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armv/io.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armv/io.h	2003-08-15 15:06:10.000000000 -0700
@@ -22,17 +22,14 @@
 
 #include <asm/proc-fns.h>
 
-extern inline void dma_cache_inv(unsigned long start, unsigned long size)
-{
-	processor.u.armv3v4._cache_purge_area(start, start + size);
-}
+#define dma_cache_inv(start, size)					    \
+	do { processor.u.armv3v4._cache_purge_area((unsigned long)(start),  \
+		((unsigned long)(start)+(size))); } while (0)
 
-extern inline void dma_cache_wback(unsigned long start, unsigned long size)
-{
-	processor.u.armv3v4._cache_wback_area(start, start + size);
-}
+#define dma_cache_wback(start, size)					    \
+	do { processor.u.armv3v4._cache_wback_area((unsigned long)(start),  \
+		((unsigned long)(start)+(size))); } while (0)
 
-extern inline void dma_cache_wback_inv(unsigned long start, unsigned long size)
-{
-	processor.u.armv3v4._flush_cache_area(start, start + size, 0);
-}
+#define dma_cache_wback_inv(start, size)				    \
+	do { processor.u.armv3v4._flush_cache_area((unsigned long)(start),  \
+		((unsigned long)(start)+(size)), 0); } while (0)
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armv/mm-init.h linux-2.2.8-pre5/include/asm-arm/proc-armv/mm-init.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armv/mm-init.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armv/mm-init.h	2003-08-15 15:06:10.000000000 -0700
@@ -37,7 +37,7 @@
  */
 #include <asm/pgtable.h>
  
-#define PTE_SIZE (PTRS_PER_PTE * 4)
+#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR)
 
 extern unsigned long setup_io_pagetables(unsigned long start_mem);
 
@@ -79,7 +79,7 @@
 alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot)
 {
 	pgd_t *pgdp;
-	pmd_t *pmdp, pmd;
+	pmd_t *pmdp;
 	pte_t *ptep;
 
 	pgdp = pgd_offset_k(virt);
@@ -92,46 +92,41 @@
 
 		ptep = (pte_t *)memory;
 		memzero(ptep, PTE_SIZE);
+		memory += PTE_SIZE;
 
-		pmd_val(pmd) = __virt_to_phys(memory) | PMD_TYPE_TABLE | PMD_DOMAIN(domain);
-		set_pmd(pmdp, pmd);
+		ptep = (pte_t *)memory;
+		memzero(ptep, PTE_SIZE);
+
+		set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain)));
 
 		*mem = memory + PTE_SIZE;
 	}
 
 	ptep = pte_offset(pmdp, virt);
 
-	pte_val(*ptep) = phys | prot | PTE_TYPE_SMALL;
+	set_pte(ptep, mk_pte_phys(phys, __pgprot(prot)));
 }
 
 static inline unsigned long
 setup_pagetables(unsigned long start_mem, unsigned long end_mem)
 {
-	unsigned long address;
+	unsigned long address = 0;
 
-	/*
-	 * map in zero page
-	 */
-	alloc_init_page(&start_mem, 0, __virt_to_phys(PAGE_OFFSET), DOMAIN_USER, PTE_CACHEABLE);
-
-	/*
-	 * ensure no mappings in user space
-	 */
-	for (address = PGDIR_SIZE; address < PAGE_OFFSET; address += PGDIR_SIZE)
-		free_init_section(address);
-
-	/*
-	 * map in physical ram & kernel
-	 */
-	for (address = PAGE_OFFSET; address < end_mem; address += PGDIR_SIZE)
-		alloc_init_section(&start_mem, address, __virt_to_phys(address), DOMAIN_KERNEL,
-				   PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE | PMD_SECT_AP_WRITE);
+	do {
+		if (address >= PAGE_OFFSET && address < end_mem)
+			/*
+			 * map in physical ram & kernel
+			 */
+			alloc_init_section(&start_mem, address, __virt_to_phys(address), DOMAIN_KERNEL,
+					   PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE | PMD_SECT_AP_WRITE);
+		else
+			/*
+			 * unmap everything else
+			 */
+			free_init_section(address);
 
-	/*
-	 * unmap everything else
-	 */
-	for (address = end_mem; address; address += PGDIR_SIZE)
-		free_init_section(address);
+		address += PGDIR_SIZE;
+	} while (address != 0);
 
 	/*
 	 * An area to invalidate the cache
@@ -144,6 +139,12 @@
 	 */
 	start_mem = setup_io_pagetables(start_mem);
 
+	/*
+	 * map in zero page
+	 */
+	alloc_init_page(&start_mem, 0, __virt_to_phys(PAGE_OFFSET),
+			DOMAIN_USER, L_PTE_CACHEABLE | L_PTE_YOUNG | L_PTE_PRESENT);
+
 	flush_cache_all();
 
 	return start_mem;
@@ -156,9 +157,21 @@
 
 	*start_mem = smem = PAGE_ALIGN(*start_mem);
 
+	/*
+	 * Mark all of memory from the end of kernel to end of memory
+	 */
 	while (smem < end_mem) {
-	    	clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
-    		smem += PAGE_SIZE;
+		clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
+		smem += PAGE_SIZE;
+	}
+
+	/*
+	 * Mark memory from page 1 to start of the swapper page directory
+	 */
+	smem = PAGE_OFFSET + PAGE_SIZE;
+	while (smem < (unsigned long)&swapper_pg_dir) {
+		clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
+		smem += PAGE_SIZE;
 	}
 }	
 
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armv/pgtable.h linux-2.2.8-pre5/include/asm-arm/proc-armv/pgtable.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armv/pgtable.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/proc-armv/pgtable.h	2003-08-15 15:06:10.000000000 -0700
@@ -3,14 +3,15 @@
  *
  * Copyright (C) 1995, 1996, 1997 Russell King
  *
- * 12-01-1997	RMK	Altered flushing routines to use function pointers
+ * 12-Jan-1997	RMK	Altered flushing routines to use function pointers
  *			now possible to combine ARM6, ARM7 and StrongARM versions.
+ * 17-Apr-1999	RMK	Now pass an area size to clean_cache_area and
+ *			flush_icache_area.
  */
 #ifndef __ASM_PROC_PGTABLE_H
 #define __ASM_PROC_PGTABLE_H
 
-#include <asm/arch/mmu.h>
-#include <asm/arch/processor.h>		/* For TASK_SIZE */
+#include <asm/arch/memory.h>		/* For TASK_SIZE */
 
 #define LIBRARY_TEXT_START 0x0c000000
 
@@ -41,8 +42,23 @@
 				 ((_vma)->vm_flags & VM_EXEC) ? 1 : 0);	\
 	} while (0)
 
+#define clean_cache_range(_start,_end)					\
+	do {								\
+		unsigned long _s, _sz;					\
+		_s = (unsigned long)_start;				\
+		_sz = (unsigned long)_end - _s;				\
+		processor.u.armv3v4._clean_cache_area(_s, _sz);		\
+	} while (0)
+
+#define clean_cache_area(_start,_size)					\
+	do {								\
+		unsigned long _s;					\
+		_s = (unsigned long)_start;				\
+		processor.u.armv3v4._clean_cache_area(_s, _size);	\
+	} while (0)
+
 #define flush_icache_range(_start,_end)					\
-	processor.u.armv3v4._flush_icache_area((_start), (_end))
+	processor.u.armv3v4._flush_icache_area((_start), (_end) - (_start))
 
 /*
  * We don't have a MEMC chip...
@@ -60,12 +76,6 @@
 	processor.u.armv3v4._flush_ram_page ((_page) & PAGE_MASK);
 
 /*
- * Make the page uncacheable (must flush page beforehand).
- */
-#define uncache_page(_page)						\
-	processor.u.armv3v4._flush_ram_page ((_page) & PAGE_MASK);
-
-/*
  * TLB flushing:
  *
  *  - flush_tlb() flushes the current mm struct TLBs
@@ -106,22 +116,15 @@
 	} while (0)
 
 /*
- * Since the page tables are in cached memory, we need to flush the dirty
- * data cached entries back before we flush the tlb...  This is also useful
- * to flush out the SWI instruction for signal handlers...
+ * PMD_SHIFT determines the size of the area a second-level page table can map
  */
-#define __flush_entry_to_ram(entry)						\
-	processor.u.armv3v4._flush_cache_entry((unsigned long)(entry))
-
-#define __flush_pte_to_ram(entry)						\
-	processor.u.armv3v4._flush_cache_pte((unsigned long)(entry))
-
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
 #define PMD_SHIFT       20
 #define PMD_SIZE        (1UL << PMD_SHIFT)
 #define PMD_MASK        (~(PMD_SIZE-1))
 
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
+/*
+ * PGDIR_SHIFT determines what a third-level page table entry can map
+ */
 #define PGDIR_SHIFT     20
 #define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
 #define PGDIR_MASK      (~(PGDIR_SIZE-1))
@@ -135,6 +138,7 @@
 #define PTRS_PER_PGD    4096
 #define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
 
+
 /* Just any arbitrary offset to the start of the vmalloc VM area: the
  * current 8MB value just means that there will be a 8MB "hole" after the
  * physical memory until the kernel virtual memory starts.  That means that
@@ -147,87 +151,28 @@
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
 #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
 
-/* PMD types (actually level 1 descriptor) */
-#define PMD_TYPE_MASK		0x0003
-#define PMD_TYPE_FAULT		0x0000
-#define PMD_TYPE_TABLE		0x0001
-#define PMD_TYPE_SECT		0x0002
-#define PMD_UPDATABLE		0x0010
-#define PMD_SECT_CACHEABLE	0x0008
-#define PMD_SECT_BUFFERABLE	0x0004
-#define PMD_SECT_AP_WRITE	0x0400
-#define PMD_SECT_AP_READ	0x0800
-#define PMD_DOMAIN(x)		((x) << 5)
-
-/* PTE types (actially level 2 descriptor) */
-#define PTE_TYPE_MASK	0x0003
-#define PTE_TYPE_FAULT	0x0000
-#define PTE_TYPE_LARGE	0x0001
-#define PTE_TYPE_SMALL	0x0002
-#define PTE_AP_READ	0x0aa0
-#define PTE_AP_WRITE	0x0550
-#define PTE_CACHEABLE	0x0008
-#define PTE_BUFFERABLE	0x0004
 
-/* Domains */
+/*
+ * Domains
+ */
 #define DOMAIN_USER	0
 #define DOMAIN_KERNEL	1
 #define DOMAIN_TABLE	1
 #define DOMAIN_IO	2
 
-#define _PAGE_CHG_MASK  (0xfffff00c | PTE_TYPE_MASK)
 
-/*
- * We define the bits in the page tables as follows:
- *  PTE_BUFFERABLE	page is dirty
- *  PTE_AP_WRITE	page is writable
- *  PTE_AP_READ		page is a young (unsetting this causes faults for any access)
- *  PTE_CACHEABLE       page is readable
- *
- * A page will not be made writable without the dirty bit set.
- * It is not legal to have a writable non-dirty page though (it breaks).
- *
- * A readable page is marked as being cacheable.
- * Youngness is indicated by hardware read.  If the page is old,
- * then we will fault and make the page young again.
- */
-#define _PTE_YOUNG	PTE_AP_READ
-#define _PTE_DIRTY	PTE_BUFFERABLE
-#define _PTE_READ	PTE_CACHEABLE
-#define _PTE_WRITE	PTE_AP_WRITE
-
-#define PAGE_NONE       __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG)
-#define PAGE_SHARED     __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ | _PTE_WRITE)
-#define PAGE_COPY       __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ)
-#define PAGE_READONLY   __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ)
-#define PAGE_KERNEL     __pgprot(PTE_TYPE_SMALL | _PTE_READ  | _PTE_DIRTY | _PTE_WRITE)
 
-#define _PAGE_USER_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER))
-#define _PAGE_KERNEL_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL))
+#undef TEST_VERIFY_AREA
 
 /*
- * The arm can't do page protection for execute, and considers that the same are read.
- * Also, write permissions imply read permissions. This is the closest we can get..
+ * The sa110 doesn't have any external MMU info: the kernel page
+ * tables contain all the necessary information.
  */
-#define __P000  PAGE_NONE
-#define __P001  PAGE_READONLY
-#define __P010  PAGE_COPY
-#define __P011  PAGE_COPY
-#define __P100  PAGE_READONLY
-#define __P101  PAGE_READONLY
-#define __P110  PAGE_COPY
-#define __P111  PAGE_COPY
-
-#define __S000  PAGE_NONE
-#define __S001  PAGE_READONLY
-#define __S010  PAGE_SHARED
-#define __S011  PAGE_SHARED
-#define __S100  PAGE_READONLY
-#define __S101  PAGE_READONLY
-#define __S110  PAGE_SHARED
-#define __S111  PAGE_SHARED
+extern __inline__ void update_mmu_cache(struct vm_area_struct * vma,
+	unsigned long address, pte_t pte)
+{
+}
 
-#undef TEST_VERIFY_AREA
 
 /*
  * BAD_PAGETABLE is used when we need a bogus page-table, while
@@ -240,97 +185,40 @@
 extern pte_t * __bad_pagetable(void);
 extern unsigned long *empty_zero_page;
 
-#define BAD_PAGETABLE __bad_pagetable()
-#define BAD_PAGE __bad_page()
-#define ZERO_PAGE ((unsigned long) empty_zero_page)
+#define BAD_PAGETABLE	__bad_pagetable()
+#define BAD_PAGE	__bad_page()
+#define ZERO_PAGE	((unsigned long) empty_zero_page)
 
 /* number of bits that fit into a memory pointer */
-#define BYTES_PER_PTR			(sizeof(unsigned long))
-#define BITS_PER_PTR                    (8*BYTES_PER_PTR)
+#define BYTES_PER_PTR	(sizeof(unsigned long))
+#define BITS_PER_PTR	(8*BYTES_PER_PTR)
 
 /* to align the pointer to a pointer address */
-#define PTR_MASK                        (~(sizeof(void*)-1))
+#define PTR_MASK	(~(sizeof(void*)-1))
 
 /* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
-#define SIZEOF_PTR_LOG2                 2
+#define SIZEOF_PTR_LOG2	2
 
 /* to find an entry in a page-table */
 #define PAGE_PTR(address) \
 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
 
-/* to set the page-dir */
+/* to set the page-dir
+ * Note that we need to flush the cache and TLBs
+ * if we are affecting the current task.
+ */
 #define SET_PAGE_DIR(tsk,pgdir)					\
 do {								\
 	tsk->tss.memmap = __virt_to_phys((unsigned long)pgdir);	\
-	if ((tsk) == current)					\
+	if ((tsk) == current) {					\
+		flush_cache_all();				\
 		__asm__ __volatile__(				\
 		"mcr%?	p15, 0, %0, c2, c0, 0\n"		\
 		: : "r" (tsk->tss.memmap));			\
+		flush_tlb_all();				\
+	}							\
 } while (0)
 
-extern __inline__ int pte_none(pte_t pte)
-{
-	return !pte_val(pte);
-}
-
-#define pte_clear(ptep)	set_pte(ptep, __pte(0))
-
-extern __inline__ int pte_present(pte_t pte)
-{
-#if 0
-	/* This is what it really does, the else
-	   part is just to make it easier for the compiler */
-	switch (pte_val(pte) & PTE_TYPE_MASK) {
-	case PTE_TYPE_LARGE:
-	case PTE_TYPE_SMALL:
-		return 1;
-	default:
-		return 0;
-	}
-#else
-	return ((pte_val(pte) + 1) & 2);
-#endif
-}
-
-extern __inline__ int pmd_none(pmd_t pmd)
-{
-	return !pmd_val(pmd);
-}
-
-#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0))
-
-extern __inline__ int pmd_bad(pmd_t pmd)
-{
-#if 0
-	/* This is what it really does, the else
-	   part is just to make it easier for the compiler */
-	switch (pmd_val(pmd) & PMD_TYPE_MASK) {
-	case PMD_TYPE_FAULT:
-	case PMD_TYPE_TABLE:
-		return 0;
-	default:
-		return 1;
-	}
-#else
-	return pmd_val(pmd) & 2;
-#endif
-}
-
-extern __inline__ int pmd_present(pmd_t pmd)
-{
-#if 0
-	/* This is what it really does, the else
-	   part is just to make it easier for the compiler */
-	switch (pmd_val(pmd) & PMD_TYPE_MASK) {
-	case PMD_TYPE_TABLE:
-		return 1;
-	default:
-		return 0;
-	}
-#else
-	return ((pmd_val(pmd) + 1) & 2);
-#endif
-}
 
 /*
  * The "pgd_xxx()" functions here are trivial for a folded two-level
@@ -342,231 +230,224 @@
 #define pgd_present(pgd)	(1)
 #define pgd_clear(pgdp)
 
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-#define pte_read(pte)		(1)
-#define pte_exec(pte)		(1)
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-extern __inline__ int pte_write(pte_t pte)
+/* to find an entry in a page-table-directory */
+extern __inline__ pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
 {
-	return pte_val(pte) & _PTE_WRITE;
+	return mm->pgd + (address >> PGDIR_SHIFT);
 }
 
-extern __inline__ int pte_dirty(pte_t pte)
-{
-	return pte_val(pte) & _PTE_DIRTY;
-}
+extern unsigned long get_page_2k(int priority);
+extern void free_page_2k(unsigned long page);
 
-extern __inline__ int pte_young(pte_t pte)
-{
-	return pte_val(pte) & _PTE_YOUNG;
-}
+/*
+ * Allocate and free page tables. The xxx_kernel() versions are
+ * used to allocate a kernel page table - this turns on ASN bits
+ * if any.
+ */
 
-extern __inline__ pte_t pte_wrprotect(pte_t pte)
-{
-	pte_val(pte) &= ~_PTE_WRITE;
-	return pte;
-}
+#ifndef __SMP__
+extern struct pgtable_cache_struct {
+	unsigned long *pgd_cache;
+	unsigned long *pte_cache;
+	unsigned long pgtable_cache_sz;
+} quicklists;
 
-extern __inline__ pte_t pte_nocache(pte_t pte)
-{
-	pte_val(pte) &= ~PTE_CACHEABLE;
-	return pte;
-}
+#define pgd_quicklist (quicklists.pgd_cache)
+#define pmd_quicklist ((unsigned long *)0)
+#define pte_quicklist (quicklists.pte_cache)
+#define pgtable_cache_size (quicklists.pgtable_cache_sz)
+#else
+#error Pgtable caches have to be per-CPU, so that no locking is needed.
+#endif
 
-extern __inline__ pte_t pte_mkclean(pte_t pte)
-{
-	pte_val(pte) &= ~_PTE_DIRTY;
-	return pte;
-}
+extern pgd_t *get_pgd_slow(void);
 
-extern __inline__ pte_t pte_mkold(pte_t pte)
+extern __inline__ pgd_t *get_pgd_fast(void)
 {
-	pte_val(pte) &= ~_PTE_YOUNG;
-	return pte;
+	unsigned long *ret;
+
+	if((ret = pgd_quicklist) != NULL) {
+		pgd_quicklist = (unsigned long *)(*ret);
+		ret[0] = ret[1];
+		clean_cache_area(ret, 4);
+		pgtable_cache_size--;
+	} else
+		ret = (unsigned long *)get_pgd_slow();
+	return (pgd_t *)ret;
 }
 
-extern __inline__ pte_t pte_mkwrite(pte_t pte)
+extern __inline__ void free_pgd_fast(pgd_t *pgd)
 {
-	pte_val(pte) |= _PTE_WRITE;
-	return pte;
+	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+	pgd_quicklist = (unsigned long *) pgd;
+	pgtable_cache_size++;
 }
 
-extern __inline__ pte_t pte_mkdirty(pte_t pte)
+extern __inline__ void free_pgd_slow(pgd_t *pgd)
 {
-	pte_val(pte) |= _PTE_DIRTY;
-	return pte;
+	free_pages((unsigned long) pgd, 2);
 }
 
-extern __inline__ pte_t pte_mkyoung(pte_t pte)
+#define pgd_free(pgd)		free_pgd_fast(pgd)
+#define pgd_alloc()		get_pgd_fast()
+
+extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
 {
-	pte_val(pte) |= _PTE_YOUNG;
-	return pte;
+	struct task_struct * p;
+	pgd_t *pgd;
+
+	read_lock(&tasklist_lock);
+	for_each_task(p) {
+		if (!p->mm)
+			continue;
+		*pgd_offset(p->mm,address) = entry;
+	}
+	read_unlock(&tasklist_lock);
+	for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+		pgd[address >> PGDIR_SHIFT] = entry;
 }
 
-/*
- * The following are unable to be implemented on this MMU
- */
-#if 0
-extern __inline__ pte_t pte_rdprotect(pte_t pte)
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+/****************
+* PMD functions *
+****************/
+
+/* PMD types (actually level 1 descriptor) */
+#define PMD_TYPE_MASK		0x0003
+#define PMD_TYPE_FAULT		0x0000
+#define PMD_TYPE_TABLE		0x0001
+#define PMD_TYPE_SECT		0x0002
+#define PMD_UPDATABLE		0x0010
+#define PMD_SECT_CACHEABLE	0x0008
+#define PMD_SECT_BUFFERABLE	0x0004
+#define PMD_SECT_AP_WRITE	0x0400
+#define PMD_SECT_AP_READ	0x0800
+#define PMD_DOMAIN(x)		((x) << 5)
+
+#define _PAGE_USER_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER))
+#define _PAGE_KERNEL_TABLE	(PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL))
+
+#define pmd_none(pmd)		(!pmd_val(pmd))
+#define pmd_clear(pmdp)		set_pmd(pmdp, __pmd(0))
+#define pmd_bad(pmd)		(pmd_val(pmd) & 2)
+#define mk_user_pmd(ptep)	__mk_pmd(ptep, _PAGE_USER_TABLE)
+#define mk_kernel_pmd(ptep)	__mk_pmd(ptep, _PAGE_KERNEL_TABLE)
+#define set_pmd(pmdp,pmd)	processor.u.armv3v4._set_pmd(pmdp,pmd)
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(dir, address) ((pmd_t *)(dir))
+
+extern __inline__ int pmd_present(pmd_t pmd)
 {
-	pte_val(pte) &= ~(PTE_CACHEABLE|PTE_AP_READ);
-	return pte;
+	return ((pmd_val(pmd) + 1) & 2);
 }
 
-extern __inline__ pte_t pte_exprotect(pte_t pte)
+/* We don't use pmd cache, so this is a dummy routine */
+extern __inline__ pmd_t *get_pmd_fast(void)
 {
-	pte_val(pte) &= ~(PTE_CACHEABLE|PTE_AP_READ);
-	return pte;
+	return (pmd_t *)0;
 }
 
-extern __inline__ pte_t pte_mkread(pte_t pte)
+extern __inline__ void free_pmd_fast(pmd_t *pmd)
 {
-	pte_val(pte) |= PTE_CACHEABLE;
-	return pte;
 }
 
-extern __inline__ pte_t pte_mkexec(pte_t pte)
+extern __inline__ void free_pmd_slow(pmd_t *pmd)
 {
-	pte_val(pte) |= PTE_CACHEABLE;
-	return pte;
 }
-#endif
+
+extern void __bad_pmd(pmd_t *pmd);
+extern void __bad_pmd_kernel(pmd_t *pmd);
 
 /*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
  */
-extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot)
+extern __inline__ void pmd_free(pmd_t *pmd)
 {
-	pte_t pte;
-	pte_val(pte) = __virt_to_phys(page) | pgprot_val(pgprot);
-	return pte;
 }
 
-/* This takes a physical page address that is used by the remapping functions */
-extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
+extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
 {
-	pte_t pte;
-	pte_val(pte) = physpage + pgprot_val(pgprot);
-	return pte;
+	return (pmd_t *) pgd;
 }
 
-extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{
-	pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
-	return pte;
-}
+#define pmd_free_kernel		pmd_free
+#define pmd_alloc_kernel	pmd_alloc
 
-extern __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
+extern __inline__ pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
 {
-	*pteptr = pteval;
-	__flush_pte_to_ram(pteptr);
-}
+	unsigned long pte_ptr = (unsigned long)ptep;
+	pmd_t pmd;
 
-extern __inline__ unsigned long pte_page(pte_t pte)
-{
-	return __phys_to_virt(pte_val(pte) & PAGE_MASK);
-}
+	pte_ptr -= PTRS_PER_PTE * BYTES_PER_PTR;
 
-extern __inline__ pmd_t mk_user_pmd(pte_t *ptep)
-{
-	pmd_t pmd;
-	pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_USER_TABLE;
-	return pmd;
-}
+	/*
+	 * The pmd must be loaded with the physical
+	 * address of the PTE table
+	 */
+	pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot;
 
-extern __inline__ pmd_t mk_kernel_pmd(pte_t *ptep)
-{
-	pmd_t pmd;
-	pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_KERNEL_TABLE;
 	return pmd;
 }
 
-#if 1
-#define set_pmd(pmdp,pmd) processor.u.armv3v4._set_pmd(pmdp,pmd)
-#else
-extern __inline__ void set_pmd(pmd_t *pmdp, pmd_t pmd)
-{
-	*pmdp = pmd;
-	__flush_pte_to_ram(pmdp);
-}
-#endif
-
 extern __inline__ unsigned long pmd_page(pmd_t pmd)
 {
-	return __phys_to_virt(pmd_val(pmd) & 0xfffffc00);
-}
-
-/* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+	unsigned long ptr;
 
-/* to find an entry in a page-table-directory */
-extern __inline__ pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
-{
-	return mm->pgd + (address >> PGDIR_SHIFT);
-}
+	ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * BYTES_PER_PTR - 1);
 
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, address) ((pmd_t *)(dir))
+	ptr += PTRS_PER_PTE * BYTES_PER_PTR;
 
-/* Find an entry in the third-level page table.. */
-extern __inline__ pte_t * pte_offset(pmd_t * dir, unsigned long address)
-{
-	return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+	return __phys_to_virt(ptr);
 }
 
-extern unsigned long get_small_page(int priority);
-extern void free_small_page(unsigned long page);
 
-/*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
- */
-
-#ifndef __SMP__
-extern struct pgtable_cache_struct {
-	unsigned long *pgd_cache;
-	unsigned long *pte_cache;
-	unsigned long pgtable_cache_sz;
-} quicklists;
+/****************
+* PTE functions *
+****************/
 
-#define pgd_quicklist (quicklists.pgd_cache)
-#define pmd_quicklist ((unsigned long *)0)
-#define pte_quicklist (quicklists.pte_cache)
-#define pgtable_cache_size (quicklists.pgtable_cache_sz)
-#else
-#error Pgtable caches have to be per-CPU, so that no locking is needed.
-#endif
+/* PTE types (actially level 2 descriptor) */
+#define PTE_TYPE_MASK		0x0003
+#define PTE_TYPE_FAULT		0x0000
+#define PTE_TYPE_LARGE		0x0001
+#define PTE_TYPE_SMALL		0x0002
+#define PTE_AP_READ		0x0aa0
+#define PTE_AP_WRITE		0x0550
+#define PTE_CACHEABLE		0x0008
+#define PTE_BUFFERABLE		0x0004
 
-extern pgd_t *get_pgd_slow(void);
+#define pte_none(pte)		(!pte_val(pte))
+#define pte_clear(ptep)		set_pte(ptep, __pte(0))
 
-extern __inline__ pgd_t *get_pgd_fast(void)
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot)
 {
-	unsigned long *ret;
-
-	if((ret = pgd_quicklist) != NULL) {
-		pgd_quicklist = (unsigned long *)(*ret);
-		ret[0] = ret[1];
-		pgtable_cache_size--;
-	} else
-		ret = (unsigned long *)get_pgd_slow();
-	return (pgd_t *)ret;
+	pte_t pte;
+	pte_val(pte) = __virt_to_phys(page) | pgprot_val(pgprot);
+	return pte;
 }
 
-extern __inline__ void free_pgd_fast(pgd_t *pgd)
+/* This takes a physical page address that is used by the remapping functions */
+extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
 {
-	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
-	pgd_quicklist = (unsigned long *) pgd;
-	pgtable_cache_size++;
+	pte_t pte;
+	pte_val(pte) = physpage + pgprot_val(pgprot);
+	return pte;
 }
 
-extern __inline__ void free_pgd_slow(pgd_t *pgd)
+#define set_pte(ptep, pte)	processor.u.armv3v4._set_pte(ptep,pte)
+
+extern __inline__ unsigned long pte_page(pte_t pte)
 {
-	free_pages((unsigned long) pgd, 2);
+	return __phys_to_virt(pte_val(pte) & PAGE_MASK);
 }
 
 extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
@@ -579,6 +460,7 @@
 	if((ret = (unsigned long *)pte_quicklist) != NULL) {
 		pte_quicklist = (unsigned long *)(*ret);
 		ret[0] = ret[1];
+		clean_cache_area(ret, 4);
 		pgtable_cache_size--;
 	}
 	return (pte_t *)ret;
@@ -593,31 +475,124 @@
 
 extern __inline__ void free_pte_slow(pte_t *pte)
 {
-	free_small_page((unsigned long)pte);
+	free_page_2k((unsigned long)(pte - PTRS_PER_PTE));
 }
 
-/* We don't use pmd cache, so this is a dummy routine */
-extern __inline__ pmd_t *get_pmd_fast(void)
-{
-	return (pmd_t *)0;
-}
+#define pte_free_kernel(pte)	free_pte_fast(pte)
+#define pte_free(pte)		free_pte_fast(pte)
 
-extern __inline__ void free_pmd_fast(pmd_t *pmd)
+/*###############################################################################
+ * New PageTableEntry stuff...
+ */
+/* We now keep two sets of ptes - the physical and the linux version.
+ * This gives us many advantages, and allows us greater flexibility.
+ *
+ * The Linux pte's contain:
+ *  bit   meaning
+ *   0    page present
+ *   1    young
+ *   2    bufferable	- matches physical pte
+ *   3    cacheable	- matches physical pte
+ *   4    user
+ *   5    write
+ *   6    execute
+ *   7    dirty
+ *  8-11  unused
+ *  12-31 virtual page address
+ *
+ * These are stored at the pte pointer; the physical PTE is at -1024bytes
+ */
+#define L_PTE_PRESENT		(1 << 0)
+#define L_PTE_YOUNG		(1 << 1)
+#define L_PTE_BUFFERABLE	(1 << 2)
+#define L_PTE_CACHEABLE		(1 << 3)
+#define L_PTE_USER		(1 << 4)
+#define L_PTE_WRITE		(1 << 5)
+#define L_PTE_EXEC		(1 << 6)
+#define L_PTE_DIRTY		(1 << 7)
+
+/*
+ * The following macros handle the cache and bufferable bits...
+ */
+#define _L_PTE_DEFAULT	L_PTE_PRESENT | L_PTE_YOUNG
+#define _L_PTE_READ	L_PTE_USER | L_PTE_CACHEABLE
+#define _L_PTE_EXEC	_L_PTE_READ | L_PTE_EXEC
+
+#define PAGE_NONE       __pgprot(_L_PTE_DEFAULT)
+#define PAGE_COPY       __pgprot(_L_PTE_DEFAULT | _L_PTE_READ  | L_PTE_BUFFERABLE)
+#define PAGE_SHARED     __pgprot(_L_PTE_DEFAULT | _L_PTE_READ  | L_PTE_BUFFERABLE | L_PTE_WRITE)
+#define PAGE_READONLY   __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_KERNEL     __pgprot(_L_PTE_DEFAULT | L_PTE_CACHEABLE | L_PTE_BUFFERABLE | L_PTE_DIRTY | L_PTE_WRITE)
+
+#define _PAGE_CHG_MASK		(PAGE_MASK | L_PTE_DIRTY | L_PTE_YOUNG)
+
+/*
+ * The table below defines the page protection levels that we insert into our
+ * Linux page table version.  These get translated into the best that the
+ * architecture can perform.  Note that on most ARM hardware:
+ *  1) We cannot do execute protection
+ *  2) If we could do execute protection, then read is implied
+ *  3) write implies read permissions
+ */
+#define __P000  PAGE_NONE
+#define __P001  PAGE_READONLY
+#define __P010  PAGE_COPY
+#define __P011  PAGE_COPY
+#define __P100  PAGE_READONLY
+#define __P101  PAGE_READONLY
+#define __P110  PAGE_COPY
+#define __P111  PAGE_COPY
+
+#define __S000  PAGE_NONE
+#define __S001  PAGE_READONLY
+#define __S010  PAGE_SHARED
+#define __S011  PAGE_SHARED
+#define __S100  PAGE_READONLY
+#define __S101  PAGE_READONLY
+#define __S110  PAGE_SHARED
+#define __S111  PAGE_SHARED
+
+
+
+#define pte_present(pte)	(pte_val(pte) & L_PTE_PRESENT)
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+#define pte_read(pte)			(pte_val(pte) & L_PTE_USER)
+#define pte_write(pte)			(pte_val(pte) & L_PTE_WRITE)
+#define pte_exec(pte)			(pte_val(pte) & L_PTE_EXEC)
+#define pte_dirty(pte)			(pte_val(pte) & L_PTE_DIRTY)
+#define pte_young(pte)			(pte_val(pte) & L_PTE_YOUNG)
+
+#define PTE_BIT_FUNC(fn,op)			\
+extern inline pte_t fn##(pte_t pte) { pte_val(pte) op##; return pte; }
+
+//PTE_BIT_FUNC(pte_rdprotect, &= ~L_PTE_USER);
+PTE_BIT_FUNC(pte_wrprotect, &= ~L_PTE_WRITE);
+PTE_BIT_FUNC(pte_exprotect, &= ~L_PTE_EXEC);
+PTE_BIT_FUNC(pte_mkclean,   &= ~L_PTE_DIRTY);
+PTE_BIT_FUNC(pte_mkold,     &= ~L_PTE_YOUNG);
+//PTE_BIT_FUNC(pte_mkread,    |= L_PTE_USER);
+PTE_BIT_FUNC(pte_mkwrite,   |= L_PTE_WRITE);
+PTE_BIT_FUNC(pte_mkexec,    |= L_PTE_EXEC);
+PTE_BIT_FUNC(pte_mkdirty,   |= L_PTE_DIRTY);
+PTE_BIT_FUNC(pte_mkyoung,   |= L_PTE_YOUNG);
+PTE_BIT_FUNC(pte_nocache,   &= ~L_PTE_CACHEABLE);
+
+extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
+	pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+	return pte;
 }
 
-extern __inline__ void free_pmd_slow(pmd_t *pmd)
+/* Find an entry in the third-level page table.. */
+extern __inline__ pte_t * pte_offset(pmd_t * dir, unsigned long address)
 {
+	return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
-extern void __bad_pmd(pmd_t *pmd);
-extern void __bad_pmd_kernel(pmd_t *pmd);
-
-#define pte_free_kernel(pte)	free_pte_fast(pte)
-#define pte_free(pte)		free_pte_fast(pte)
-#define pgd_free(pgd)		free_pgd_fast(pgd)
-#define pgd_alloc()		get_pgd_fast()
-
 extern __inline__ pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address)
 {
 	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
@@ -655,49 +630,6 @@
 	return (pte_t *) pmd_page(*pmd) + address;
 }
 
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-extern __inline__ void pmd_free(pmd_t *pmd)
-{
-}
-
-extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
-{
-	return (pmd_t *) pgd;
-}
-
-#define pmd_free_kernel		pmd_free
-#define pmd_alloc_kernel	pmd_alloc
-
-extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
-{
-	struct task_struct * p;
-	pgd_t *pgd;
-
-	read_lock(&tasklist_lock);
-	for_each_task(p) {
-		if (!p->mm)
-			continue;
-		*pgd_offset(p->mm,address) = entry;
-	}
-	read_unlock(&tasklist_lock);
-	for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-		pgd[address >> PGDIR_SHIFT] = entry;
-}
-
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
-/*
- * The sa110 doesn't have any external MMU info: the kernel page
- * tables contain all the necessary information.
- */
-extern __inline__ void update_mmu_cache(struct vm_area_struct * vma,
-	unsigned long address, pte_t pte)
-{
-}
-
 #define SWP_TYPE(entry) (((entry) >> 2) & 0x7f)
 #define SWP_OFFSET(entry) ((entry) >> 9)
 #define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9))
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armv/processor.h linux-2.2.8-pre5/include/asm-arm/proc-armv/processor.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armv/processor.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armv/processor.h	2003-08-15 15:06:10.000000000 -0700
@@ -12,8 +12,6 @@
 #ifndef __ASM_PROC_PROCESSOR_H
 #define __ASM_PROC_PROCESSOR_H
 
-#ifdef __KERNEL__
- 
 #define KERNEL_STACK_SIZE	PAGE_SIZE
 
 struct context_save_struct {
@@ -28,56 +26,18 @@
 	unsigned long pc;
 };
 
-#define EXTRA_THREAD_STRUCT				\
-	struct context_save_struct *save;		\
-	unsigned long memmap;
-
-#define EXTRA_THREAD_STRUCT_INIT			\
-	0,						\
-	((unsigned long) swapper_pg_dir) - PAGE_OFFSET
+#define INIT_CSS (struct context_save_struct){ SVC_MODE, 0, 0, 0, 0, 0, 0, 0, 0 }
 
-DECLARE_THREAD_STRUCT;
-
-/*
- * Return saved PC of a blocked thread.
- */
-extern __inline__ unsigned long thread_saved_pc (struct thread_struct *t)
-{
-	if (t->save)
-		return t->save->pc;
-	else
-		return 0;
-}
-
-extern __inline__ unsigned long get_css_fp (struct thread_struct *t)
-{
-	if (t->save)
-		return t->save->fp;
-	else
-		return 0;
-}
-
-asmlinkage void ret_from_sys_call(void) __asm__ ("ret_from_sys_call");
-
-extern __inline__ void copy_thread_css (struct context_save_struct *save)
-{
-	save->cpsr = SVC_MODE;
-	save->r4 =
-	save->r5 =
-	save->r6 =
-	save->r7 =
-	save->r8 =
-	save->r9 =
-	save->fp = 0;
-	save->pc = (unsigned long) ret_from_sys_call;
-}
+#define EXTRA_THREAD_STRUCT
+#define EXTRA_THREAD_STRUCT_INIT
+#define SWAPPER_PG_DIR	(((unsigned long)swapper_pg_dir) - PAGE_OFFSET)
 
 #define start_thread(regs,pc,sp)					\
 ({									\
 	unsigned long *stack = (unsigned long *)sp;			\
 	set_fs(USER_DS);						\
 	memzero(regs->uregs, sizeof(regs->uregs));			\
-	if (current->personality == PER_LINUX_32BIT)			\
+	if (current->personality & ADDR_LIMIT_32BIT)			\
 		regs->ARM_cpsr = USR_MODE;				\
 	else								\
 		regs->ARM_cpsr = USR26_MODE;				\
@@ -92,10 +52,7 @@
 /*
  * NOTE! The task struct and the stack go together
  */
-#define alloc_task_struct() \
-	((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
-#define free_task_struct(p)	free_pages((unsigned long)(p),1)
-
-#endif
+#define ll_alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
 
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armv/ptrace.h linux-2.2.8-pre5/include/asm-arm/proc-armv/ptrace.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armv/ptrace.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/proc-armv/ptrace.h	2003-08-15 15:06:10.000000000 -0700
@@ -52,9 +52,14 @@
 #define CC_Z_BIT	(1 << 30)
 #define CC_N_BIT	(1 << 31)
 
+#if 0 /* GCC/egcs should be able to optimise this, IMHO */
 #define user_mode(regs)	\
 	((((regs)->ARM_cpsr & MODE_MASK) == USR_MODE) || \
 	 (((regs)->ARM_cpsr & MODE_MASK) == USR26_MODE))
+#else
+#define user_mode(regs)	\
+	(((regs)->ARM_cpsr & 0xf) == 0)
+#endif
 
 #define processor_mode(regs) \
 	((regs)->ARM_cpsr & MODE_MASK)
@@ -74,8 +79,19 @@
 /* Are the current registers suitable for user mode?
  * (used to maintain security in signal handlers)
  */
-#define valid_user_regs(regs) \
-	(user_mode(regs) && ((regs)->ARM_sp & 3) == 0)
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+	if ((regs->ARM_cpsr & 0xf) == 0 ||
+	    (regs->ARM_cpsr & (F_BIT|I_BIT)))
+		return 1;
+
+	/*
+	 * Force CPSR to something logical...
+	 */
+	regs->ARM_cpsr &= (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT|0x10);
+
+	return 0;
+}
 
 #endif
 
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armv/semaphore.h linux-2.2.8-pre5/include/asm-arm/proc-armv/semaphore.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armv/semaphore.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armv/semaphore.h	2003-08-15 15:06:10.000000000 -0700
@@ -60,6 +60,32 @@
 	return temp;
 }
 
+extern inline int down_trylock(struct semaphore *sem)
+{
+	unsigned int cpsr, temp;
+
+	__asm__ __volatile__ ("
+	@ atomic down try lock operation
+	mrs	%0, cpsr
+	orr	%1, %0, #128		@ disable IRQs
+	bic	%0, %0, #0x80000000	@ clear N
+	msr	cpsr, %1
+	ldr	%1, [%2]
+	subs	%1, %1, #1
+	orrmi	%0, %0, #0x80000000	@ set N
+	str	%1, [%2]
+	msr	cpsr, %0
+	movmi	r0, %2
+	movpl	r0, #0
+	blmi	" SYMBOL_NAME_STR(__down_trylock_failed) "
+	mov	%1, r0"
+		: "=&r" (cpsr), "=&r" (temp)
+		: "r" (sem)
+		: "r0", "lr", "cc");
+
+	return temp;
+}
+
 /*
  * Note! This is subtle. We jump to wake people up only if
  * the semaphore was negative (== somebody was waiting on it).
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-armv/uaccess.h linux-2.2.8-pre5/include/asm-arm/proc-armv/uaccess.h
--- linux-2.2.8-pre4/include/asm-arm/proc-armv/uaccess.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/proc-armv/uaccess.h	2003-08-15 15:06:10.000000000 -0700
@@ -133,6 +133,7 @@
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
 	"3:	mvn	%0, %3\n"				\
+	"	mov	%1, #0\n"				\
 	"	b	2b\n"					\
 	"	.previous\n"					\
 	"	.section __ex_table,\"a\"\n"			\
@@ -153,6 +154,7 @@
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
 	"4:	mvn	%0, %5\n"				\
+	"	mov	%1, #0\n"				\
 	"	b	3b\n"					\
 	"	.previous\n"					\
 	"	.section __ex_table,\"a\"\n"			\
@@ -173,6 +175,7 @@
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
 	"3:	mvn	%0, %3\n"				\
+	"	mov	%1, #0\n"				\
 	"	b	2b\n"					\
 	"	.previous\n"					\
 	"	.section __ex_table,\"a\"\n"			\
diff -urN linux-2.2.8-pre4/include/asm-arm/processor.h linux-2.2.8-pre5/include/asm-arm/processor.h
--- linux-2.2.8-pre4/include/asm-arm/processor.h	1999-01-18 09:55:30.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/processor.h	2003-08-15 15:06:10.000000000 -0700
@@ -7,12 +7,14 @@
 #ifndef __ASM_ARM_PROCESSOR_H
 #define __ASM_ARM_PROCESSOR_H
 
+#define FP_SIZE 35
+
 struct fp_hard_struct {
-	unsigned int save[140/4];		/* as yet undefined */
+	unsigned int save[FP_SIZE];		/* as yet undefined */
 };
 
 struct fp_soft_struct {
-	unsigned int save[140/4];		/* undefined information */
+	unsigned int save[FP_SIZE];		/* undefined information */
 };
 
 union fp_state {
@@ -22,28 +24,59 @@
 
 typedef unsigned long mm_segment_t;		/* domain register	*/
 
-#define NR_DEBUGS	5
+#ifdef __KERNEL__
 
-#define DECLARE_THREAD_STRUCT							\
-struct thread_struct {								\
-	unsigned long	address;		/* Address of fault	*/	\
-	unsigned long	trap_no;		/* Trap number		*/	\
-	unsigned long	error_code;		/* Error code of trap	*/	\
-	union fp_state	fpstate;		/* FPE save state	*/	\
-	unsigned long	debug[NR_DEBUGS];	/* Debug/ptrace		*/	\
-	EXTRA_THREAD_STRUCT							\
-}
+#include <asm/assembler.h> 
+
+#define NR_DEBUGS	5
 
 #include <asm/arch/processor.h>
 #include <asm/proc/processor.h>
 
-#define INIT_TSS  {			\
-	0,				\
-	0,				\
-	0,				\
-	{ { { 0, }, }, },		\
-	{ 0, },				\
-	EXTRA_THREAD_STRUCT_INIT	\
+struct thread_struct {
+	unsigned long			address;	  /* Address of fault	*/
+	unsigned long			trap_no;	  /* Trap number	*/
+	unsigned long			error_code;	  /* Error code of trap	*/
+	union fp_state			fpstate;	  /* FPE save state	*/
+	unsigned long			debug[NR_DEBUGS]; /* Debug/ptrace	*/
+	struct context_save_struct	*save;		  /* context save	*/
+	unsigned long			memmap;		  /* page tables	*/
+	EXTRA_THREAD_STRUCT
+};
+
+#define INIT_MMAP \
+{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+
+#define INIT_TSS  {				\
+	0,					\
+	0,					\
+	0,					\
+	{ { { 0, }, }, },			\
+	{ 0, },					\
+	(struct context_save_struct *)0,	\
+	SWAPPER_PG_DIR				\
+	EXTRA_THREAD_STRUCT_INIT		\
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	return t->save ? t->save->pc & ~PCMASK : 0;
+}
+
+extern __inline__ unsigned long get_css_fp(struct thread_struct *t)
+{
+	return t->save ? t->save->fp : 0;
+}
+
+asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
+
+extern __inline__ void init_thread_css(struct context_save_struct *save)
+{
+	*save = INIT_CSS;
+	save->pc |= (unsigned long)ret_from_sys_call;
 }
 
 /* Forward declaration, a strange C thing */
@@ -57,7 +90,12 @@
 #define release_segments(mm)		do { } while (0)
 #define forget_segments()		do { } while (0)
 
+extern struct task_struct *alloc_task_struct(void);
+extern void free_task_struct(struct task_struct *);
+
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+#endif
+
 #endif /* __ASM_ARM_PROCESSOR_H */
diff -urN linux-2.2.8-pre4/include/asm-arm/proc-fns.h linux-2.2.8-pre5/include/asm-arm/proc-fns.h
--- linux-2.2.8-pre4/include/asm-arm/proc-fns.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/proc-fns.h	2003-08-15 15:06:10.000000000 -0700
@@ -9,6 +9,10 @@
 #include <asm/page.h>
 
 #ifdef __KERNEL__
+
+/* forward-decare task_struct */
+struct task_struct;
+
 /*
  * Don't change this structure
  */
@@ -18,7 +22,7 @@
 	 *
 	 * flush caches for task switch
 	 */
-	void (*_switch_to)(void *prev, void *next);
+	struct task_struct *(*_switch_to)(struct task_struct *prev, struct task_struct *next);
 	/*
 	 * get data abort address/flags
 	 */
@@ -54,10 +58,10 @@
 			 */
 			void (*_flush_cache_entry)(unsigned long address);
 			/*
-			 * flush a virtual address used for a page table
-			 * note D-cache only!
+			 * clean a virtual address range from the
+			 * D-cache without flushing the cache.
 			 */
-			void (*_flush_cache_pte)(unsigned long address);
+			void (*_clean_cache_area)(unsigned long start, unsigned long size);
 			/*
 			 * flush a page to RAM
 			 */
@@ -76,13 +80,17 @@
 			 */
 			void (*_set_pmd)(pmd_t *pmdp, pmd_t pmd);
 			/*
+			 * Set a PTE
+			 */
+			void (*_set_pte)(pte_t *ptep, pte_t pte);
+			/*
 			 * Special stuff for a reset
 			 */
 			unsigned long (*reset)(void);
 			/*
 			 * flush an icached page
 			 */
-			void (*_flush_icache_area)(unsigned long start, unsigned long end);
+			void (*_flush_icache_area)(unsigned long start, unsigned long size);
 			/*
 			 * write back dirty cached data
 			 */
diff -urN linux-2.2.8-pre4/include/asm-arm/semaphore.h linux-2.2.8-pre5/include/asm-arm/semaphore.h
--- linux-2.2.8-pre4/include/asm-arm/semaphore.h	1999-01-14 15:53:25.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/semaphore.h	2003-08-15 15:06:10.000000000 -0700
@@ -19,50 +19,16 @@
 
 asmlinkage void __down_failed (void /* special register calling convention */);
 asmlinkage int  __down_interruptible_failed (void /* special register calling convention */);
+asmlinkage int  __down_failed_trylock(void  /* params in registers */);
 asmlinkage void __up_wakeup (void /* special register calling convention */);
 
 extern void __down(struct semaphore * sem);
 extern int  __down_interruptible(struct semaphore * sem);
+extern int  __down_trylock(struct semaphore * sem);
 extern void __up(struct semaphore * sem);
 
 #define sema_init(sem, val)	atomic_set(&((sem)->count), (val))
 
-/*
- * These two _must_ execute atomically wrt each other.
- *
- * This is trivially done with load_locked/store_cond,
- * but on the x86 we need an external synchronizer.
- * Currently this is just the global interrupt lock,
- * bah. Go for a smaller spinlock some day.
- *
- * (On the other hand this shouldn't be in any critical
- * path, so..)
- */
-static inline void wake_one_more(struct semaphore * sem)
-{
-	unsigned long flags;
-
-	save_flags(flags);
-	cli();
-	sem->waking++;
-	restore_flags(flags);
-}
-
-static inline int waking_non_zero(struct semaphore *sem, struct task_struct *tsk)
-{
-	unsigned long flags;
-	int ret = 0;
-
-	save_flags(flags);
-	cli();
-	if (sem->waking > 0) {
-		sem->waking--;
-		ret = 1;
-	}
-	restore_flags(flags);
-	return ret;
-}
-
 #include <asm/proc/semaphore.h>
 
 #endif
diff -urN linux-2.2.8-pre4/include/asm-arm/semaphore-helper.h linux-2.2.8-pre5/include/asm-arm/semaphore-helper.h
--- linux-2.2.8-pre4/include/asm-arm/semaphore-helper.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/semaphore-helper.h	2003-08-15 15:06:10.000000000 -0700
@@ -0,0 +1,84 @@
+#ifndef ASMARM_SEMAPHORE_HELPER_H
+#define ASMARM_SEMAPHORE_HELPER_H
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (atomic_read(&sem->count) <= 0)
+		sem->waking++;
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->waking > 0) {
+		sem->waking--;
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking non zero interruptible
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->waking > 0) {
+		sem->waking--;
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		atomic_inc(&sem->count);
+		ret = -EINTR;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;	
+}
+
+/*
+ * waking_non_zero_try_lock:
+ *	1	failed to lock
+ *	0	got the lock
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 1;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->waking <= 0)
+		atomic_inc(&sem->count);
+	else {
+		sem->waking--;
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/system.h linux-2.2.8-pre5/include/asm-arm/system.h
--- linux-2.2.8-pre4/include/asm-arm/system.h	1998-12-17 09:05:43.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/system.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,10 +1,26 @@
 #ifndef __ASM_ARM_SYSTEM_H
 #define __ASM_ARM_SYSTEM_H
 
+#include <linux/kernel.h>
+
+#ifdef __KERNEL__
+
 #include <linux/config.h>
 
+#define __ebsa285_data		__attribute__((__section__(".data.ebsa285")))
+#define __netwinder_data	__attribute__((__section__(".data.netwinder")))
+
+#ifdef CONFIG_TEXT_SECTIONS
+#define __ebsa285_text		__attribute__((__section__(".text.ebsa285")))
+#define __netwinder_text	__attribute__((__section__(".text.netwinder")))
+#else
+#define __ebsa285_text
+#define __netwinder_text
+#endif
+
 /* The type of machine we're running on */
-extern unsigned int machine_type;
+extern unsigned int __machine_arch_type;
+
 #define MACH_TYPE_EBSA110	0
 #define MACH_TYPE_RISCPC	1
 #define MACH_TYPE_NEXUSPCI	3
@@ -12,31 +28,101 @@
 #define MACH_TYPE_NETWINDER	5
 #define MACH_TYPE_CATS		6
 #define MACH_TYPE_TBOX		7
+#define MACH_TYPE_CO285		8
+#define MACH_TYPE_CLPS7110	9
+#define MACH_TYPE_ARCHIMEDES	10
+#define MACH_TYPE_A5K		11
+
+/*
+ * Sort out a definition for machine_arch_type
+ * The rules basically are:
+ * 1. If one architecture is selected, then all machine_is_xxx()
+ *    are constant.
+ * 2. If two or more architectures are selected, then the selected
+ *    machine_is_xxx() are variable, and the unselected machine_is_xxx()
+ *    are constant zero.
+ */
+#ifdef CONFIG_ARCH_EBSA110
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type	__machine_arch_type
+# else
+#  define machine_arch_type	MACH_TYPE_EBSA110
+# endif
+# define machine_is_ebsa110()	(machine_arch_type == MACH_TYPE_EBSA110)
+#else
+# define machine_is_ebsa110()	(0)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type	__machine_arch_type
+# else
+#  define machine_arch_type	MACH_TYPE_RISCPC
+# endif
+# define machine_is_riscpc()	(machine_arch_type == MACH_TYPE_RISCPC)
+#else
+# define machine_is_riscpc()	(0)
+#endif
 
 #ifdef CONFIG_ARCH_EBSA285
-#define machine_is_ebsa285()	(1)
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type	__machine_arch_type
+# else
+#  define machine_arch_type	MACH_TYPE_EBSA285
+# endif
+# define machine_is_ebsa285()	(machine_arch_type == MACH_TYPE_EBSA285)
 #else
-#define machine_is_ebsa285()	(0)
+# define machine_is_ebsa285()	(0)
 #endif
 
-#ifdef CONFIG_ARCH_VNC
-#define machine_is_netwinder()	(1)
+#ifdef CONFIG_ARCH_NETWINDER
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type	__machine_arch_type
+# else
+#  define machine_arch_type	MACH_TYPE_NETWINDER
+# endif
+# define machine_is_netwinder()	(machine_arch_type == MACH_TYPE_NETWINDER)
 #else
-#define machine_is_netwinder()	(0)
+# define machine_is_netwinder()	(0)
 #endif
 
-#if defined(CONFIG_CATS)
-#define machine_is_cats()	(machine_type == MACH_TYPE_CATS)
+#ifdef CONFIG_CATS
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type	__machine_arch_type
+# else
+#  define machine_arch_type	MACH_TYPE_CATS
+# endif
+# define machine_is_cats()	(machine_arch_type == MACH_TYPE_CATS)
 #else
-#define machine_is_cats()	(0)
+# define machine_is_cats()	(0)
 #endif
 
-#if 0
-#define machine_is_ebsa285()	(machine_type == MACH_TYPE_EBSA285)
-#define machine_is_netwinder()	(machine_type == MACH_TYPE_NETWINDER)
+#ifdef CONFIG_ARCH_CO285
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type	__machine_arch_type
+# else
+#  define machine_arch_type	MACH_TYPE_CO285
+# endif
+# define machine_is_co285()	(machine_arch_type == MACH_TYPE_CO285)
+#else
+# define machine_is_co285()	(0)
 #endif
 
-#include <linux/kernel.h>
+#ifndef machine_arch_type
+#define machine_arch_type	__machine_arch_type
+#endif
+
+/*
+ * task_struct isn't always declared - forward-declare it here.
+ */
+struct task_struct;
+
 #include <asm/proc-fns.h>
 
 extern void arm_malalignedptr(const char *, void *, volatile void *);
@@ -53,7 +139,7 @@
  *
  * `next' and `prev' should be struct task_struct, but it isn't always defined
  */
-#define switch_to(prev,next) processor._switch_to(prev,next)
+#define switch_to(prev,next,last) do { last = processor._switch_to(prev,next); } while (0)
 
 /*
  * Include processor dependent parts
@@ -62,9 +148,12 @@
 #include <asm/arch/system.h>
 
 #define mb() __asm__ __volatile__ ("" : : : "memory")
-#define nop() __asm__ __volatile__("mov r0,r0\n\t");
+#define rmb() mb()
+#define wmb() mb()
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
 
 extern asmlinkage void __backtrace(void);
 
 #endif
 
+#endif
diff -urN linux-2.2.8-pre4/include/asm-arm/unistd.h linux-2.2.8-pre5/include/asm-arm/unistd.h
--- linux-2.2.8-pre4/include/asm-arm/unistd.h	1999-01-07 15:51:33.000000000 -0800
+++ linux-2.2.8-pre5/include/asm-arm/unistd.h	2003-08-15 15:06:10.000000000 -0700
@@ -195,6 +195,9 @@
 #define __NR_capset			(__NR_SYSCALL_BASE+185)
 #define __NR_sigaltstack		(__NR_SYSCALL_BASE+186)
 #define __NR_sendfile			(__NR_SYSCALL_BASE+187)
+					/* 188 reserved */
+					/* 189 reserved */
+#define __NR_vfork			(__NR_SYSCALL_BASE+190)
 
 #define __sys2(x) #x
 #define __sys1(x) __sys2(x)
@@ -364,7 +367,7 @@
 
 static inline int _exit(int exitcode)
 {
-	extern int sys_exit(int);
+	extern int sys_exit(int) __attribute__((noreturn));
 	return sys_exit(exitcode);
 }
 
@@ -393,37 +396,11 @@
 static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp);
 
 /*
- * This is the mechanism for creating a new kernel thread.
- *
- * NOTE! Only a kernel-only process(ie the swapper or direct descendants
- * who haven't done an "execve()") should use this: it will work within
- * a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
+ * Create a new kernel thread
  */
-static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-	long retval;
-
-	__asm__ __volatile__("
-	mov	r0,%1
-	mov	r1,%2
-	"__syscall(clone)"
-	teq	r0, #0
-	bne	1f
-	mov	r0,%4
-	mov	lr, pc
-	mov	pc, %3
-	"__syscall(exit)"
-1:	mov %0,r0"
-        : "=r" (retval)
-        : "Ir" (flags | CLONE_VM), "Ir" (NULL), "r" (fn), "Ir" (arg)
-	: "r0","r1","r2","r3","lr");
-	
-	return retval;
-}
+extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
 #endif
-
 #endif /* __ASM_ARM_UNISTD_H */
 
 
diff -urN linux-2.2.8-pre4/include/asm-arm/vga.h linux-2.2.8-pre5/include/asm-arm/vga.h
--- linux-2.2.8-pre4/include/asm-arm/vga.h	1998-09-06 10:45:30.000000000 -0700
+++ linux-2.2.8-pre5/include/asm-arm/vga.h	2003-08-15 15:06:10.000000000 -0700
@@ -1,9 +1,10 @@
 #ifndef ASMARM_VGA_H
 #define ASMARM_VGA_H
 
+#include <asm/hardware.h>
 #include <asm/io.h>
 
-#define VGA_MAP_MEM(x)	(0xe0000000 + (x))
+#define VGA_MAP_MEM(x)	(PCIMEM_BASE + (x))
 
 #define vga_readb(x)	(*(x))
 #define vga_writeb(x,y)	(*(y) = (x))
diff -urN linux-2.2.8-pre4/include/linux/dcache.h linux-2.2.8-pre5/include/linux/dcache.h
--- linux-2.2.8-pre4/include/linux/dcache.h	1999-03-19 08:08:57.000000000 -0800
+++ linux-2.2.8-pre5/include/linux/dcache.h	2003-08-15 15:06:10.000000000 -0700
@@ -77,7 +77,7 @@
 };
 
 struct dentry_operations {
-	int (*d_revalidate)(struct dentry *);
+	int (*d_revalidate)(struct dentry *, int);
 	int (*d_hash) (struct dentry *, struct qstr *);
 	int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
 	void (*d_delete)(struct dentry *);
diff -urN linux-2.2.8-pre4/include/linux/fs.h linux-2.2.8-pre5/include/linux/fs.h
--- linux-2.2.8-pre4/include/linux/fs.h	1999-04-27 09:56:21.000000000 -0700
+++ linux-2.2.8-pre5/include/linux/fs.h	2003-08-15 15:06:10.000000000 -0700
@@ -810,6 +810,18 @@
 #define PTR_ERR(ptr)	((long)(ptr))
 #define IS_ERR(ptr)	((unsigned long)(ptr) > (unsigned long)(-1000))
 
+/*
+ * The bitmask for a lookup event:
+ *  - follow links at the end
+ *  - require a directory
+ *  - ending slashes ok even for nonexistent files
+ *  - internal "there are more path compnents" flag
+ */
+#define LOOKUP_FOLLOW		(1)
+#define LOOKUP_DIRECTORY	(2)
+#define LOOKUP_SLASHOK		(4)
+#define LOOKUP_CONTINUE		(8)
+
 extern struct dentry * lookup_dentry(const char *, struct dentry *, unsigned int);
 extern struct dentry * __namei(const char *, unsigned int);
 
diff -urN linux-2.2.8-pre4/include/linux/mc146818rtc.h linux-2.2.8-pre5/include/linux/mc146818rtc.h
--- linux-2.2.8-pre4/include/linux/mc146818rtc.h	1999-04-27 09:57:56.000000000 -0700
+++ linux-2.2.8-pre5/include/linux/mc146818rtc.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,149 +0,0 @@
-/* mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
- * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993
- * derived from Data Sheet, Copyright Motorola 1984 (!).
- * It was written to be part of the Linux operating system.
- */
-/* permission is hereby granted to copy, modify and redistribute this code
- * in terms of the GNU Library General Public License, Version 2 or later,
- * at your option.
- */
-
-#ifndef _MC146818RTC_H
-#define _MC146818RTC_H
-#include <asm/io.h>
-
-#ifndef RTC_PORT
-#define RTC_PORT(x)	(0x70 + (x))
-#define RTC_ALWAYS_BCD	1
-#endif
-
-#define CMOS_READ(addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-outb_p((val),RTC_PORT(1)); \
-})
-
-/**********************************************************************
- * register summary
- **********************************************************************/
-#define RTC_SECONDS		0
-#define RTC_SECONDS_ALARM	1
-#define RTC_MINUTES		2
-#define RTC_MINUTES_ALARM	3
-#define RTC_HOURS		4
-#define RTC_HOURS_ALARM		5
-/* RTC_*_alarm is always true if 2 MSBs are set */
-# define RTC_ALARM_DONT_CARE 	0xC0
-
-#define RTC_DAY_OF_WEEK		6
-#define RTC_DAY_OF_MONTH	7
-#define RTC_MONTH		8
-#define RTC_YEAR		9
-
-/* control registers - Moto names
- */
-#define RTC_REG_A		10
-#define RTC_REG_B		11
-#define RTC_REG_C		12
-#define RTC_REG_D		13
-
-/**********************************************************************
- * register details
- **********************************************************************/
-#define RTC_FREQ_SELECT	RTC_REG_A
-
-/* update-in-progress  - set to "1" 244 microsecs before RTC goes off the bus,
- * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
- * totalling to a max high interval of 2.228 ms.
- */
-# define RTC_UIP		0x80
-# define RTC_DIV_CTL		0x70
-   /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
-#  define RTC_REF_CLCK_4MHZ	0x00
-#  define RTC_REF_CLCK_1MHZ	0x10
-#  define RTC_REF_CLCK_32KHZ	0x20
-   /* 2 values for divider stage reset, others for "testing purposes only" */
-#  define RTC_DIV_RESET1	0x60
-#  define RTC_DIV_RESET2	0x70
-  /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
-# define RTC_RATE_SELECT 	0x0F
-
-/**********************************************************************/
-#define RTC_CONTROL	RTC_REG_B
-# define RTC_SET 0x80		/* disable updates for clock setting */
-# define RTC_PIE 0x40		/* periodic interrupt enable */
-# define RTC_AIE 0x20		/* alarm interrupt enable */
-# define RTC_UIE 0x10		/* update-finished interrupt enable */
-# define RTC_SQWE 0x08		/* enable square-wave output */
-# define RTC_DM_BINARY 0x04	/* all time/date values are BCD if clear */
-# define RTC_24H 0x02		/* 24 hour mode - else hours bit 7 means pm */
-# define RTC_DST_EN 0x01	/* auto switch DST - works f. USA only */
-
-/**********************************************************************/
-#define RTC_INTR_FLAGS	RTC_REG_C
-/* caution - cleared by read */
-# define RTC_IRQF 0x80		/* any of the following 3 is active */
-# define RTC_PF 0x40
-# define RTC_AF 0x20
-# define RTC_UF 0x10
-
-/**********************************************************************/
-#define RTC_VALID	RTC_REG_D
-# define RTC_VRT 0x80		/* valid RAM and time */
-/**********************************************************************/
-
-/* example: !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) 
- * determines if the following two #defines are needed
- */
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
-/*
- * The struct used to pass data via the following ioctl. Similar to the
- * struct tm in <time.h>, but it needs to be here so that the kernel 
- * source is self contained, allowing cross-compiles, etc. etc.
- */
-
-struct rtc_time {
-	int tm_sec;
-	int tm_min;
-	int tm_hour;
-	int tm_mday;
-	int tm_mon;
-	int tm_year;
-	int tm_wday;
-	int tm_yday;
-	int tm_isdst;
-};
-
-/*
- * ioctl calls that are permitted to the /dev/rtc interface, if 
- * CONFIG_RTC was enabled.
- */
-
-#define RTC_AIE_ON	_IO('p', 0x01)	/* Alarm int. enable on		*/
-#define RTC_AIE_OFF	_IO('p', 0x02)	/* ... off			*/
-#define RTC_UIE_ON	_IO('p', 0x03)	/* Update int. enable on	*/
-#define RTC_UIE_OFF	_IO('p', 0x04)	/* ... off			*/
-#define RTC_PIE_ON	_IO('p', 0x05)	/* Periodic int. enable on	*/
-#define RTC_PIE_OFF	_IO('p', 0x06)	/* ... off			*/
-
-#define RTC_ALM_SET	_IOW('p', 0x07, struct rtc_time) /* Set alarm time  */
-#define RTC_ALM_READ	_IOR('p', 0x08, struct rtc_time) /* Read alarm time */
-#define RTC_RD_TIME	_IOR('p', 0x09, struct rtc_time) /* Read RTC time   */
-#define RTC_SET_TIME	_IOW('p', 0x0a, struct rtc_time) /* Set RTC time    */
-#define RTC_IRQP_READ	_IOR('p', 0x0b, unsigned long)	 /* Read IRQ rate   */
-#define RTC_IRQP_SET	_IOW('p', 0x0c, unsigned long)	 /* Set IRQ rate    */
-#define RTC_EPOCH_READ	_IOR('p', 0x0d, unsigned long)	 /* Read epoch      */
-#define RTC_EPOCH_SET	_IOW('p', 0x0e, unsigned long)	 /* Set epoch       */
-
-
-#endif /* _MC146818RTC_H */
diff -urN linux-2.2.8-pre4/include/linux/nfs_fs.h linux-2.2.8-pre5/include/linux/nfs_fs.h
--- linux-2.2.8-pre4/include/linux/nfs_fs.h	2003-08-15 15:06:09.000000000 -0700
+++ linux-2.2.8-pre5/include/linux/nfs_fs.h	2003-08-15 15:06:10.000000000 -0700
@@ -182,6 +182,7 @@
 extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
 extern int nfs_revalidate(struct dentry *);
 extern int nfs_open(struct inode *, struct file *);
+extern int nfs_release(struct inode *, struct file *);
 extern int _nfs_revalidate_inode(struct nfs_server *, struct dentry *);
 
 /*
diff -urN linux-2.2.8-pre4/MAINTAINERS linux-2.2.8-pre5/MAINTAINERS
--- linux-2.2.8-pre4/MAINTAINERS	1999-04-24 18:23:38.000000000 -0700
+++ linux-2.2.8-pre5/MAINTAINERS	2003-08-15 15:06:10.000000000 -0700
@@ -779,14 +779,14 @@
 USB HUB AND UHCI DRIVERS
 P:	Johannes Erdfelt
 M:	jerdfelt@sventech.com
-L:	linux-usb@peloncho.fis.ucm.es
+L:	linux-usb@suse.com
 S:	Maintained
 
 USB OHCI DRIVER
 P:	Gregory P. Smith
 M:	greg@electricrain.com
 M:	greg@suitenine.com
-L:	linux-usb@peloncho.fis.ucm.es
+L:	linux-usb@suse.com
 S:	Maintained (not yet usable)
 W:	http://suitenine.com/usb/
 
