diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/Makefile linux-2.4.6.uc0pre0.actiontec/arch/armnommu/Makefile
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/Makefile	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/Makefile	2004-12-06 19:35:49.000000000 +0100
@@ -7,9 +7,9 @@
 #
 # Copyright (C) 1995-2001 by Russell King
 
-LINKFLAGS	:=-p -X -T arch/armnommu/vmlinux.lds
+LINKFLAGS	:=-p -X
 GZFLAGS		:=-9
-CFLAGS		+=-fno-common -pipe
+CFLAGS		+=-fno-common -pipe -fno-builtin -D__linux__
 
 ifneq ($(CONFIG_NO_FRAME_POINTER),y)
 CFLAGS		:=$(CFLAGS:-fomit-frame-pointer=)
@@ -41,6 +41,7 @@
 tune-$(CONFIG_CPU_ARM710)	:=-mtune=arm7tdmi
 tune-$(CONFIG_CPU_ARM720T)	:=-mtune=arm7tdmi
 tune-$(CONFIG_CPU_ARM920T)	:=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM926T)	:=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
 tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
 
@@ -56,7 +57,7 @@
 
 ifeq ($(CONFIG_CPU_32),y)
 PROCESSOR	 = armv
-TEXTADDR	 = 0xC0008000
+TEXTADDR	 = 0x0
 endif
 
 ifeq ($(CONFIG_ARCH_ARCA5K),y)
@@ -124,6 +125,12 @@
 #LINKFLAGS	 = -X -T arch/armnommu/vmlinux.lds
 endif
 
+ifeq ($(CONFIG_ARCH_CX821XX),y)
+MACHINE		= cx821xx
+TEXTADDR	= 0x800000
+CFLAGS		+= -DNO_MM -DMAGIC_ROM_PTR
+LINKFLAGS	+= -T arch/armnommu/mach-$(MACHINE)/ramlinux.lds
+endif
 
 export	LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
 
@@ -178,9 +185,13 @@
 $(LINUX): arch/armnommu/vmlinux.lds
 
 arch/armnommu/vmlinux.lds: arch/armnommu/vmlinux-$(PROCESSOR).lds.in dummy
+ifeq ($(CONFIG_ARCH_DSC21),y)
 	@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >tmp.ld
 	@sed 's/DATAADDR/$(DATAADDR)/' <tmp.ld >$@
 	$(RM) tmp.ld
+else
+	@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@	
+endif
 
 arch/armnommu/kernel arch/armnommu/mm arch/armnommu/lib: dummy
 	$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
@@ -224,6 +235,9 @@
 	@true
 endif
 
+linux.bin: linux
+	 $(CROSS_COMPILE)objcopy -O binary linux linux.bin
+
 # My testing targets (that short circuit a few dependencies)
 zImg:;	@$(MAKEBOOT) zImage
 Img:;	@$(MAKEBOOT) Image
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/boot/Makefile linux-2.4.6.uc0pre0.actiontec/arch/armnommu/boot/Makefile
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/boot/Makefile	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/boot/Makefile	2004-12-06 19:35:49.000000000 +0100
@@ -8,7 +8,7 @@
 # Copyright (C) 1995-2000 Russell King
 #
 
-SYSTEM	=$(TOPDIR)/$(LINUX)
+SYSTEM	=$(TOPDIR)/vmlinux
 
 ifeq ($(CONFIG_CPU_26),y)
 ZTEXTADDR	 = 0x02080000
@@ -120,14 +118,14 @@
 
 bzImage: zImage
 
-zImage:	$(CONFIGURE) compressed/$(LINUX)
-	$(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@
+zImage:	$(CONFIGURE) compressed/vmlinux
+	$(OBJCOPY) -O binary -R .note -R .comment -S compressed/vmlinux $@
 
 bootpImage: bootp/bootp
 	$(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
 
-compressed/$(LINUX): $(TOPDIR)/$(LINUX) dep
-	@$(MAKE) -C compressed LINUX=$(LINUX)
+compressed/vmlinux: $(TOPDIR)/vmlinux dep
+	@$(MAKE) -C compressed vmlinux
 
 bootp/bootp: zImage initrd
 	@$(MAKE) -C bootp bootp
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/config.in linux-2.4.6.uc0pre0.actiontec/arch/armnommu/config.in
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/config.in	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/config.in	2004-12-06 19:35:49.000000000 +0100
@@ -7,6 +7,7 @@
 define_bool CONFIG_ARM y
 define_bool CONFIG_SBUS n
 define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 
 # Begin uclinux additions -----------------------------------------------------
 define_bool CONFIG_UCLINUX y
@@ -36,11 +37,150 @@
 #------------------------------------------------------------------------------
 #                               S y s t e m
 #------------------------------------------------------------------------------
+
 mainmenu_option next_comment
 comment 'System Type'
 choice 'ARM system type'	\
-	 "TI-DSC21		CONFIG_ARCH_DSC21"
-endmenu
+       "Atmel			CONFIG_ARCH_ATMEL \
+	Conexant		CONFIG_ARCH_CNXT \
+	TI-DSC21		CONFIG_ARCH_DSC21 \
+	Samsung_S3C4		CONFIG_ARCH_S3C4" Atmel
+
+if [ "$CONFIG_ARCH_CNXT" = "y" ]; then
+choice ' Conexant/Mindspeed architecture' \
+   	" P52xxCtrl		CONFIG_ARCH_P52 \
+	  sp_CN9414 		CONFIG_ARCH_SPIPE \
+	  CX821xxCtrl		CONFIG_ARCH_CX821XX \
+	  CX861xxCtrl		CONFIG_ARCH_CX861XX" CX821xxCtrl 
+
+  if [ "$CONFIG_ARCH_P52" = "y" ]; then
+  choice ' P52xx board implementation'	\
+	"IAD_EVM		CONFIG_IAD_EVM \
+	 JSCHornet		CONFIG_HORNET" IAD_EVM
+  fi
+  
+  choice ' Board Support Package'	" \
+	HASBANI			CONFIG_BD_HASBANI \
+	GOLDENGATE		CONFIG_BD_GOLDENGATE \
+	MACKINAC		CONFIG_BD_MACKINAC \
+	RUSHMORE		CONFIG_BD_RUSHMORE \
+	OAKLAND			CONFIG_BD_OAKLAND \
+	LIONSGATE		CONFIG_BD_LIONSGATE \
+	OLDFAITHFUL		CONFIG_BD_OLDFAITHFUL \ 
+	" MACKINAC
+
+  if [ "$CONFIG_BD_HASBANI" = "y" ]; then
+    define_bool CONFIG_CHIP_P52 y
+  fi
+  if [ "$CONFIG_BD_GOLDENGATE" = "y" ]; then
+    define_bool CONFIG_CHIP_CX82100 y
+    define_bool CONFIG_CHIP_CX86100 n
+    define_bool CONFIG_CHIP_CX82110 n
+  fi
+  if [ "$CONFIG_BD_MACKINAC" = "y" ]; then
+    define_bool CONFIG_CHIP_CX82110 y
+    define_bool CONFIG_CHIP_CX86100 n
+    define_bool CONFIG_CHIP_CX82100 n
+  fi
+  if [ "$CONFIG_BD_RUSHMORE" = "y" ]; then
+    define_bool CONFIG_CHIP_CX82110 y
+    define_bool CONFIG_CHIP_CX86100 n
+    define_bool CONFIG_CHIP_CX82100 n
+  fi
+  if [ "$CONFIG_BD_OAKLAND" = "y" ]; then
+    define_bool CONFIG_CHIP_CX82100 y
+    define_bool CONFIG_CHIP_CX86100 n
+    define_bool CONFIG_CHIP_CX82110 n
+  fi
+  if [ "$CONFIG_BD_LIONSGATE" = "y" ]; then
+    define_bool CONFIG_CHIP_CX82100 y
+    define_bool CONFIG_CHIP_CX86100 n
+    define_bool CONFIG_CHIP_CX82110 n
+  fi
+  if [ "$CONFIG_BD_OLDFAITHFUL" = "y" ]; then
+    define_bool CONFIG_CHIP_CX86100 y
+    define_bool CONFIG_CHIP_CX82100 n
+    define_bool CONFIG_CHIP_CX82110 n
+  fi
+fi
+
+if [ "$CONFIG_ARCH_S3C4" = "y" ]; then
+choice	'Processor' \
+   	" S3C4510		CONFIG_CPU_S3C4510 \
+	  S3C4520		CONFIG_CPU_S3C4520 \
+	  S3C4530		CONFIG_CPU_S3C4530 \
+	  S3C44B0X 		CONFIG_CPU_S3C44B0X" S3C4530
+choice	'Board implementation'	\
+	"uClink-II		CONFIG_BOARD_UCLINKII \
+	 evS3C4530-LII		CONFIG_BOARD_EVS3C4530LII \
+	 evS3C4530-HEI		CONFIG_BOARD_EVS3C4530HEI" evS3C4530-HEI
+
+# bool 	'Use System Memory Manager' CONFIG_SYSMEM y
+# bool	'Cache enable' CONFIG_CACHE_ON n
+
+
+fi
+
+# ARM940T
+if [ "$CONFIG_CHIP_CX82100" = "y" -o "$CONFIG_CHIP_CX82110" = "y" ]; then
+	define_bool CONFIG_CPU_32 y
+	define_bool CONFIG_CPU_26 n
+	define_bool CONFIG_CPU_ARM940T y
+	define_bool CONFIG_NO_PGT_CACHE y
+	bool 'Set flash/sdram size and base addr' CONFIG_SET_MEM_PARAM
+
+	if [ "$CONFIG_SET_MEM_PARAM" = "y" ]; then
+	   hex 'SDRAM Base Address' DRAM_BASE 0x00800000
+	   hex 'SDRAM Size ' DRAM_SIZE 0x00780000
+	   hex 'FLASH Base Address ' FLASH_MEM_BASE 0x00400000
+	   hex 'FLASH Size ' FLASH_SIZE 0x00400000
+	fi
+
+	if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+	   define_hex DRAM_BASE 0x00800000
+	   define_hex DRAM_SIZE 0x00780000
+	   define_hex FLASH_MEM_BASE 0x00400000
+	   define_hex FLASH_SIZE 0x00400000
+	fi
+
+	   bool '  ARM940T CPU idle' CONFIG_CPU_ARM940_CPU_IDLE
+	   bool '  ARM940T I-Cache on' CONFIG_CPU_ARM940_I_CACHE_ON
+	   bool '  ARM940T D-Cache on' CONFIG_CPU_ARM940_D_CACHE_ON
+	if [ "$CONFIG_CPU_ARM940_D_CACHE_ON" = "y" ] ; then
+	   bool '  Force write through caches on ARM940T' CONFIG_CPU_ARM940_WRITETHROUGH
+	fi
+fi
+
+# ARM926
+if [ "$CONFIG_CHIP_CX86100" = "y" ]; then
+	define_bool CONFIG_CPU_32 y
+	define_bool CONFIG_CPU_26 n
+	define_bool CONFIG_CPU_ARM926T y
+	define_bool CONFIG_NO_PGT_CACHE y
+	bool 'Set flash/sdram size and base addr' CONFIG_SET_MEM_PARAM
+
+	if [ "$CONFIG_SET_MEM_PARAM" = "y" ]; then
+	   hex 'SDRAM Base Address' DRAM_BASE 0x008200000
+	   hex 'SDRAM Size ' DRAM_SIZE 0x003E00000
+	   hex 'FLASH Base Address ' FLASH_MEM_BASE 0x004000000
+	   hex 'FLASH Size ' FLASH_SIZE 0x00400000
+	fi
+
+	if [ "$CONFIG_SET_MEM_PARAM" = "n" ]; then
+	   define_hex DRAM_BASE 0x008200000
+	   define_hex DRAM_SIZE 0x003e00000
+	   define_hex FLASH_MEM_BASE 0x004000000
+	   define_hex FLASH_SIZE 0x00400000
+	fi
+
+   bool '  ARM926 CPU idle' CONFIG_CPU_ARM926_CPU_IDLE
+   bool '  ARM926 I-Cache on' CONFIG_CPU_ARM926_I_CACHE_ON
+   bool '  ARM926 D-Cache on' CONFIG_CPU_ARM926_D_CACHE_ON
+	if [ "$CONFIG_CPU_ARM926_D_CACHE_ON" = "y" ] ; then
+	   bool '  Force write through caches on ARM926' CONFIG_CPU_ARM926_WRITETHROUGH
+	fi
+fi
+
 if [ "$CONFIG_ARCH_DSC21" = "y" ]; then
    define_bool CONFIG_CPU_ARM710 y
    define_bool CONFIG_CPU_32 y
@@ -50,9 +190,62 @@
    define_hex DRAM_SIZE 0x00200000
    define_hex FLASH_MEM_BASE 0x08400000
    define_hex FLASH_SIZE 0x00200000
-   define_bool CONFIG_ARCH_ATMEL n
    define_bool CONFIG_DUMMY_CONSOLE y
 fi
+
+if [ "$CONFIG_ARCH_ATMEL" = "y" ]; then
+   define_bool CONFIG_NO_PGT_CACHE y
+   define_bool CONFIG_CPU_ARM710 y
+   define_bool CONFIG_CPU_32 y
+   define_hex DRAM_BASE 0x01000000
+   define_bool CONFIG_CPU_AT91X40 y
+   define_hex DRAM_SIZE 0x00200000
+   define_hex FLASH_MEM_BASE 0x08400000
+   define_hex FLASH_SIZE 0x00200000
+   define_bool CONFIG_SERIAL_ATMEL y
+
+   bool 'Atmel Kernel-Debug hack' CONFIG_ATMEL_DEBUG
+   if [ "$CONFIG_ATMEL_DEBUG" = "y" ]; then
+	hex 'Debug buffer address' AT91_DEBUG_BASE 0x01400000
+   fi
+fi
+
+if [ "$CONFIG_ARCH_S3C4" = "y" ]; then
+    define_bool	CONFIG_CPU_ARM710	y
+    define_bool	CONFIG_CPU_32		y
+    define_bool	CONFIG_NO_PGT_CACHE	y
+    
+    if [ "$CONFIG_BOARD_UCLINKII" = "y" ]; then
+	define_int	CONFIG_ARM_CLK  50000000
+	define_hex	DRAM_BASE	0x00020000
+	define_hex	DRAM_SIZE 	0x007D0000
+	define_hex	FLASH_MEM_BASE	0x01000000
+	define_hex	FLASH_SIZE	0x00200000
+    else if [ "$CONFIG_BOARD_EVS3C4530LII" = "y" ]; then
+	    define_int	CONFIG_ARM_CLK  50000000
+	    define_hex	DRAM_BASE	0x00020000
+	    define_hex	DRAM_SIZE 	0x007D0000
+	    define_hex	FLASH_MEM_BASE	0x01000000
+	    define_hex	FLASH_SIZE	0x00200000
+	    else if [ "$CONFIG_BOARD_EVS3C4530HEI" = "y" ]; then
+		    define_int	CONFIG_ARM_CLK  50000000
+		    define_hex	DRAM_BASE	0x00020000
+		    define_hex	DRAM_SIZE 	0x007D0000
+		    define_hex	FLASH_MEM_BASE	0x01000000
+		    define_hex	FLASH_SIZE	0x00200000
+		    define_bool CONFIG_UCBOOTSTRAP	y
+		 fi
+	 fi
+    fi    
+fi
+choice 'Kernel executes from' \
+	"RAM	CONFIG_RAMKERNEL \
+	 ROM	CONFIG_ROMKERNEL" RAM
+
+bool	'  Use uCbootstrap calls' CONFIG_UCBOOTSTRAP
+
+endmenu
+
 #------------------------------------------------------------------------------
 #                             G e n e r a l
 #------------------------------------------------------------------------------
@@ -73,8 +266,11 @@
 tristate 'NWFPE math emulation' CONFIG_NWFPE
 choice 'Kernel core (/proc/kcore) format' \
 	"ELF		CONFIG_KCORE_ELF	\
-	 A.OUT		CONFIG_KCORE_AOUT" ELF
-define_bool CONFIG_BINFMT_FLAT y
+	 A.OUT		CONFIG_KCORE_AOUT" A.OUT
+tristate 'Kernel support for flat binaries' CONFIG_BINFMT_FLAT
+if [ "$CONFIG_BINFMT_FLAT" != "n" ]; then
+   bool '    Enable ZFLAT support' CONFIG_BINFMT_ZFLAT
+fi
 define_bool CONFIG_KERNEL_ELF y
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -178,6 +374,32 @@
 fi
 
 #------------------------------------------------------------------------------
+#                        	   U S B
+#------------------------------------------------------------------------------
+# mainmenu_option next_comment
+# comment 'ISDN subsystem'
+# bool 'USB support' CONFIG_USB
+# if [ "$CONFIG_USB" != "n" ]; then
+# 	bool 'Use USB for Data in addition to Control' CONFIG_DATA_OVER_USB
+# fi
+# endmenu
+
+#------------------------------------------------------------------------------
+#                        	   VOIP
+#------------------------------------------------------------------------------
+mainmenu_option next_comment
+comment 'VOIP support'
+tristate 'VOIP support' CONFIG_CNXT_VOIP
+if [ "$CONFIG_CNXT_VOIP" != "n" ]; then
+	choice	'Voip Hardware' \
+	   	" 1LGPIO		CONFIG_CNXT_VOIP_1LGPIO \
+		  GL			CONFIG_CNXT_VOIP_GL \
+		  SPI_GL		CONFIG_CNXT_VOIP_SPI_GL \
+		  SPI_NG 		CONFIG_CNXT_VOIP_SPI_NG" 1LGPIO
+fi
+endmenu
+
+#------------------------------------------------------------------------------
 #                        M i s c    D r i v e r s
 #------------------------------------------------------------------------------
 source drivers/parport/Config.in
@@ -189,14 +411,19 @@
 source drivers/usb/Config.in
 source drivers/ieee1394/Config.in
 source drivers/i2o/Config.in
+source drivers/telephony/Config.in
+
 #------------------------------------------------------------------------------
 #                     K e r n e l    H a c k i n g
 #------------------------------------------------------------------------------
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
-define_bool CONFIG_FRAME_POINTER y
 bool 'Find REVISITS' CONFIG_REVISIT
+bool 'Config frame pointer' CONFIG_FRAME_POINTER
+if [ "$CONFIG_FRAME_POINTER" = "n" ]; then
+   define_bool CONFIG_NO_FRAME_POINTER y
+fi
 bool 'Verbose kernel error messages' CONFIG_DEBUG_ERRORS
 bool 'Verbose user fault messages' CONFIG_DEBUG_USER
 bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/Makefile linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/Makefile
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/Makefile	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/Makefile	2004-12-06 19:35:49.000000000 +0100
@@ -34,14 +34,14 @@
 
 # Object file lists.
 
-obj-y		:= arch.o dma.o $(ENTRY_OBJ) irq.o process.o ptrace.o    \
-		   semaphore.o setup.o signal.o sys_arm.o time.o traps.o \
-		   $(O_OBJS_$(MACHINE))
+obj-y		:= arch.o compat.o dma.o $(ENTRY_OBJ) entry-common.o irq.o   \
+		   process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
+		   time.o traps.o $(O_OBJS_$(MACHINE))
 obj-m		:=
 obj-n		:=
 obj-		:=
 
-export-objs	:= armksyms.o dma.o ecard.o fiq.o oldlatches.o time.o
+export-objs	:= armksyms.o dma.o ecard.o fiq.o io.o oldlatches.o time.o
 
 no-irq-arch	:= $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
 		   $(CONFIG_ARCH_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110)
@@ -57,10 +57,15 @@
 obj-$(CONFIG_ISA_DMA)	+= dma-isa.o
 obj-$(CONFIG_PCI)	+= bios32.o $(pci-$(MACHINE)) $(pci-y)
 
+ifneq ($(MACHINE),ebsa110)
+  obj-y		+= io.o
+endif
+
 all: kernel.o $(HEAD_OBJ) init_task.o
 
 include $(TOPDIR)/Rules.make
 
 # Spell out some dependencies that `make dep' doesn't spot
-entry-armv.o: calls.S $(TOPDIR)/include/asm-armnommu/constants.h
-entry-armo.o: calls.S $(TOPDIR)/include/asm-armnommu/constants.h
+entry-armv.o: entry-header.S $(TOPDIR)/include/asm/constants.h
+entry-armo.o: entry-header.S $(TOPDIR)/include/asm/constants.h
+entry-common.o: entry-header.S calls.S $(TOPDIR)/include/asm/constants.h
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/arch.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/arch.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/arch.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/arch.c	2004-12-06 19:35:49.000000000 +0100
@@ -28,46 +25,41 @@
 unsigned int memc_ctrl_reg;
 unsigned int number_mfm_drives;
 
-static void __init
-fixup_acorn(struct machine_desc *desc, struct param_struct *params,
-	    char **cmdline, struct meminfo *mi)
+static int __init parse_tag_acorn(const struct tag *tag)
 {
-	if (machine_is_riscpc()) {
-		int i;
+	memc_ctrl_reg = tag->u.acorn.memc_control_reg;
+	number_mfm_drives = tag->u.acorn.adfsdrives;
 
-		/*
-		 * RiscPC can't handle half-word loads and stores
-		 */
-		elf_hwcap &= ~HWCAP_HALF;
-
-		switch (params->u1.s.pages_in_vram) {
-		case 512:
-			vram_size += PAGE_SIZE * 256;
-		case 256:
-			vram_size += PAGE_SIZE * 256;
-		default:
-			break;
-		}
-
-		if (vram_size) {
-			desc->video_start = 0x02000000;
-			desc->video_end   = 0x02000000 + vram_size;
-		}
-
-		for (i = 0; i < 4; i++) {
-			mi->bank[i].start = PHYS_OFFSET + (i << 26);
-			mi->bank[i].node  = 0;
-			mi->bank[i].size  =
-				params->u1.s.pages_in_bank[i] *
-				params->u1.s.page_size;
-		}
-		mi->nr_banks = 4;
+	switch (tag->u.acorn.vram_pages) {
+	case 512:
+		vram_size += PAGE_SIZE * 256;
+	case 256:
+		vram_size += PAGE_SIZE * 256;
+	default:
+		break;
 	}
-	memc_ctrl_reg	  = params->u1.s.memc_control_reg;
-	number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
+#if 0
+	if (vram_size) {
+		desc->video_start = 0x02000000;
+		desc->video_end   = 0x02000000 + vram_size;
+	}
+#endif
+	return 0;
 }
 
+__tagtable(ATAG_ACORN, parse_tag_acorn);
+
 #ifdef CONFIG_ARCH_RPC
+static void __init
+fixup_riscpc(struct machine_desc *desc, struct param_struct *unusd,
+	    char **cmdline, struct meminfo *mi)
+{
+	/*
+	 * RiscPC can't handle half-word loads and stores
+	 */
+	elf_hwcap &= ~HWCAP_HALF;
+}
+
 extern void __init rpc_map_io(void);
 
 MACHINE_START(RISCPC, "Acorn-RiscPC")
@@ -76,7 +68,7 @@
 	BOOT_PARAMS(0x10000100)
 	DISABLE_PARPORT(0)
 	DISABLE_PARPORT(1)
-	FIXUP(fixup_acorn)
+	FIXUP(fixup_riscpc)
 	MAPIO(rpc_map_io)
 	INITIRQ(genarch_init_irq)
 MACHINE_END
@@ -85,7 +77,6 @@
 MACHINE_START(ARCHIMEDES, "Acorn-Archimedes")
 	MAINTAINER("Dave Gilbert")
 	BOOT_PARAMS(0x0207c000)
-	FIXUP(fixup_acorn)
 	INITIRQ(genarch_init_irq)
 MACHINE_END
 #endif
@@ -93,7 +84,6 @@
 MACHINE_START(A5K, "Acorn-A5000")
 	MAINTAINER("Russell King")
 	BOOT_PARAMS(0x0207c000)
-	FIXUP(fixup_acorn)
 	INITIRQ(genarch_init_irq)
 MACHINE_END
 #endif
@@ -103,7 +93,7 @@
 extern void __init l7200_map_io(void);
 
 static void __init
-fixup_l7200(struct machine_desc *desc, struct param_struct *params,
+fixup_l7200(struct machine_desc *desc, struct param_struct *unused,
              char **cmdline, struct meminfo *mi)
 {
         mi->nr_banks      = 1;
@@ -185,9 +175,3 @@
 	INITIRQ(genarch_init_irq)
 MACHINE_END
 #endif
-#ifdef CONFIG_ARCH_DSC21
-MACHINE_START(DSC21, "DSC21")
-	MAINTAINER("RdgeRun Inc")
-	INITIRQ(genarch_init_irq)
-MACHINE_END
-#endif
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/armksyms.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/armksyms.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/armksyms.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/armksyms.c	2004-12-06 19:35:49.000000000 +0100
@@ -48,7 +48,6 @@
 extern int sys_read(int, char *, int);
 extern int sys_lseek(int, off_t, int);
 extern int sys_exit(int);
-extern int sys_wait4(int, int *, int, struct rusage *);
 
 /*
  * libgcc functions - functions that are used internally by the
@@ -114,7 +113,6 @@
 EXPORT_SYMBOL(system_rev);
 EXPORT_SYMBOL(system_serial_low);
 EXPORT_SYMBOL(system_serial_high);
-EXPORT_SYMBOL(mem_fclk_21285);
 EXPORT_SYMBOL(__bug);
 EXPORT_SYMBOL(__bad_xchg);
 EXPORT_SYMBOL(__readwrite_bug);
@@ -123,6 +121,9 @@
 EXPORT_SYMBOL(pm_idle);
 EXPORT_SYMBOL(pm_power_off);
 
+extern void __do_softirq(void);
+EXPORT_SYMBOL_NOVERS(__do_softirq);
+
 	/* processor dependencies */
 EXPORT_SYMBOL(__machine_arch_type);
 
@@ -131,12 +132,24 @@
 EXPORT_SYMBOL(__csum_ipv6_magic);
 
 	/* io */
-EXPORT_SYMBOL(outsb);
-EXPORT_SYMBOL(outsw);
-EXPORT_SYMBOL(outsl);
-EXPORT_SYMBOL(insb);
-EXPORT_SYMBOL(insw);
-EXPORT_SYMBOL(insl);
+#ifndef __raw_readsb
+EXPORT_SYMBOL_NOVERS(__raw_readsb);
+#endif
+#ifndef __raw_readsw
+EXPORT_SYMBOL_NOVERS(__raw_readsw);
+#endif
+#ifndef __raw_readsl
+EXPORT_SYMBOL_NOVERS(__raw_readsl);
+#endif
+#ifndef __raw_writesb
+EXPORT_SYMBOL_NOVERS(__raw_writesb);
+#endif
+#ifndef __raw_writesw
+EXPORT_SYMBOL_NOVERS(__raw_writesw);
+#endif
+#ifndef __raw_writesl
+EXPORT_SYMBOL_NOVERS(__raw_writesl);
+#endif
 
 	/* address translation */
 #ifndef __virt_to_phys__is_a_macro
@@ -155,8 +168,6 @@
 #ifndef CONFIG_NO_PGT_CACHE
 EXPORT_SYMBOL(quicklists);
 #endif
-EXPORT_SYMBOL(__handle_bad_pmd);
-EXPORT_SYMBOL(__handle_bad_pmd_kernel);
 
 	/* string / mem functions */
 EXPORT_SYMBOL_NOVERS(strcpy);
@@ -243,8 +254,5 @@
 EXPORT_SYMBOL_NOVERS(__down_interruptible_failed);
 EXPORT_SYMBOL_NOVERS(__down_trylock_failed);
 EXPORT_SYMBOL_NOVERS(__up_wakeup);
-EXPORT_SYMBOL_NOVERS(__down_read_failed);
-EXPORT_SYMBOL_NOVERS(__down_write_failed);
-EXPORT_SYMBOL_NOVERS(__rwsem_wake);
 
 EXPORT_SYMBOL(get_wchan);
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/calls.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/calls.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/calls.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/calls.S	2004-12-06 19:35:49.000000000 +0100
@@ -13,6 +13,7 @@
 #define NR_syscalls 256
 #else
 
+__syscall_start:
 /* 0 */		.long	SYMBOL_NAME(sys_ni_syscall)
 		.long	SYMBOL_NAME(sys_exit)
 		.long	SYMBOL_NAME(sys_fork_wrapper)
@@ -176,7 +177,7 @@
 /* 160 */	.long	SYMBOL_NAME(sys_sched_get_priority_min)
 		.long	SYMBOL_NAME(sys_sched_rr_get_interval)
 		.long	SYMBOL_NAME(sys_nanosleep)
-		.long	SYMBOL_NAME(sys_mremap)
+		.long	SYMBOL_NAME(sys_arm_mremap)
 		.long	SYMBOL_NAME(sys_setresuid16)
 /* 165 */	.long	SYMBOL_NAME(sys_getresuid16)
 		.long	SYMBOL_NAME(sys_ni_syscall)
@@ -231,8 +232,13 @@
 /* 215 */	.long	SYMBOL_NAME(sys_setfsuid)
 		.long	SYMBOL_NAME(sys_setfsgid)
 		.long	SYMBOL_NAME(sys_getdents64)
+		.long	SYMBOL_NAME(sys_pivot_root)
+		.long	SYMBOL_NAME(sys_mincore)
+/* 220 */	.long	SYMBOL_NAME(sys_madvise)
+		.long	SYMBOL_NAME(sys_fcntl64)
+__syscall_end:
 
-		.rept	NR_syscalls-217
+		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
 			.long	SYMBOL_NAME(sys_ni_syscall)
 		.endr
 #endif
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/dma.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/dma.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/dma.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/dma.c	2004-12-06 19:35:49.000000000 +0100
@@ -12,7 +12,7 @@
  *  DMA facilities.
  */
 #include <linux/module.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/mman.h>
 #include <linux/init.h>
@@ -139,7 +139,7 @@
 
 	dma->sg = &dma->buf;
 	dma->sgcount = 1;
-	dma->buf.address = (void*)bus_to_virt(physaddr);
+	dma->buf.address = bus_to_virt(physaddr);
 	dma->using_sg = 0;
 	dma->invalid = 1;
 }
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/ecard.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/ecard.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/ecard.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/ecard.c	2004-12-06 19:35:49.000000000 +0100
@@ -26,7 +26,6 @@
  *  17-Apr-1999	RMK	Support for EASI Type C cycles.
  */
 #define ECARD_C
-#define __KERNEL_SYSCALLS__
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -34,9 +33,11 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/reboot.h>
 #include <linux/mm.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/notifier.h>
 #include <linux/init.h>
 
 #include <asm/dma.h>
@@ -54,7 +55,7 @@
 
 enum req {
 	req_readbytes,
-	req_reset
+	req_reset_all
 };
 
 struct ecard_request {
@@ -135,19 +136,14 @@
 #define POD_INT_ADDR(x)	((volatile unsigned char *)\
 			 ((BUS_ADDR((x)) - IO_BASE) + IO_START))
 
-static void
-ecard_task_reset(struct ecard_request *req)
+static inline void ecard_task_reset(void)
 {
-	if (req->ec == NULL) {
-		ecard_t *ec;
+	ecard_t *ec;
 
-		for (ec = cards; ec; ec = ec->next)
-			if (ec->loader)
-				ecard_loader_reset(POD_INT_ADDR(ec->podaddr),
-						   ec->loader);
-	} else if (req->ec->loader)
-		ecard_loader_reset(POD_INT_ADDR(req->ec->podaddr),
-				   req->ec->loader);
+	for (ec = cards; ec; ec = ec->next)
+		if (ec->loader)
+			ecard_loader_reset(POD_INT_ADDR(ec->podaddr),
+					   ec->loader);
 }
 
 static void
@@ -157,48 +153,47 @@
 	volatile unsigned char *base_addr =
 		(volatile unsigned char *)POD_INT_ADDR(req->ec->podaddr);
 	unsigned int len = req->length;
+	unsigned int off = req->address;
 
 	if (req->ec->slot_no == 8) {
 		/*
-		 * The card maintains an index which
-		 * increments the address into a 4096-byte
-		 * page on each access.  We need to keep
+		 * The card maintains an index which increments the address
+		 * into a 4096-byte page on each access.  We need to keep
 		 * track of the counter.
 		 */
 		static unsigned int index;
-		unsigned int offset, page;
-		unsigned char byte = 0; /* keep gcc quiet */
-
-		offset = req->address & 4095;
-		page   = req->address >> 12;
+		unsigned int page;
 
-		if (page > 256)
+		page = (off >> 12) * 4;
+		if (page > 256 * 4)
 			return;
 
-		page *= 4;
+		off &= 4095;
 
-		if (offset == 0 || index > offset) {
-			/*
-			 * We need to reset the index counter.
-			 */
+		/*
+		 * If we are reading offset 0, or our current index is
+		 * greater than the offset, reset the hardware index counter.
+		 */
+		if (off == 0 || index > off) {
 			*base_addr = 0;
 			index = 0;
 		}
 
-		while (index <= offset) {
+		/*
+		 * Increment the hardware index counter until we get to the
+		 * required offset.  The read bytes are discarded.
+		 */
+		while (index < off) {
+			unsigned char byte;
 			byte = base_addr[page];
 			index += 1;
 		}
 
 		while (len--) {
-			*buf++ = byte;
-			if (len) {
-				byte = base_addr[page];
-				index += 1;
-			}
+			*buf++ = base_addr[page];
+			index += 1;
 		}
 	} else {
-		unsigned int off = req->address;
 
 		if (!req->use_loader || !req->ec->loader) {
 			off *= 4;
@@ -221,12 +216,26 @@
 
 }
 
+static void ecard_do_request(struct ecard_request *req)
+{
+	switch (req->req) {
+	case req_readbytes:
+		ecard_task_readbytes(req);
+		break;
+
+	case req_reset_all:
+		ecard_task_reset();
+		break;
+	}
+}
+
 #ifdef CONFIG_CPU_32
 static pid_t ecard_pid;
 static wait_queue_head_t ecard_wait;
-static wait_queue_head_t ecard_done;
 static struct ecard_request *ecard_req;
 
+static DECLARE_MUTEX_LOCKED(ecard_done_sem);
+
 /*
  * Set up the expansion card daemon's page tables.
  */
@@ -318,16 +327,8 @@
 			}
 		} while (req == NULL);
 
-		switch (req->req) {
-		case req_readbytes:
-			ecard_task_readbytes(req);
-			break;
-
-		case req_reset:
-			ecard_task_reset(req);
-			break;
-		}
-		wake_up(&ecard_done);
+		ecard_do_request(req);
+		up(&ecard_done_sem);
 	}
 }
 
@@ -337,76 +338,91 @@
  * FIXME: The test here is not sufficient to detect if the
  * kcardd is running.
  */
-static inline void
+static void
 ecard_call(struct ecard_request *req)
 {
 	/*
-	 * If we're called from task 0, or from an
-	 * interrupt (will be keyboard interrupt),
-	 * we forcefully set up the memory map, and
-	 * call the loader.  We can't schedule, or
-	 * sleep for this call.
+	 * Make sure we have a context that is able to sleep.
 	 */
-	if ((current == &init_task || in_interrupt()) &&
-	    req->req == req_reset && req->ec == NULL) {
-		ecard_init_pgtables(current->mm);
-		ecard_task_reset(req);
-	} else {
-		if (ecard_pid <= 0)
-			ecard_pid = kernel_thread(ecard_task, NULL,
-					CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+	if (current == &init_task || in_interrupt())
+		BUG();
 
-		ecard_req = req;
+	if (ecard_pid <= 0)
+		ecard_pid = kernel_thread(ecard_task, NULL,
+				CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 
-		wake_up(&ecard_wait);
+	ecard_req = req;
+	wake_up(&ecard_wait);
 
-		sleep_on(&ecard_done);
-	}
+	/*
+	 * Now wait for kecardd to run.
+	 */
+	down(&ecard_done_sem);
 }
 #else
 /*
  * On 26-bit processors, we don't need the kcardd thread to access the
  * expansion card loaders.  We do it directly.
  */
-static inline void
-ecard_call(struct ecard_request *req)
-{
-	if (req->req == req_reset)
-		ecard_task_reset(req);
-	else
-		ecard_task_readbytes(req);
-}
+#define ecard_call(req)	ecard_do_request(req)
 #endif
 
 /* ======================= Mid-level card control ===================== */
+
 /*
- * This is called to reset the loaders for each expansion card on reboot.
+ * This function is responsible for resetting the expansion cards to a
+ * sensible state immediately prior to rebooting the system.  This function
+ * has process state (keventd), so we can sleep.
  *
- * This is required to make sure that the card is in the correct state
- * that RiscOS expects it to be.
+ * Possible "val" values here:
+ *  SYS_RESTART   -  restarting system
+ *  SYS_HALT      - halting system
+ *  SYS_POWER_OFF - powering down system
+ *
+ * We ignore all calls, unless it is a SYS_RESTART call - power down/halts
+ * will be followed by a SYS_RESTART if ctrl-alt-del is pressed again.
  */
-void
-ecard_reset(int slot)
+static int ecard_reboot(struct notifier_block *me, unsigned long val, void *v)
 {
 	struct ecard_request req;
 
-	req.req = req_reset;
+	if (val != SYS_RESTART)
+		return 0;
 
-	if (slot < 0)
-		req.ec = NULL;
-	else
-		req.ec = slot_to_ecard(slot);
+	/*
+	 * Disable the expansion card interrupt
+	 */
+	disable_irq(IRQ_EXPANSIONCARD);
 
+	/*
+	 * If we have any expansion card loader code which will handle
+	 * the reset for us, call it now.
+	 */
+	req.req = req_reset_all;
 	ecard_call(&req);
 
+	/*
+	 * Disable the expansion card interrupt again, just to be sure.
+	 */
+	disable_irq(IRQ_EXPANSIONCARD);
+
+	/*
+	 * Finally, reset the expansion card interrupt mask to
+	 * all enable (RISC OS doesn't set this)
+	 */
 #ifdef HAS_EXPMASK
-	if (have_expmask && slot < 0) {
-		have_expmask |= ~0;
-		__raw_writeb(have_expmask, EXPMASK_ENABLE);
-	}
+	have_expmask = ~0;
+	__raw_writeb(have_expmask, EXPMASK_ENABLE);
 #endif
+	return 0;
 }
 
+static struct notifier_block ecard_reboot_notifier = {
+	notifier_call:	ecard_reboot,
+};
+
+
+
 static void
 ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
 {
@@ -893,9 +909,8 @@
 	int i, rc = -ENOMEM;
 
 	ec = kmalloc(sizeof(ecard_t), GFP_KERNEL);
-
 	if (!ec)
-		goto nodev;
+		goto nomem;
 
 	memset(ec, 0, sizeof(ecard_t));
 
@@ -967,22 +982,16 @@
 	if (slot < 2)
 		ec->dma = 2 + slot;
 #endif
-#if 0	/* We don't support FIQs on expansion cards at the moment */
-	ec->fiq = 96 + slot;
-#endif
-
-	rc = 0;
 
 	for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
 
 	*ecp = ec;
+	slot_to_expcard[slot] = ec;
+	return 0;
 
 nodev:
-	if (rc && ec)
-		kfree(ec);
-	else
-		slot_to_expcard[slot] = ec;
-
+	kfree(ec);
+nomem:
 	return rc;
 }
 
@@ -1051,9 +1060,13 @@
 {
 	int slot;
 
+	/*
+	 * Register our reboot notifier
+	 */
+	register_reboot_notifier(&ecard_reboot_notifier);
+
 #ifdef CONFIG_CPU_32
 	init_waitqueue_head(&ecard_wait);
-	init_waitqueue_head(&ecard_done);
 #endif
 
 	printk("Probing expansion cards\n");
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/entry-armv.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/entry-armv.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/entry-armv.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/entry-armv.S	2004-12-06 19:35:49.000000000 +0100
@@ -13,62 +13,8 @@
  *  Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
  *  it to save wrong values...  Be aware!
  */
-#include <linux/config.h> /* for CONFIG_ARCH_xxxx */
-#include <linux/linkage.h>
-
-#include <asm/assembler.h>
-#include <asm/constants.h>
-#include <asm/errno.h>
-#include <asm/hardware.h>
-#include <asm/arch/irqs.h>
-#include <asm/proc-fns.h>
-
-
-#ifndef MODE_SVC
-#define MODE_SVC 0x13
-#endif
-
-		.macro	zero_fp
-#ifndef CONFIG_NO_FRAME_POINTER
-		mov	fp, #0
-#endif
-		.endm
-
-		.text
-
-@ Bad Abort numbers
-@ -----------------
-@
-#define BAD_PREFETCH	0
-#define BAD_DATA	1
-#define BAD_ADDREXCPTN	2
-#define BAD_IRQ		3
-#define BAD_UNDEFINSTR	4
-
-@
-@ Stack format (ensured by USER_* and SVC_*)
-@
-#define S_FRAME_SIZE	72
-#define S_OLD_R0	68
-#define S_PSR		64
-#define S_PC		60
-#define S_LR		56
-#define S_SP		52
-#define S_IP		48
-#define S_FP		44
-#define S_R10		40
-#define S_R9		36
-#define S_R8		32
-#define S_R7		28
-#define S_R6		24
-#define S_R5		20
-#define S_R4		16
-#define S_R3		12
-#define S_R2		8
-#define S_R1		4
-#define S_R0		0
-
-#define OFF_CR_ALIGNMENT(x)	cr_alignment - x
+#include <linux/config.h>
+#include "entry-header.S"
 
 #ifdef IOC_BASE
 /* IOC / IOMD based hardware */
@@ -89,41 +35,52 @@
 		.if	ioc_base_low
 		orr	r4, r4, #ioc_base_low
 		.endif
-		ldrb	\irqstat, [r4, #0x24]		@ get high priority first
-		adr	\base, irq_prio_h
+		ldrb	\irqstat, [r4, #IOMD_IRQREQB]	@ get high priority first
+		ldr	\base, =irq_prio_h
 		teq	\irqstat, #0
 #ifdef IOMD_BASE
-		ldreqb	\irqstat, [r4, #0x1f4]		@ get dma
-		adreq	\base, irq_prio_d
+		ldreqb	\irqstat, [r4, #IOMD_DMAREQ]	@ get dma
+		addeq	\base, \base, #256		@ irq_prio_h table size
 		teqeq	\irqstat, #0
+		bne	2406f
 #endif
-		ldreqb	\irqstat, [r4, #0x14]		@ get low priority
-		adreq	\base, irq_prio_l
-
-		teq	\irqstat, #0
-		ldrneb	\irqnr, [\base, \irqstat]	@ get IRQ number
+		ldreqb	\irqstat, [r4, #IOMD_IRQREQA]	@ get low priority
+		addeq	\base, \base, #256		@ irq_prio_d table size
+		teqeq	\irqstat, #0
+#ifdef IOMD_IRQREQC
+		ldreqb	\irqstat, [r4, #IOMD_IRQREQC]
+		addeq	\base, \base, #256		@ irq_prio_l table size
+		teqeq	\irqstat, #0
+#endif
+#ifdef IOMD_IRQREQD
+		ldreqb	\irqstat, [r4, #IOMD_IRQREQD]
+		addeq	\base, \base, #256		@ irq_prio_lc table size
+		teqeq	\irqstat, #0
+#endif
+2406:		ldrneb	\irqnr, [\base, \irqstat]	@ get IRQ number
 		.endm
 
 /*
- * Interrupt table (incorporates priority)
+ * Interrupt table (incorporates priority).  Please note that we
+ * rely on the order of these tables (see above code).
  */
 		.macro	irq_prio_table
-irq_prio_l:	.byte	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+irq_prio_h:	.byte	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
 #ifdef IOMD_BASE
 irq_prio_d:	.byte	 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
 		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
@@ -142,26 +99,64 @@
 		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
 		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
 #endif
-irq_prio_h:	.byte	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+irq_prio_l:	.byte	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+#ifdef IOMD_IRQREQC
+irq_prio_lc:	.byte	24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
+		.byte	28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
+		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+#endif
+#ifdef IOMD_IRQREQD
+irq_prio_ld:	.byte	40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
+		.byte	44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
+		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+#endif
 		.endm
 
 #elif defined(CONFIG_ARCH_EBSA110)
 
+#define IRQ_STAT		0xff000000	/* read */
+
 		.macro	disable_fiq
 		.endm
 
@@ -457,7 +452,9 @@
 		.macro	irq_prio_table
 		.endm
 
-#elif defined(CONFIG_ARCH_P720T)
+#elif defined(CONFIG_ARCH_CLPS711X)
+
+#include <asm/hardware/clps7111.h>
 
 		.macro	disable_fiq
 		.endm
@@ -501,117 +498,433 @@
 		.macro	irq_prio_table
 		.endm
 
-#elif defined(CONFIG_ARCH_DSC21)
-        /*
-         * Get Int status 0, compare with int mask 0.
-         * Get Int status 1, compare with int mask 1.
-         * Shift masked Int status 1 on top of masked
-         *   Int status 0 (so int 1 #0 would return 0x10).
-         *  Return as irqnr
-         */
-		.macro	get_irqnr_and_base, irqnr, stat, base, mask
-		ldr	r4, =IRQ0_STATUS		@ get low ints
-		ldrh	\irqnr, [r4]			@ save in irqnr
-		ldr	\mask, =IRQ0_ENABLE             @ get low mask
-		ldrh	r1, [\mask]			@ save in r1
-		bic	\irqnr, r1, \irqnr		@ compare with mask
-		ldr	r4, =IRQ1_STATUS                @ get high ints
-		ldrh	\base, [r4]			@ save in base
-		ldr	\mask, =IRQ1_ENABLE
-		ldrh	r1, [\mask]			@ get mask
-		bic	\base, r1, \base		@ compare with mask
-		orr	\irqnr, \irqnr, \base, lsl #4
-                
-		/*  Base should return pointing to priority table  */
- 		adr	\base, irq_prio_dsc21
-		cmp     \irqnr, #0                    
+#elif defined(CONFIG_ARCH_ANAKIN)
+
+		.macro	disable_fiq
 		.endm
-		
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	\base, #IO_BASE
+		mov	\irqstat, #INTERRUPT_CONTROLLER
+		ldr	\tmp, =anakin_irq_mask
+		ldr	\irqstat, [\base, \irqstat]
+		ldr	\tmp, [\tmp]
+		ands	\irqstat, \irqstat, \tmp
+		ldrne	\tmp, =anakin_active_irqs
+		strne	\irqstat, [\tmp]
+		movne	\irqnr, #IRQ_ANAKIN
+		.endm
+
 		.macro	irq_prio_table
-irq_prio_dsc21:
-		.byte   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
+		.ltorg
+		.bss
+ENTRY(anakin_irq_mask)
+		.word	0
+ENTRY(anakin_active_irqs)
+		.space	4
+		.text
 		.endm
 
-	       /* Writes a 0 to Enable FIQ Interrupt lower byte.  I'm using the
-	        * value of the FIQ address to write a 0 to the byte.  If you
-		* want to write to a higher byte, don't use this method.
-		*/
-		.equ efiqr, INTCTRL_REGISTER_BASE & 0x20
+#elif defined(CONFIG_ARCH_CNXT)
+
 		.macro	disable_fiq
-		    mov r12, #efiqr
-		    strb r12, [r12]
 		.endm
 
-#else
-#error Unknown architecture
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+#ifdef CONFIG_ARCH_P52
+
+		ldr	r4, =P52INT_STATUS_M	
+		ldr	\irqstat, [r4]
+
+
+		tst	\irqstat, #P52INT_MASK_TIMER_1 
+		movne	\irqnr, #P52INT_LVL_TIMER_1
+		bne	1001f
+	
+		tst	\irqstat, #P52INT_MASK_TIMER_2
+		movne	\irqnr, #P52INT_LVL_TIMER_2
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_TIMER_3
+		movne	\irqnr, #P52INT_LVL_TIMER_3
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_TIMER_4
+		movne	\irqnr, #P52INT_LVL_TIMER_4
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_USB 
+		movne	\irqnr, #P52INT_LVL_USB 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_HOST
+		movne	\irqnr, #P52INT_LVL_HOST
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_HOST_ERR
+		movne	\irqnr, #P52INT_LVL_HOST_ERR
+		bne	1001f
+	
+		tst	\irqstat, #P52INT_MASK_DMA8 
+		movne	\irqnr, #P52INT_LVL_DMA8 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA6
+		movne	\irqnr, #P52INT_LVL_DMA6
+		bne     1001f
+	
+		tst	\irqstat, #P52INT_MASK_DMA5
+		movne	\irqnr, #P52INT_LVL_DMA5
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA4
+		movne	\irqnr, #P52INT_LVL_DMA4
+		bne	1001f
+	
+		tst	\irqstat, #P52INT_MASK_DMA3
+		movne	\irqnr, #P52INT_LVL_DMA3
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA2
+		movne	\irqnr, #P52INT_LVL_DMA2
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA1
+		movne	\irqnr, #P52INT_LVL_DMA1
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DMA_ERR 
+		movne	\irqnr, #P52INT_LVL_DMA_ERR 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_E2_ERR
+		movne	\irqnr, #P52INT_LVL_E2_ERR
+		bne	1001f
+       
+		tst	\irqstat, #P52INT_MASK_E1_ERR 
+		movne	\irqnr, #P52INT_LVL_E1_ERR 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_DSL
+		movne	\irqnr, #P52INT_LVL_DSL
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_GPIO 
+		movne	\irqnr, #P52INT_LVL_GPIO 
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_COMMTX
+		movne	\irqnr, #P52INT_LVL_COMMTX
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_COMMRX
+		movne	\irqnr, #P52INT_LVL_COMMRX
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_SW1 
+		movne	\irqnr, #P52INT_LVL_SW1
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_SW2
+		movne	\irqnr, #P52INT_LVL_SW2
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_SW3
+		movne	\irqnr, #P52INT_LVL_SW3
+		bne	1001f
+
+		tst	\irqstat, #P52INT_MASK_SW4
+		movne	\irqnr, #P52INT_LVL_SW4
+1001:
 #endif
 
-/*============================================================================
- * For entry-common.S
- */
+#ifdef CONFIG_ARCH_CX821XX
+	
+		ldr	r4, =CNXT_INT_STATUS_M	
+		ldr	\irqstat, [r4]
 
-		.macro	save_user_regs
-		sub	sp, sp, #S_FRAME_SIZE
-		stmia	sp, {r0 - r12}			@ Calling r0 - r12
-		add	r8, sp, #S_PC
-		stmdb	r8, {sp, lr}^			@ Calling sp, lr
-		str	lr, [r8, #0]			@ Save calling PC
-		mrs	r6, spsr
-		str	r6, [r8, #4]			@ Save CPSR
-		str	r0, [r8, #8]			@ Save OLD_R0
-		.endm
-
-		.macro	restore_user_regs
-		ldr	r0, [sp, #S_PSR]		@ Get calling cpsr
-		mov	ip, #I_BIT | MODE_SVC
-		msr	cpsr_c, ip			@ disable IRQs
-		msr	spsr, r0			@ save in spsr_svc
-		ldmia	sp, {r0 - lr}^			@ Get calling r0 - lr
-		mov	r0, r0
-		ldr	lr, [sp, #S_PC]			@ Get PC
-		add	sp, sp, #S_FRAME_SIZE
-		movs	pc, lr				@ return & move spsr_svc into cpsr
-		.endm
-
-		.macro	mask_pc, rd, rm
-		.endm
-
-		/* If we're optimising for StrongARM the resulting code won't 
-		   run on an ARM7 and we can save a couple of instructions.  
-									--pb */
-		.macro	arm700_bug_check, instr, temp
-#ifndef __ARM_ARCH_4__
-		and	\temp, \instr, #0x0f000000	@ check for SWI
-		teq	\temp, #0x0f000000
-		bne	.Larm700bug
+		tst	\irqstat, #CNXT_INT_MASK_DMA1
+		movne	\irqnr, #CNXT_INT_LVL_DMA1
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA3
+		movne	\irqnr, #CNXT_INT_LVL_DMA3
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA2
+		movne	\irqnr, #CNXT_INT_LVL_DMA2
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA4
+		movne	\irqnr, #CNXT_INT_LVL_DMA4
+		bne	1001f
+	
+		tst	\irqstat, #CNXT_INT_MASK_E1_ERR 
+		movne	\irqnr, #CNXT_INT_LVL_E1_ERR 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_E2_ERR
+		movne	\irqnr, #CNXT_INT_LVL_E2_ERR
+		bne	1001f
+       
+		tst	\irqstat, #CNXT_INT_MASK_TIMER_1 
+		movne	\irqnr, #CNXT_INT_LVL_TIMER_1
+		bne	1001f
+	
+		tst	\irqstat, #CNXT_INT_MASK_TIMER_2
+		movne	\irqnr, #CNXT_INT_LVL_TIMER_2
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_TIMER_3
+		movne	\irqnr, #CNXT_INT_LVL_TIMER_3
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_TIMER_4
+		movne	\irqnr, #CNXT_INT_LVL_TIMER_4
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_USB 
+		movne	\irqnr, #CNXT_INT_LVL_USB 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_HOST
+		movne	\irqnr, #CNXT_INT_LVL_HOST
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_HOST_ERR
+		movne	\irqnr, #CNXT_INT_LVL_HOST_ERR
+		bne	1001f
+	
+		tst	\irqstat, #CNXT_INT_MASK_DMA8 
+		movne	\irqnr, #CNXT_INT_LVL_DMA8 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA6
+		movne	\irqnr, #CNXT_INT_LVL_DMA6
+		bne     1001f
+	
+		tst	\irqstat, #CNXT_INT_MASK_DMA5
+		movne	\irqnr, #CNXT_INT_LVL_DMA5
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DMA_ERR 
+		movne	\irqnr, #CNXT_INT_LVL_DMA_ERR 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_DSL
+		movne	\irqnr, #CNXT_INT_LVL_DSL
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_GPIO 
+		movne	\irqnr, #CNXT_INT_LVL_GPIO 
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_COMMTX
+		movne	\irqnr, #CNXT_INT_LVL_COMMTX
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_COMMRX
+		movne	\irqnr, #CNXT_INT_LVL_COMMRX
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_SW1 
+		movne	\irqnr, #CNXT_INT_LVL_SW1
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_SW2
+		movne	\irqnr, #CNXT_INT_LVL_SW2
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_SW3
+		movne	\irqnr, #CNXT_INT_LVL_SW3
+		bne	1001f
+
+		tst	\irqstat, #CNXT_INT_MASK_SW4
+		movne	\irqnr, #CNXT_INT_LVL_SW4
+
+	
+1001:
 #endif
+		
+#ifdef CONFIG_ARCH_CX861XX
+
+		ldr	r4, =PIC_TOP_MISR_IRQ
+		ldr	\irqstat, [r4]
+
+		tst	\irqstat, #INT_MASK_DMA_TX_A 
+		movne	\irqnr, #INT_SRC_DMA_TX_A
+		bne	1001f
+	
+		tst	\irqstat, #INT_MASK_DMA_TX_B
+		movne	\irqnr, #INT_SRC_DMA_TX_B
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_DMA_RX_A
+		movne	\irqnr, #INT_SRC_DMA_RX_A
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_DMA_RX_B
+		movne	\irqnr, #INT_SRC_DMA_RX_B
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_GPIO_A
+		movne	\irqnr, #INT_SRC_GPIO_A
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_GPIO_B
+		movne	\irqnr, #INT_SRC_GPIO_B
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_GPIO_C
+		movne	\irqnr, #INT_SRC_GPIO_C
+		bne	1001f
+	
+		tst	\irqstat, #INT_MASK_GPIO_D
+		movne	\irqnr, #INT_SRC_GPIO_D
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_EMAC_A
+		movne	\irqnr, #INT_SRC_EMAC_A
+		bne     1001f
+	
+		tst	\irqstat, #INT_MASK_EMAC_B
+		movne	\irqnr, #INT_SRC_EMAC_B
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_PPI
+		movne	\irqnr, #INT_SRC_PPI
+		bne	1001f
+	
+		tst	\irqstat, #INT_MASK_UART
+		movne	\irqnr, #INT_SRC_UART
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_USB_DEVICE
+		movne	\irqnr, #INT_SRC_USB_DEVICE
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_ADSL
+		movne	\irqnr, #INT_SRC_ADSL
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_TIMER_INTA
+		movne	\irqnr, #INT_SRC_TIMER_INTA
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_TIMER_INTB
+		movne	\irqnr, #INT_SRC_TIMER_INTB
+		bne	1001f
+       
+		tst	\irqstat, #INT_MASK_VOICE
+		movne	\irqnr, #INT_SRC_VOICE
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_USB_HOST
+		movne	\irqnr, #INT_SRC_USB_HOST
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_3DES
+		movne	\irqnr, #INT_SRC_3DES
+		bne	1001f
+
+		tst	\irqstat, #INT_MASK_MISC
+		movne	\irqnr, #INT_SRC_MISC
+1001:
+#endif
+
+#ifdef CONFIG_ARCH_SPIPE
+		@
+		@ not been tested 
+		@	
+		ldr	r4, =0x350044
+		ldr	\irqnr, [r4]	
+		
+		mov r5,#0
+icloopusr:
+		cmp r5,#31
+		ble icshftusr
+		b icendusr
+icshftusr:
+		mov r4,r6,lsr r5		@ shift untill we get one
+		and r0,r4,#1			@ int priority is in the status
+		cmp r0,#0
+		beq incicusr
+		b icendusr
+incicusr:
+		add r5,r5,#1
+		b icloopusr
+		
+icendusr:		 
+		mov	r0, r5
+#endif
+
 		.endm
 
-		.macro	enable_irqs, temp
-		mrs	\temp, cpsr
-		bic	\temp, \temp, #I_BIT
-		msr	cpsr, \temp
+		.macro	irq_prio_table
 		.endm
+	
+#elif defined(CONFIG_ARCH_ATMEL)
 
-		.macro	get_current_task, rd
-		mov	\rd, sp, lsr #13
-		mov	\rd, \rd, lsl #13
+		.macro	disable_fiq
 		.endm
 
-		/*
-		 * Like adr, but force SVC mode (if required)
-		 */
-		.macro	adrsvc, cond, reg, label
-		adr\cond	\reg, \label
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	r4, =AIC_IVR
+		ldr	\irqnr, [r4]		@ignore value
+		ldr	r4, =AIC_ISR		@read interrupt nr.
+		ldr	\irqnr, [r4]
+		teq	\irqnr, #0
+
+		ldreq	r4, =AIC_EOICR		@ EOI
+		streq	r4, [r4]		@ value=dont care
 		.endm
 
-		.macro	alignment_trap, rbase, rtemp, sym
-#ifdef CONFIG_ALIGNMENT_TRAP
-		ldr	\rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
-		mcr	p15, 0, \rtemp, c1, c0
-#endif
+		.macro	irq_prio_table
 		.endm
 
+#elif	defined(CONFIG_ARCH_S3C4)
+
+		.macro	disable_fiq
+		.endm
+		
+	#if	defined(CONFIG_CPU_S3C4530)
+	
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	r4, =INTOSET_IRQ
+		ldr	\irqnr, [r4]
+		
+		/*  To be differentiated from interrupt pending priority "0",
+		    if all interrupt pending bits are "0" when read INTOSET_IRQ
+		    register, the return value is "0x54". We will get interrupt
+		    number "21" if don't check it.
+								    OZH.   */
+		teq	\irqnr, #0x54
+		beq	1001f
+		
+		mov	\irqnr, \irqnr, lsr #2	/* Get the interrupt number	*/
+		
+		/* Check for masked interrupt	*/
+		mov	r4, #1			
+		mov 	r4, r4, lsl \irqnr
+		ldr	r5, =INTMSK
+		ldr	r5, [r5]
+		mvn	r5, r5
+		tst	r5, r4
+		
+@		and	r4, r4, r5
+@		teq	r4, r5
+1001:
+		.endm
+	#endif
+		.macro	irq_prio_table
+		.endm
+		
+#else
+#error Unknown architecture
+#endif
+
 /*
  * Invalid mode handlers
  */
@@ -646,15 +959,15 @@
 		and	r2, r6, #31			@ int mode
 		b	SYMBOL_NAME(bad_mode)
 
-#ifdef CONFIG_NWFPE
+#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
 		/* The FPE is always present */
 		.equ	fpe_not_present, 0
 #else
 wfs_mask_data:	.word	0x0e200110			@ WFS/RFS
 		.word	0x0fef0fff
-		.word	0x0d0d0100			@ LDF [sp]/STF [sp]
-		.word	0x0d0b0100			@ LDF [fp]/STF [fp]
-		.word	0x0f0f0f00
+		.word	0x0d000100			@ LDF [sp]/STF [sp]
+		.word	0x0d000100			@ LDF [fp]/STF [fp]
+		.word	0x0f000f00
 
 /* We get here if an undefined instruction happens and the floating
  * point emulator is not present.  If the offending instruction was
@@ -725,7 +1038,7 @@
 
 		.align	5
 __irq_svc:	sub	sp, sp, #S_FRAME_SIZE
-		stmia	sp, {r0 - r12}			@ save r0 - r12
+		stmia	sp, {r0 - r12}			@ save r0 - r1
 		ldr	r7, .LCirq
 		add	r5, sp, #S_FRAME_SIZE
 		ldmia	r7, {r7 - r9}
@@ -796,9 +1109,6 @@
 .LCprocfns:	.word	SYMBOL_NAME(processor)
 #endif
 .LCfp:		.word	SYMBOL_NAME(fp_enter)
-#ifdef CONFIG_ALIGNMENT_TRAP
-.LCswi:		.word	SYMBOL_NAME(cr_alignment)
-#endif
 
 		irq_prio_table
 
@@ -825,7 +1135,7 @@
 		mov	r2, #MODE_SVC
 		msr	cpsr_c, r2			@ Enable interrupts
 		mov	r2, sp
-		adrsvc	al, lr, ret_from_sys_call
+		adrsvc	al, lr, ret_from_exception
 		b	SYMBOL_NAME(do_DataAbort)
 
 		.align	5
@@ -845,9 +1155,9 @@
 		@ routine called with r0 = irq number, r1 = struct pt_regs *
 		@
 		bne	do_IRQ
-		mov	r4, #0
-		get_current_task r5
-		b	ret_with_reschedule
+		mov	why, #0
+		get_current_task tsk
+		b	ret_to_user
 
 		.align	5
 __und_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
@@ -859,7 +1169,7 @@
 		stmdb	r8, {sp, lr}^			@ Save user sp, lr
 		alignment_trap r4, r7, __temp_und
 		zero_fp
-		adrsvc	al, r9, ret_from_sys_call	@ r9  = normal FP return
+		adrsvc	al, r9, ret_from_exception	@ r9  = normal FP return
 		adrsvc	al, lr, fpundefinstr		@ lr  = undefined instr return
 
 call_fpe:	get_current_task r10
@@ -873,7 +1183,7 @@
 		msr	cpsr_c, r0			@ Enable interrupts
 		mov	r0, lr
 		mov	r1, sp
-		adrsvc	al, lr, ret_from_sys_call
+		adrsvc	al, lr, ret_from_exception
 		b	SYMBOL_NAME(do_undefinstr)
 
 		.align	5
@@ -891,40 +1201,19 @@
 		mov	r0, r5				@ address (pc)
 		mov	r1, sp				@ regs
 		bl	SYMBOL_NAME(do_PrefetchAbort)	@ call abort handler
-		teq	r0, #0				@ Does this still apply???
-		bne	ret_from_sys_call		@ Return from exception
-#ifdef DEBUG_UNDEF
-		adr	r0, t
-		bl	SYMBOL_NAME(printk)
-#endif
-		mov	r0, r5
-		mov	r1, sp
-		and	r2, r6, #31
-		bl	SYMBOL_NAME(do_undefinstr)
-		ldr	lr, [sp, #S_PSR]		@ Get USR cpsr
-		msr	spsr, lr
-		ldmia	sp, {r0 - pc}^			@ Restore USR registers
-
-#ifdef DEBUG_UNDEF
-t:		.ascii "Prefetch -> undefined instruction\n\0"
-		.align
-#endif
-
-#include "entry-common.S"
+		/* fall through */
+/*
+ * This is the return code to user mode for abort handlers
+ */
+ENTRY(ret_from_exception)
+		get_current_task tsk
+		mov	why, #0
+		b	ret_to_user
 
+		.data
+ENTRY(fp_enter)
+		.word	fpe_not_present
 		.text
-
-#ifndef __ARM_ARCH_4__
-.Larm700bug:	ldr	r0, [sp, #S_PSR]		@ Get calling cpsr
-		str	lr, [r8]
-		msr	spsr, r0
-		ldmia	sp, {r0 - lr}^			@ Get calling r0 - lr
-		mov	r0, r0
-		ldr	lr, [sp, #S_PC]			@ Get PC
-		add	sp, sp, #S_FRAME_SIZE
-		movs	pc, lr
-#endif
-
 /*
  * Register switch for ARMv3 and ARMv4 processors
  * r0 = previous, r1 = next, return previous.
@@ -936,7 +1225,10 @@
 		str	ip, [sp, #-4]!			@ Save cpsr_SVC
 		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
 		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
+#ifndef CONFIG_UCLINUX
 		ldr	r2, [r1, #TSS_DOMAIN]
+		mcr	p15, 0, r2, c3, c0		@ Set domain register
+#endif
 		ldr	ip, [sp], #4
 		msr	spsr, ip			@ Save tasks CPSR into SPSR for this return
 		ldmfd	sp!, {r4 - sl, fp, pc}^		@ Load all regs saved previously
@@ -952,6 +1244,47 @@
 		.align	5
 __stubs_start:
 /*
+ * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode
+ * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
+ */
+vector_undefinstr:
+		@
+		@ save mode specific registers
+		@
+		ldr	r13, .LCsund
+		str	lr, [r13]			@ save lr_UND
+		mrs	lr, spsr
+		str	lr, [r13, #4]			@ save spsr_UND
+		@
+		@ now branch to the relevent MODE handling routine
+		@
+		mov	r13, #I_BIT | MODE_SVC
+		msr	spsr_c, r13			@ switch to SVC_32 mode
+
+		and	lr, lr, #15
+		ldr	lr, [pc, lr, lsl #2]
+		movs	pc, lr				@ Changes mode and branches
+
+.LCtab_und:	.word	__und_usr			@  0 (USR_26 / USR_32)
+		.word	__und_invalid			@  1 (FIQ_26 / FIQ_32)
+		.word	__und_invalid			@  2 (IRQ_26 / IRQ_32)
+		.word	__und_svc			@  3 (SVC_26 / SVC_32)
+		.word	__und_invalid			@  4
+		.word	__und_invalid			@  5
+		.word	__und_invalid			@  6
+		.word	__und_invalid			@  7
+		.word	__und_invalid			@  8
+		.word	__und_invalid			@  9
+		.word	__und_invalid			@  a
+		.word	__und_invalid			@  b
+		.word	__und_invalid			@  c
+		.word	__und_invalid			@  d
+		.word	__und_invalid			@  e
+		.word	__und_invalid			@  f
+
+		.align	5
+
+/*
  * Interrupt dispatcher
  * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
  */
@@ -1075,46 +1408,6 @@
 
 		.align	5
 
-/*
- * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode
- * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
- */
-vector_undefinstr:
-		@
-		@ save mode specific registers
-		@
-		ldr	r13, .LCsund
-		str	lr, [r13]			@ save lr_UND
-		mrs	lr, spsr
-		str	lr, [r13, #4]			@ save spsr_UND
-		@
-		@ now branch to the relevent MODE handling routine
-		@
-		mov	r13, #I_BIT | MODE_SVC
-		msr	spsr_c, r13			@ switch to SVC_32 mode
-
-		and	lr, lr, #15
-		ldr	lr, [pc, lr, lsl #2]
-		movs	pc, lr				@ Changes mode and branches
-
-.LCtab_und:	.word	__und_usr			@  0 (USR_26 / USR_32)
-		.word	__und_invalid			@  1 (FIQ_26 / FIQ_32)
-		.word	__und_invalid			@  2 (IRQ_26 / IRQ_32)
-		.word	__und_svc			@  3 (SVC_26 / SVC_32)
-		.word	__und_invalid			@  4
-		.word	__und_invalid			@  5
-		.word	__und_invalid			@  6
-		.word	__und_invalid			@  7
-		.word	__und_invalid			@  8
-		.word	__und_invalid			@  9
-		.word	__und_invalid			@  a
-		.word	__und_invalid			@  b
-		.word	__und_invalid			@  c
-		.word	__und_invalid			@  d
-		.word	__und_invalid			@  e
-		.word	__und_invalid			@  f
-
-		.align	5
 
 /*=============================================================================
  * Undefined FIQs
@@ -1126,8 +1419,51 @@
  * other mode than FIQ...  Ok you can switch to another mode, but you can't
  * get out of that mode without clobbering one register.
  */
+#ifndef CONFIG_ARCH_CX821XX
 vector_FIQ:	disable_fiq
 		subs	pc, lr, #4
+#else
+/*******************************************************************************
+/	Function:	vector_FIQ
+/	Description:	Handles fast interrupt exception,
+/
+/	Inputs			Working			Outputs
+/	R0  = NA		R0  = 			R0  = Restored
+/	R1  = NA		R1  = 			R1  = Restored
+/	R2  = NA		R2  = 			R2  = Restored
+/	R3  = NA		R3  = 			R3  = Restored
+/	R4  = NA		R4  = 			R4  = Restored
+/	R5  = NA		R5  = 			R5  = Restored
+/	R6  = NA		R6  = 			R6  = Restored
+/	R7  = NA		R7  = 			R7  = Restored
+/	R8  = NA		R8  = 			R8  = Restored
+/	R9  = NA		R9  = 			R9  = Restored
+/	R10 = NA		R10 = 			R10 = Restored
+/	R11 = NA		R11 = 			R11 = Restored
+/	R12 = NA		R12 = 			R12 = Restored
+/
+/ This routine is entered with r8-r14 (r8-r12, SP and LR) replaced by r8_fiq - 
+/ r14_fiq. The CPSR will have been copied to the SPSR_fiq.
+/*******************************************************************************/
+vector_FIQ:
+	/*
+		Adjust return address in LR now since we we return via restoring all regs
+		including the LR, but the LR is restored to the PC (R15).
+	*/
+	sub	lr, lr, #4
+
+	@ Save registers
+	stmfd	sp!, {r0-r7, lr}
+	
+#if 0	
+	@ call the FIQ handler
+	bl	cnxt_do_FIQ
+#endif
+	@ Restore registers and return (The "^" causes the CPSR to be restored from the SPSR)
+	ldmfd	sp!, {r0-r7, pc}^
+#endif
+
+
 
 /*=============================================================================
  * Address exception handler
@@ -1156,7 +1492,11 @@
 		.equ	__real_stubs_start, .LCvectors + 0x200
 
 .LCvectors:	swi	SYS_ERROR0
+#ifdef		CONFIG_UCBOOTSTRAP	/* The uCbootstrap system calls use	*/
+		.word	0xe59ff038	/* an undefined instruction trap 	*/	
+#else
 		b	__real_stubs_start + (vector_undefinstr - __stubs_start)
+#endif
 		ldr	pc, __real_stubs_start + (.LCvswi - __stubs_start)
 		b	__real_stubs_start + (vector_prefetch - __stubs_start)
 		b	__real_stubs_start + (vector_data - __stubs_start)
@@ -1168,7 +1508,6 @@
 		stmfd	sp!, {r4 - r6, lr}
 
 		adr	r1, .LCvectors			@ set up the vectors
-		mov	r0, #0
 		ldmia	r1, {r1, r2, r3, r4, r5, r6, ip, lr}
 		stmia	r0, {r1, r2, r3, r4, r5, r6, ip, lr}
 
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/entry-common.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/entry-common.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/entry-common.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/entry-common.S	2004-12-06 19:35:49.000000000 +0100
@@ -8,71 +8,85 @@
  * published by the Free Software Foundation.
  */
 #include <linux/config.h>
+#include "entry-header.S"
 
-#define PT_TRACESYS	0x00000002
-
-@ OS version number used in SWIs
-@  RISC OS is 0
-@  RISC iX is 8
-@
-#define OS_NUMBER	9
+/* 
+ * We rely on the fact that R0 is at the bottom of the stack (due to
+ * slow/fast restore user regs).
+ */
+#if S_R0 != 0
+#error "Please fix"
+#endif
 
-/*============================================================================
- * All exits to user mode from the kernel go through this code.
+/*
+ * Our do_softirq out of line code.  See include/asm-arm/softirq.h for
+ * the calling assembly.
  */
+	.section ".text.lock","ax"
+ENTRY(__do_softirq)
+	stmfd	sp!, {r0 - r3, ip, lr}
+	bl	do_softirq
+	ldmfd	sp!, {r0 - r3, ip, pc}
+	.previous
 
-#define S_OFF		8
+	.align	5
+/*
+ * This is the fast syscall return path.  We do as little as
+ * possible here, and this includes saving r0 back into the SVC
+ * stack.
+ */
+ret_fast_syscall:
+	ldr	r1, [tsk, #TSK_NEED_RESCHED]
+	ldr	r2, [tsk, #TSK_SIGPENDING]
+	teq	r1, #0				@ need_resched || sigpending
+	teqeq	r2, #0
+	bne	slow
+	fast_restore_user_regs
 
-		.macro	get_softirq, rd
-#ifdef CONFIG_SMP
-#error SMP not supported
-#else
-		ldr	\rd, __irq_stat
-#endif
-		.endm
+/*
+ * Ok, we need to do extra processing, enter the slow path.
+ */
+slow:	str	r0, [sp, #S_R0+S_OFF]!	@ returned r0
+	b	1f
 
-		.globl	ret_from_sys_call
+/*
+ * "slow" syscall return path.  "why" tells us if this was a real syscall.
+ */
+reschedule:
+	bl	SYMBOL_NAME(schedule)
+ENTRY(ret_to_user)
+ret_slow_syscall:
+	ldr	r1, [tsk, #TSK_NEED_RESCHED]
+	ldr	r2, [tsk, #TSK_SIGPENDING]
+1:	teq	r1, #0				@ need_resched => schedule()
+	bne	reschedule
+	teq	r2, #0				@ sigpending => do_signal()
+	blne	__do_signal
+	restore_user_regs
+
+__do_signal:
+	mov	r0, #0				@ NULL 'oldset'
+	mov	r1, sp				@ 'regs'
+	mov	r2, why				@ 'syscall'
+	b	SYMBOL_NAME(do_signal)		@ note the bl above sets lr
 
-		.align	5
-fast_syscall_return:
-		str	r0, [sp, #S_R0 + S_OFF]	@ returned r0
-slow_syscall_return:
-		add	sp, sp, #S_OFF
-ret_from_sys_call:				@ external entry
-		get_softirq r0
-		get_current_task r5
-		ldmia	r0, {r0, r1}		@ softirq_active, softirq_mask
-		mov	r4, #1			@ flag this as being syscall return
-		tst	r0, r1
-		blne	SYMBOL_NAME(do_softirq)
-ret_with_reschedule:				@ external entry (r5 must be set) (__irq_usr)
-		ldr	r0, [r5, #TSK_NEED_RESCHED]
-		ldr	r1, [r5, #TSK_SIGPENDING]
-		teq	r0, #0
-		bne	ret_reschedule
-		teq	r1, #0			@ check for signals
-		blne	ret_signal
-ret_from_all:	restore_user_regs		@ internal
-
-ret_signal:	mov	r1, sp			@ internal
-		mov	r2, r4
-		b	SYMBOL_NAME(do_signal)	@ note the bl above sets lr
-
-ret_reschedule:	adrsvc	al, lr, ret_with_reschedule	@ internal
-		b	SYMBOL_NAME(schedule)
-
-		.globl	ret_from_exception
-ret_from_exception:				@ external entry
-		get_softirq r0
-		get_current_task r5
-		ldmia	r0, {r0, r1}		@ softirq_active, softirq_mask
-		mov	r4, #0
-		tst	r0, r1
-		ldr	r6, [sp, #S_PSR]
-		blne	SYMBOL_NAME(do_softirq)
-		tst	r6, #3			@ returning to user mode?
-		beq	ret_with_reschedule
-		b	ret_from_all
+/*
+ * This is how we return from a fork.  __switch_to will be calling us
+ * with r0 pointing at the previous task that was running (ready for
+ * calling schedule_tail).
+ */
+ENTRY(ret_from_fork)
+	bl	SYMBOL_NAME(schedule_tail)
+	get_current_task tsk
+	ldr	ip, [tsk, #TSK_PTRACE]		@ check for syscall tracing
+	mov	why, #1
+	tst	ip, #PT_TRACESYS		@ are we tracing syscalls?
+	beq	ret_slow_syscall
+	mov	r1, sp
+	mov	r0, #1				@ trace exit [IP = 1]
+	bl	SYMBOL_NAME(syscall_trace)
+	b	ret_slow_syscall
+	
 
 #include "calls.S"
 
@@ -81,76 +95,102 @@
  *-----------------------------------------------------------------------------
  */
 
-/*
- * Create some aliases for some registers.  These should allow
- * us to have in theory up to 7 arguments to a function.
- */
-scno		.req	r9			@ syscall number
-tbl		.req	r8			@ syscall table pointer
-tip		.req	r7			@ temporary IP
-
-		.align	5
-vector_swi:	save_user_regs
-		mask_pc	lr, lr
-		zero_fp
-		ldr	scno, [lr, #-4]		@ get SWI instruction
-		arm700_bug_check scno, ip
+	/* If we're optimising for StrongARM the resulting code won't 
+	   run on an ARM7 and we can save a couple of instructions.  
+								--pb */
+#ifdef CONFIG_CPU_ARM710
+	.macro	arm710_bug_check, instr, temp
+	and	\temp, \instr, #0x0f000000	@ check for SWI
+	teq	\temp, #0x0f000000
+	bne	.Larm700bug
+	.endm
+
+.Larm700bug:
+	ldr	r0, [sp, #S_PSR]		@ Get calling cpsr
+	sub	lr, lr, #4
+	str	lr, [r8]
+	msr	spsr, r0
+	ldmia	sp, {r0 - lr}^			@ Get calling r0 - lr
+	mov	r0, r0
+	ldr	lr, [sp, #S_PC]			@ Get PC
+	add	sp, sp, #S_FRAME_SIZE
+	movs	pc, lr
+#else
+	.macro	arm710_bug_check, instr, temp
+	.endm
+#endif
+
+	.align	5
+ENTRY(vector_swi)
+	save_user_regs
+	mask_pc	lr, lr
+	zero_fp
+	ldr	scno, [lr, #-4]			@ get SWI instruction
+	arm710_bug_check scno, ip
+
 #ifdef CONFIG_ALIGNMENT_TRAP
-		ldr	ip, .LCswi
-		ldr	ip, [ip]
-		mcr	p15, 0, ip, c1, c0
+	ldr	ip, __cr_alignment
+	ldr	ip, [ip]
+	mcr	p15, 0, ip, c1, c0		@ update control register
+	/* NEW CODE */
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	/* NEW CODE */
 #endif
-		enable_irqs ip
+	enable_irqs ip
+
+	str	r4, [sp, #-S_OFF]!		@ push fifth arg
 
-		str	r4, [sp, #-S_OFF]!	@ push fifth arg
-		adrsvc	al, lr, fast_syscall_return
+	get_current_task tsk
+	ldr	ip, [tsk, #TSK_PTRACE]		@ check for syscall tracing
+	bic	scno, scno, #0xff000000		@ mask off SWI op-code
+	eor	scno, scno, #OS_NUMBER << 20	@ check OS number
+	adr	tbl, sys_call_table		@ load syscall table pointer
+	tst	ip, #PT_TRACESYS		@ are we tracing syscalls?
+	bne	__sys_trace
+
+	adrsvc	al, lr, ret_fast_syscall	@ return address
+	cmp	scno, #NR_syscalls		@ check upper syscall limit
+	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
+
+	add	r1, sp, #S_OFF
+2:	mov	why, #0				@ no longer a real syscall
+	cmp	scno, #ARMSWI_OFFSET
+	eor	r0, scno, #OS_NUMBER << 20	@ put OS number back
+	bcs	SYMBOL_NAME(arm_syscall)	
+	b	SYMBOL_NAME(sys_ni_syscall)	@ not private func
+
+	/*
+	 * This is the really slow path.  We're going to be doing
+	 * context switches, and waiting for our parent to respond.
+	 */
+__sys_trace:
+	add	r1, sp, #S_OFF
+	mov	r0, #0				@ trace entry [IP = 0]
+	bl	SYMBOL_NAME(syscall_trace)
+
+	adrsvc	al, lr, __sys_trace_return	@ return address
+	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
+	cmp	scno, #NR_syscalls		@ check upper syscall limit
+	ldmccia	r1, {r0 - r3}			@ have to reload r0 - r3
+	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
+	b	2b
+
+__sys_trace_return:
+	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
+	mov	r1, sp
+	mov	r0, #1				@ trace exit [IP = 1]
+	bl	SYMBOL_NAME(syscall_trace)
+	b	ret_slow_syscall
 
-		bic	scno, scno, #0xff000000	@ mask off SWI op-code
-		eor	scno, scno, #OS_NUMBER<<20	@ check OS number
-		cmp	scno, #NR_syscalls	@ check upper syscall limit
-		bcs	2f
-
-		get_current_task ip
-		ldr	ip, [ip, #TSK_PTRACE]	@ check for syscall tracing
-		adr	tbl, SYMBOL_NAME(sys_call_table)
-		tst	ip, #PT_TRACESYS
-		ldreq	pc, [tbl, scno, lsl #2]	@ call sys routine
-
-		ldr	tip, [sp, #S_IP + S_OFF]	@ save old IP
-		mov	ip, #0
-		str	ip, [sp, #S_IP + S_OFF]	@ trace entry [IP = 0]
-		bl	SYMBOL_NAME(syscall_trace)
-		str	tip, [sp, #S_IP + S_OFF]
-
-		add	ip, sp, #S_OFF
-		ldmia	ip, {r0 - r3}		@ have to reload r0 - r3
-		mov	lr, pc
-		ldr	pc, [tbl, scno, lsl #2]	@ call sys routine
-		str	r0, [sp, #S_R0 + S_OFF]	@ returned r0
-
-		mov	ip, #1
-		str	ip, [sp, #S_IP + S_OFF]	@ trace exit [IP = 1]
-		bl	SYMBOL_NAME(syscall_trace)
-		str	tip, [sp, #S_IP + S_OFF]
-		b	slow_syscall_return
-
-2:		add	r1, sp, #S_OFF
-		tst	scno, #0x00f00000	@ is it a Unix SWI?
-		bne	3f
-		subs	r0, scno, #(KSWI_SYS_BASE - KSWI_BASE)
-		bcs	SYMBOL_NAME(arm_syscall)
-		b	SYMBOL_NAME(sys_ni_syscall) @ not private func
-
-3:		eor	r0, scno, #OS_NUMBER <<20	@ Put OS number back
-		adrsvc	al, lr, slow_syscall_return
-		b	SYMBOL_NAME(deferred)
-
-		.align	5
-		.type	__irq_stat, #object
-__irq_stat:
-		.word	SYMBOL_NAME(irq_stat)
+	.align	5
+#ifdef CONFIG_ALIGNMENT_TRAP
+	.type	__cr_alignment, #object
+__cr_alignment:
+	.word	SYMBOL_NAME(cr_alignment)
+#endif
 
-		.type	sys_call_table, #object
+	.type	sys_call_table, #object
 ENTRY(sys_call_table)
 #include "calls.S"
 
@@ -163,7 +203,6 @@
 SYMBOL_NAME(sys_syscall):
 		eor	scno, r0, #OS_NUMBER << 20
 		cmp	scno, #NR_syscalls	@ check range
-		add	ip, sp, #S_OFF
 		stmleia	sp, {r5, r6}		@ shuffle args
 		movle	r0, r1
 		movle	r1, r2
@@ -224,8 +263,3 @@
 		str	r5, [sp, #4]
 		b	do_mmap2
 #endif
-
-		.data
-
-ENTRY(fp_enter)
-		.word	fpe_not_present
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/fiq.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/fiq.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/fiq.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/fiq.c	2004-12-06 19:35:49.000000000 +0100
@@ -48,7 +48,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#define FIQ_VECTOR 0x1c
+#define FIQ_VECTOR (vectors_base() + 0x1c)
 
 static unsigned long no_fiq_insn;
 
@@ -124,7 +124,7 @@
 #ifdef CONFIG_CPU_26
 	"mov	%0, pc
 	bic	%1, %0, #0x3
-	orr	%1, %1, #0x0c000001
+	orr	%1, %1, %3
 	teqp	%1, #0		@ select FIQ mode
 	mov	r0, r0
 	ldmia	%2, {r8 - r14}
@@ -133,7 +133,7 @@
 #endif
 #ifdef CONFIG_CPU_32
 	"mrs	%0, cpsr
-	mov	%1, #0xc1
+	mov	%1, %3
 	msr	cpsr_c, %1	@ select FIQ mode
 	mov	r0, r0
 	ldmia	%2, {r8 - r14}
@@ -141,7 +141,7 @@
 	mov	r0, r0"
 #endif
 	: "=&r" (tmp), "=&r" (tmp2)
-	: "r" (&regs->ARM_r8)
+	: "r" (&regs->ARM_r8), "I" (I_BIT | F_BIT | FIQ_MODE)
 	/* These registers aren't modified by the above code in a way
 	   visible to the compiler, but we mark them as clobbers anyway
 	   so that GCC won't put any of the input or output operands in
@@ -156,7 +156,7 @@
 #ifdef CONFIG_CPU_26
 	"mov	%0, pc
 	bic	%1, %0, #0x3
-	orr	%1, %1, #0x0c000001
+	orr	%1, %1, %3
 	teqp	%1, #0		@ select FIQ mode
 	mov	r0, r0
 	stmia	%2, {r8 - r14}
@@ -165,7 +165,7 @@
 #endif
 #ifdef CONFIG_CPU_32
 	"mrs	%0, cpsr
-	mov	%1, #0xc1
+	mov	%1, %3
 	msr	cpsr_c, %1	@ select FIQ mode
 	mov	r0, r0
 	stmia	%2, {r8 - r14}
@@ -173,7 +173,7 @@
 	mov	r0, r0"
 #endif
 	: "=&r" (tmp), "=&r" (tmp2)
-	: "r" (&regs->ARM_r8)
+	: "r" (&regs->ARM_r8), "I" (I_BIT | F_BIT | FIQ_MODE)
 	/* These registers aren't modified by the above code in a way
 	   visible to the compiler, but we mark them as clobbers anyway
 	   so that GCC won't put any of the input or output operands in
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/head-armv.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/head-armv.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/head-armv.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/head-armv.S	2004-12-06 19:35:49.000000000 +0100
@@ -30,10 +30,6 @@
  *
  * swapper_pg_dir, pgtbl and krnladr are all closely related.
  */
-#if (TEXTADDR & 0xffff) != 0x8000
-#error TEXTADDR must start at 0xXXXX8000
-#endif
-
 		.globl	SYMBOL_NAME(swapper_pg_dir)
 		.equ	SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
 
@@ -48,7 +44,8 @@
  * containing both.
  */
 		.macro	krnladr, rd, pgtable, rambase
-		bic	\rd, \pgtable, #0x000ff000
+		bic	\rd, \pgtable, #0x00ff000
+		bic	\rd, \rd, #0x0300000
 		.endm
 
 /*
@@ -64,8 +61,10 @@
  * See linux/arch/arm/tools/mach-types for the complete list of numbers
  * for r1.
  */
-		.section ".text.init",#alloc,#execinstr
-		.type	stext, #function
+
+
+.section ".text.init",#alloc,#execinstr
+		.type	stext, #function 
 ENTRY(stext)
 		mov	r12, r0
 /*
@@ -119,17 +118,137 @@
 		orr	r12, r12, #5 << 12
 __entry:
 #endif
-#if defined(CONFIG_ARCH_L7200)
+/*----------------------------------------------------------------------------*/
 /*
  * FIXME - No bootloader, so manually set 'r1' with our architecture number.
  */
+
+#if defined(CONFIG_ARCH_L7200)
 		mov	r1, #MACH_TYPE_L7200
 #elif defined(CONFIG_ARCH_INTEGRATOR)
 		mov	r1, #MACH_TYPE_INTEGRATOR
+#elif defined(CONFIG_ARCH_P52)
+		mov	r1, #MACH_TYPE_P52
+#elif defined(CONFIG_ARCH_CX821XX)
+		mov	r1, #MACH_TYPE_CX821XX
+#elif defined(CONFIG_ARCH_CX861XX)
+		ldr	r1, CX861XX_IDR 
 #endif
+		msr	cpsr_c, # F_BIT | I_BIT | FIQ_MODE	@ Put us in FIRQ mode and turn interrupts off
+		ldr	r13, =_firq_stack_bottom		@ initialize FIRQ stack ptr
 
 		mov	r0, #F_BIT | I_BIT | MODE_SVC	@ make sure svc mode
-		msr	cpsr_c, r0			@ and all irqs disabled
+		msr	cpsr_c, r0						@ and all irqs disabled
+
+#if defined(CONFIG_ARCH_ATMEL)
+
+    		adr	r5, LC0
+    		ldmia	r5, {r5, r6, r8, r9, sp}			@ Setup stack
+
+        /*  Copy data sections to their new home.  */
+        /*  Clear BSS */
+
+    		mov	r4, #0
+1:      	cmp	r5, r8					
+    		strcc	r4, [r5],#4
+    		bcc	1b
+
+/* FIXME */
+#if 0
+        /*  Put initial values into stack.  This would normally be done
+        by sched_init() in kernel/sched.c, but that would overwrite the
+        stack we're already using.  That would be bad.
+        */
+    		mov r5, sp
+    		sub r5, r5, #0x2000
+    		ldr r4, L_STACK_MAGIC
+    		str r4, [r5], #4
+    		ldr r4, L_STACK_UNTOUCHED_MAGIC
+1:      	cmp r5, sp
+    		strcc r4, [r5], #4
+    		bcc 1b
+#endif
+        /*  Pretend we know what our processor code is (for arm_id)   */
+
+@@@		ldr     r2, =0x41000000
+@@@		orr	r2, r2, #0x7000		@ FIXME --> 0x41007000
+
+		ldr	r2, L_AT91_SF_CIDR
+		ldr	r2, [r2]		@ read processor id
+
+		str     r2, [r6]
+		mov     r2, #MACH_TYPE_ATMEL
+		str     r2, [r9]
+
+    		mov 	fp, #0
+    		b	start_kernel
+        
+LC0:		.long	__bss_start
+    		.long	processor_id
+    		.long	_end
+			.long   __machine_arch_type
+    		.long	init_task_union+8192
+#endif
+
+/*----------------------------------------------------------------------------*/
+#if defined(CONFIG_ARCH_S3C4)
+
+		adr	r2, LC0
+		
+#if	defined(CONFIG_ROMKERNEL)
+		@  Copy data sections to their new home
+		ldmia	r2, {r4-r11,sp}
+		cmp	r9, r11
+		beq	2f
+1:		cmp	r9, r10
+		ldrcc	r3, [r9], #4
+		strcc	r3, [r11], #4
+		bcc	1b
+#else
+		ldmia	r2, {r4-r8,sp}
+#endif
+
+2:		mov	r3, #0
+3:  		cmp	r7, r8
+    		strcc	r3, [r7], #4
+    		bcc	3b
+
+#if	defined(CONFIG_CPU_S3C4530)
+		ldr	r3, [r4]		@ read system configuration register
+		bic	r3, r3, #0x83FFFFFF	@ get product identifier
+		str     r3, [r5]		@ store it
+#endif
+#if	defined(CONFIG_BOARD_UCLINKII)
+		mov     r3, #MACH_TYPE_UCLINKII
+		str     r3, [r6]
+#endif
+#if	defined(CONFIG_BOARD_EVS3C4530LII)
+		mov     r3, #MACH_TYPE_EVS3C4530LII
+		str     r3, [r6]
+#endif
+#if	defined(CONFIG_BOARD_EVS3C4530HEI)
+		mov     r3, #MACH_TYPE_EVS3C4530HEI
+		str     r3, [r6]
+#endif
+    		mov 	fp, #0
+    		b	start_kernel
+        
+LC0:		.long	0x3ff0000		@ r4
+    		.long	processor_id		@ r5
+		.long   __machine_arch_type	@ r6
+		.long	__bss_start		@ r7
+		.long	__bss_end		@ r8
+
+#if	defined (CONFIG_ROMKERNEL)
+		.long	__rom_data_start	@ r9
+		.long	__rom_data_end		@ r10
+		.long	__ram_data_start	@ r11
+#endif	/* CONFIG_ROMKERNEL */
+		.long	init_task_union+8192	@ sp
+
+#endif  /* CONFIG_ARCH_S3C4 */
+/*----------------------------------------------------------------------------*/
+
 		bl	__lookup_processor_type
 		teq	r10, #0				@ invalid processor?
 		moveq	r0, #'p'			@ yes, error 'p'
@@ -138,7 +257,10 @@
 		teq	r7, #0				@ invalid architecture?
 		moveq	r0, #'a'			@ yes, error 'a'
 		beq	__error
+	
+#ifndef CONFIG_UCLINUX
 		bl	__create_page_tables
+#endif
 		adr	lr, __ret			@ return address
 		add	pc, r10, #12			@ initialise processor
 							@ (return control reg)
@@ -190,6 +312,8 @@
 
 
 
+#if 1
+/*====================== OUR PAGE TABLE SETUP ==========================*/
 /*
  * Setup the initial page tables.  We only setup the barest
  * amount which are required to get the kernel running, which
@@ -225,23 +349,31 @@
 		 * will be removed by paging_init()
 		 */
 		krnladr	r2, r4, r5			@ start of kernel
-		add	r3, r8, r2			@ flags + kernel base
-		str	r3, [r4, r2, lsr #18]		@ identity mapping
+		add	r3, r8, r2				@ flags + kernel base
+		str	r3, [r4, r2, lsr #18]	@ identity mapping
 
 		/*
 		 * Now setup the pagetables for our kernel direct
 		 * mapped region.  We round TEXTADDR down to the
 		 * nearest megabyte boundary.
 		 */
-		add	r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel
-		add	r0, r0, #(TEXTADDR & 0x00f00000) >> 18
-		str	r3, [r0], #4			@ PAGE_OFFSET + 0MB
+		add	r0, r4, #(0x8000000 & 0xff000000) >> 18 @ start of kernel
+		add	r0, r0, #(0x8000000 & 0x00f00000) >> 18
+
+		mov	r2, r0
+		add	r2, r2, #0x100			@ Load r2 with the last page table entry address
+									@ for 64Mb of SDRAM
+
+2:		str	r3, [r0], #4			@ PAGE_OFFSET + 0MB
 		add	r3, r3, #1 << 20
 		str	r3, [r0], #4			@ PAGE_OFFSET + 1MB
 		add	r3, r3, #1 << 20
 		str	r3, [r0], #4			@ PAGE_OFFSET + 2MB
 		add	r3, r3, #1 << 20
 		str	r3, [r0], #4			@ PAGE_OFFSET + 3MB
+		add	r3, r3, #1 << 20
+		teq	r0, r2
+		bne	2b
 
 		/*
 		 * Ensure that the first section of RAM is present.
@@ -250,6 +382,7 @@
 		 *  2. the kernel is executing in the same 256MB chunk
 		 *     as the start of RAM.
 		 */
+		mov	r5, #0
 		bic	r0, r0, #0x0ff00000 >> 18	@ round down
 		and	r2, r5, #0xf0000000		@ round down
 		add	r3, r8, r2			@ flags + rambase
@@ -257,53 +390,79 @@
 
 		bic	r8, r8, #0x0c			@ turn off cacheable
 							@ and bufferable bits
-#ifdef CONFIG_DEBUG_LL
+		mov	pc, lr
+#else
+/*========================== NOT USED ==============================*/
+/*
+ * Setup the initial page tables.  We only setup the barest
+ * amount which are required to get the kernel running, which
+ * generally means mapping in the kernel code.
+ *
+ * We only map in 4MB of RAM, which should be sufficient in
+ * all cases.
+ *
+ * r5 = physical address of start of RAM
+ * r6 = physical IO address
+ * r7 = byte offset into page tables for IO
+ * r8 = page table flags
+ */
+__create_page_tables:
+		pgtbl	r4, r5				@ page table address
+
 		/*
-		 * Map in IO space for serial debugging.
-		 * This allows debug messages to be output
-		 * via a serial console before paging_init.
+		 * Clear the 16K level 1 swapper page table
 		 */
-		add	r0, r4, r7
-		rsb	r3, r7, #0x4000	@ PTRS_PER_PGD*sizeof(long)
-		cmp	r3, #0x0800
-		addge	r2, r0, #0x0800
-		addlt	r2, r0, r3
-		orr	r3, r6, r8
+		mov	r0, r4
+		mov	r3, #0
+		add	r2, r0, #0x4000
 1:		str	r3, [r0], #4
-		add	r3, r3, #1 << 20
+		str	r3, [r0], #4
+		str	r3, [r0], #4
+		str	r3, [r0], #4
 		teq	r0, r2
 		bne	1b
-#ifdef CONFIG_ARCH_NETWINDER
+
 		/*
-		 * If we're using the NetWinder, we need to map in
-		 * the 16550-type serial port for the debug messages
+		 * Create identity mapping for first MB of kernel to
+		 * cater for the MMU enable.  This identity mapping
+		 * will be removed by paging_init()
 		 */
-		teq	r1, #MACH_TYPE_NETWINDER
-		bne	1f
-		add	r0, r4, #0x3fc0
-		mov	r3, #0x7c000000
-		orr	r3, r3, r8
-		str	r3, [r0], #4
+		krnladr	r2, r4, r5			@ start of kernel
+		add	r3, r8, r2			@ flags + kernel base
+		str	r3, [r4, r2, lsr #18]		@ identity mapping
+
+		/*
+		 * Now setup the pagetables for our kernel direct
+		 * mapped region.  We round TEXTADDR down to the
+		 * nearest megabyte boundary.
+		 */
+		add	r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel
+		add	r0, r0, #(TEXTADDR & 0x00f00000) >> 18
+		str	r3, [r0], #4			@ PAGE_OFFSET + 0MB
 		add	r3, r3, #1 << 20
-		str	r3, [r0], #4
-1:
-#endif
-#endif
-#ifdef CONFIG_ARCH_RPC
+		str	r3, [r0], #4			@ PAGE_OFFSET + 1MB
+		add	r3, r3, #1 << 20
+		str	r3, [r0], #4			@ PAGE_OFFSET + 2MB
+		add	r3, r3, #1 << 20
+		str	r3, [r0], #4			@ PAGE_OFFSET + 3MB
+
 		/*
-		 * Map in screen at 0x02000000 & SCREEN2_BASE
-		 * Similar reasons here - for debug.  This is
-		 * only for Acorn RiscPC architectures.
+		 * Ensure that the first section of RAM is present.
+		 * we assume that:
+		 *  1. the RAM is aligned to a 256MB boundary
+		 *  2. the kernel is executing in the same 256MB chunk
+		 *     as the start of RAM.
 		 */
-		add	r0, r4, #0x80			@ 02000000
-		mov	r3, #0x02000000
-		orr	r3, r3, r8
-		str	r3, [r0]
-		add	r0, r4, #0x3600			@ d8000000
+		bic	r0, r0, #0x0ff00000 >> 18	@ round down
+		and	r2, r5, #0xf0000000		@ round down
+		add	r3, r8, r2			@ flags + rambase
 		str	r3, [r0]
-#endif
-		mov	pc, lr
 
+		bic	r8, r8, #0x0c			@ turn off cacheable
+							@ and bufferable bits
+		mov	pc, lr
+/*========================== NOT USED ==============================*/
+#endif
 
 
 /*
@@ -417,3 +576,16 @@
 2:		ldmib	r4, {r5, r6, r7}		@ found, get results
 		mov	r7, r7, lsr #18			@ pagetable byte offset
 		mov	pc, lr
+
+L_AT91_SF_CIDR: .long	0xfff00000
+
+#if defined(CONFIG_ARCH_CX861XX)
+CX861XX_IDR:	.long	MACH_TYPE_CX861XX
+#endif
+
+	.section .stack, "w"
+
+_firq_stack:
+_firq_stack_top:
+	.space	512
+_firq_stack_bottom:
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/init_task.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/init_task.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/init_task.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/init_task.c	2004-12-06 19:35:49.000000000 +0100
@@ -9,6 +9,7 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
+static struct vm_area_struct init_mmap = INIT_MMAP;
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS;
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/irq.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/irq.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/irq.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/irq.c	2004-12-06 19:35:49.000000000 +0100
@@ -24,16 +24,16 @@
 #include <linux/sched.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/smp.h>
 #include <linux/init.h>
 
+#include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/mach/irq.h>
-#include <asm/arch/irq.h>
-
 
+#include <asm/arch/irq.h>	/* pick up fixup_irq definition */
 
 /*
  * Maximum IRQ count.  Currently, this is arbitary.  However, it should
@@ -139,6 +139,7 @@
 		if (desc->lck_cnt > MAX_IRQ_CNT) {
 			printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
 			disable_irq(irq);
+			desc->lck_cnt = 0;
 		}
 	} else {
 		desc->lck_cnt = 0;
@@ -156,12 +157,14 @@
 	struct irqaction * action;
 	int cpu;
 
+#if 0
 	irq = fixup_irq(irq);
-
+	
 	/*
 	 * Some hardware gives randomly wrong interrupts.  Rather
 	 * than crashing, do something sensible.
 	 */
+	 
 	if (irq >= NR_IRQS)
 		goto bad_irq;
 
@@ -216,7 +219,7 @@
 
 	irq_exit(cpu, irq);
 
-	if (softirq_active(cpu) & softirq_mask(cpu))
+	if (softirq_pending(cpu))
 		do_softirq();
 	return;
 
@@ -224,6 +227,33 @@
 	irq_err_count += 1;
 	printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
 	return;
+#else
+	desc = irq_desc + irq;
+
+	cpu = smp_processor_id();
+	irq_enter(cpu, irq);
+	kstat.irqs[cpu][irq]++;
+	desc->triggered = 1;
+
+	action = desc->action;
+
+	if (action) 
+	{
+		action->handler(irq, action->dev_id, regs);
+	}
+	else
+	{
+		spin_lock(&irq_controller_lock);
+		desc->mask(irq);
+		spin_unlock(&irq_controller_lock);
+	}
+
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+	return;
+#endif
 }
 
 #ifdef CONFIG_ARCH_ACORN
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/oldlatches.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/oldlatches.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/oldlatches.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/oldlatches.c	2004-12-06 19:35:49.000000000 +0100
@@ -50,16 +50,17 @@
 		BUG();
 }
 
-static void __init oldlatch_init(void)
+static int __init oldlatch_init(void)
 {
 	if (machine_is_archimedes()) {
 		oldlatch_aupdate(0xff, 0xff);
 		/* Thats no FDC reset...*/
 		oldlatch_bupdate(0xff, LATCHB_FDCRESET);
 	}
+	return 0;
 }
 
-initcall(oldlatch_init);
+__initcall(oldlatch_init);
 
 EXPORT_SYMBOL(oldlatch_aupdate);
 EXPORT_SYMBOL(oldlatch_bupdate);
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/process.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/process.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/process.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/process.c	2004-12-06 19:35:49.000000000 +0100
@@ -17,10 +17,11 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/delay.h>
 #include <linux/reboot.h>
+#include <linux/interrupt.h>
 #include <linux/init.h>
 
 #include <asm/system.h>
@@ -39,8 +40,6 @@
 extern const char *processor_modes[];
 extern void setup_mm_for_reboot(char mode);
 
-asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
-
 static volatile int hlt_counter;
 
 #include <asm/arch/system.h>
@@ -87,7 +86,7 @@
 	init_idle();
 	current->nice = 20;
 	current->counter = -100;
-
+ 
 	while (1) {
 		void (*idle)(void) = pm_idle;
 		if (!idle)
@@ -97,6 +96,11 @@
 			idle();
 		leds_event(led_idle_end);
 		schedule();
+
+#ifndef CONFIG_NO_PGT_CACHE
+		check_pgt_cache();
+#endif					
+
 	}
 }
 
@@ -181,7 +185,9 @@
 		processor_modes[processor_mode(regs)],
 		thumb_mode(regs) ? " (T)" : "",
 		get_fs() == get_ds() ? "kernel" : "user");
-#if defined(CONFIG_CPU_32)
+	// ...MaTed-- these crash on Samsun s3c4530
+
+#if defined(CONFIG_CPU_32) & ! defined (CONFIG_CPU_S3C4530)
 	{
 		int ctrl, transbase, dac;
 		  __asm__ (
@@ -293,6 +299,8 @@
 {
 }
 
+asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+
 int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
 	unsigned long unused,
 	struct task_struct * p, struct pt_regs * regs)
@@ -310,9 +318,10 @@
 #else
 	childregs->ARM_sp = esp;
 #endif
-
 	save = ((struct context_save_struct *)(childregs)) - 1;
-	init_thread_css(save);
+	*save = INIT_CSS;
+	save->pc |= (unsigned long)ret_from_fork;
+
 	p->thread.save = save;
 
 	return 0;
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/ptrace.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/ptrace.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/ptrace.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/ptrace.c	2004-12-06 19:35:49.000000000 +0100
@@ -698,12 +698,21 @@
 	return ret;
 }
 
-asmlinkage void syscall_trace(void)
+asmlinkage void syscall_trace(int why, struct pt_regs *regs)
 {
+	unsigned long ip;
+
 	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
 			!= (PT_PTRACED|PT_TRACESYS))
 		return;
-	current->exit_code = SIGTRAP;
+
+	ip = regs->ARM_ip;
+	regs->ARM_ip = why;
+
+	/* the 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
@@ -716,4 +725,5 @@
 		send_sig(current->exit_code, current, 1);
 		current->exit_code = 0;
 	}
+	regs->ARM_ip = ip;
 }
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/semaphore.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/semaphore.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/semaphore.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/semaphore.c	2004-12-06 19:35:49.000000000 +0100
@@ -166,127 +166,6 @@
 	return 1;
 }
 
-struct rw_semaphore *down_read_failed_biased(struct rw_semaphore *sem)
-{
-	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
-
-	add_wait_queue(&sem->wait, &wait);	/* put ourselves at the head of the list */
-
-	for (;;) {
-		if (sem->read_bias_granted && xchg(&sem->read_bias_granted, 0))
-			break;
-		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-		if (!sem->read_bias_granted)
-			schedule();
-	}
-
-	remove_wait_queue(&sem->wait, &wait);
-	tsk->state = TASK_RUNNING;
-
-	return sem;
-}
-
-struct rw_semaphore *down_write_failed_biased(struct rw_semaphore *sem)
-{
-        struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
-
-	add_wait_queue_exclusive(&sem->write_bias_wait, &wait); /* put ourselves at the end of the list */
-
-	for (;;) {
-		if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0))
-			break;
-		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-		if (!sem->write_bias_granted)
-			schedule();
-	}
-
-	remove_wait_queue(&sem->write_bias_wait, &wait);
-	tsk->state = TASK_RUNNING;
-
-	/* if the lock is currently unbiased, awaken the sleepers
-	 * FIXME: this wakes up the readers early in a bit of a
-	 * stampede -> bad!
-	 */
-	if (atomic_read(&sem->count) >= 0)
-		wake_up(&sem->wait);
-
-	return sem;
-}
-
-/* Wait for the lock to become unbiased.  Readers
- * are non-exclusive. =)
- */
-struct rw_semaphore *down_read_failed(struct rw_semaphore *sem)
-{
-	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
-
-	/* this takes care of granting the lock */
-	__up_op_read(sem, __rwsem_wake);
-
-	add_wait_queue(&sem->wait, &wait);
-
-	while (atomic_read(&sem->count) < 0) {
-		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-		if (atomic_read(&sem->count) >= 0)
-			break;
-		schedule();
-	}
-
-	remove_wait_queue(&sem->wait, &wait);
-	tsk->state = TASK_RUNNING;
-
-	return sem;
-}
-
-/* Wait for the lock to become unbiased. Since we're
- * a writer, we'll make ourselves exclusive.
- */
-struct rw_semaphore *down_write_failed(struct rw_semaphore *sem)
-{
-	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
-
-	/* this takes care of granting the lock */
-	__up_op_write(sem, __rwsem_wake);
-
-	add_wait_queue_exclusive(&sem->wait, &wait);
-
-	while (atomic_read(&sem->count) < 0) {
-		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-		if (atomic_read(&sem->count) >= 0)
-			break;	/* we must attempt to acquire or bias the lock */
-		schedule();
-	}
-
-	remove_wait_queue(&sem->wait, &wait);
-	tsk->state = TASK_RUNNING;
-
-	return sem;
-}
-
-/* Called when someone has done an up that transitioned from
- * negative to non-negative, meaning that the lock has been
- * granted to whomever owned the bias.
- */
-struct rw_semaphore *rwsem_wake_readers(struct rw_semaphore *sem)
-{
-	if (xchg(&sem->read_bias_granted, 1))
-		BUG();
-	wake_up(&sem->wait);
-	return sem;
-}
-
-struct rw_semaphore *rwsem_wake_writer(struct rw_semaphore *sem)
-{
-	if (xchg(&sem->write_bias_granted, 1))
-		BUG();
-	wake_up(&sem->write_bias_wait);
-	return sem;
-}
-
 /*
  * The semaphore operations have a special calling sequence that
  * allow us to do a simpler in-line version of them. These routines
@@ -333,61 +212,6 @@
 	bl	__up
 	ldmfd	sp!, {r0 - r3, pc}^
 
-	.align	5
-	.globl	__down_read_failed
-__down_read_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bcc	1f
-1:	bl	down_read_failed_biased
-	ldmfd	sp!, {r0 - r3, pc}^
-2:	bl	down_read_failed
-	mov	r1, pc
-	orr	r2, r1, #
-	teqp r2, #0
-
-	ldr	r3, [r0]
-	subs	r3, r3, #1
-	str	r3, [r0]
-	ldmplfd	sp!, {r0 - r3, pc}^
-  orrcs r1, r1, #0x20000000   @ Set carry
-  teqp r1, #0
-	bcc	2b
-	b	1b
-
-	.align	5
-	.globl	__down_write_failed
-__down_write_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bcc	1f
-1:	bl	down_write_failed_biased
-	ldmfd	sp!, {r0 - r3, pc}^
-2:	bl	down_write_failed
-	mov r1, pc
-	orr	r2, r1, #128
-	teqp r2, #0
-
-	ldr	r3, [r0]
-	subs	r3, r3, #"RW_LOCK_BIAS_STR"
-	str	r3, [r0]
-	ldmeqfd	sp!, {r0 - r3, pc}^
-  orrcs r1, r1, #0x20000000   @ Set carry
-	teqp r1, #0
-	bcc	2b
-	b	1b
-
-	.align	5
-	.globl	__rwsem_wake
-__rwsem_wake:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	beq	1f
-	bl	rwsem_wake_readers
-	ldmfd	sp!, {r0 - r3, pc}^
-1:	bl	rwsem_wake_writer
-	ldmfd	sp!, {r0 - r3, pc}^
-
 	.previous
 	");
 
@@ -428,57 +252,6 @@
 	bl	__up
 	ldmfd	sp!, {r0 - r3, pc}
 
-	.align	5
-	.globl	__down_read_failed
-__down_read_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bcc	1f
-1:	bl	down_read_failed_biased
-	ldmfd	sp!, {r0 - r3, pc}
-2:	bl	down_read_failed
-	mrs	r1, cpsr
-	orr	r2, r1, #128
-	msr	cpsr_c, r2
-	ldr	r3, [r0]
-	subs	r3, r3, #1
-	str	r3, [r0]
-	msr	cpsr_c, r1
-	ldmplfd	sp!, {r0 - r3, pc}
-	bcc	2b
-	b	1b
-
-	.align	5
-	.globl	__down_write_failed
-__down_write_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bcc	1f
-1:	bl	down_write_failed_biased
-	ldmfd	sp!, {r0 - r3, pc}
-2:	bl	down_write_failed
-	mrs	r1, cpsr
-	orr	r2, r1, #128
-	msr	cpsr_c, r2
-	ldr	r3, [r0]
-	subs	r3, r3, #"RW_LOCK_BIAS_STR"
-	str	r3, [r0]
-	msr	cpsr_c, r1
-	ldmeqfd	sp!, {r0 - r3, pc}
-	bcc	2b
-	b	1b
-
-	.align	5
-	.globl	__rwsem_wake
-__rwsem_wake:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	beq	1f
-	bl	rwsem_wake_readers
-	ldmfd	sp!, {r0 - r3, pc}
-1:	bl	rwsem_wake_writer
-	ldmfd	sp!, {r0 - r3, pc}
-
 	.previous
 	");
 
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/setup.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/setup.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/setup.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/setup.c	2004-12-06 19:35:49.000000000 +0100
@@ -28,18 +28,20 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 
-#ifndef MEM_SIZE
-#define MEM_SIZE	(16*1024*1024)
-#endif
+
+#define MEM_SIZE	DRAM_SIZE
 
 #ifndef CONFIG_CMDLINE
 #define CONFIG_CMDLINE "root=/dev/rom0"
 #endif
-
+  
 extern void paging_init(struct meminfo *, struct machine_desc *desc);
 extern void bootmem_init(struct meminfo *);
 extern void reboot_setup(char *str);
-extern unsigned long memparse(char *ptr, char **retptr);
+//extern unsigned long memparse(char *ptr, char **retptr);
+extern unsigned long long memparse(char *ptr, char **retptr);
+extern unsigned long _end_kernel;
+
 extern int root_mountflags;
 extern int _stext, _text, _etext, _edata, _end;
 
@@ -189,7 +191,8 @@
 
 	for (;;) {
 		if (c == ' ' && !memcmp(from, "mem=", 4)) {
-			unsigned long size, start;
+			unsigned long start;
+			unsigned long long size;
 
 			if (to != command_line)
 				to -= 1;
@@ -481,14 +484,36 @@
 	}
 }
 
+
+/*
+ * Tell the kernel about any console devices we may have,  the user
+ * can use bootargs select which one they get.  The default will be
+ * the console you register first.
+ */
+
+
+
 void __init setup_arch(char **cmdline_p)
 {
 	struct param_struct *params = NULL;
 	struct machine_desc *mdesc;
 	char *from = default_command_line;
-
+	int bootmap_size;
+	unsigned long memory_start = (unsigned long)&_end_kernel;
+#ifdef CONFIG_ARCH_CNXT
+	unsigned long memory_end = END_MEM;
+#endif
+	
 	ROOT_DEV = MKDEV(0, 255);
 
+#ifdef CONFIG_BOARD_EVS3C4530HEI
+	config_BSP();
+#endif
+	
+#ifdef CONFIG_ARCH_CNXT
+	syshwinit();
+#endif
+
 	setup_processor();
 	mdesc = setup_architecture(machine_arch_type);
 	machine_name = mdesc->name;
@@ -518,11 +543,11 @@
 			parse_tags(mdesc->tagtable, mdesc->tagsize, tag);
 		else
 			parse_params(params);
-	}
+	} 
 
 	if (meminfo.nr_banks == 0) {
 		meminfo.nr_banks      = 1;
-		meminfo.bank[0].start = PHYS_OFFSET;
+		meminfo.bank[0].start = PAGE_OFFSET;//PHYS_OFFSET;
 		meminfo.bank[0].size  = MEM_SIZE;
 	}
 
@@ -535,14 +560,20 @@
 	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 	parse_cmdline(&meminfo, cmdline_p, from);
 
-#ifdef CONFIG_ARCH_DSC21
-	{
-		extern void setup_dsc21(void);
-		setup_dsc21();
-	}
-#endif	
-
+#if 0 
 	bootmem_init(&meminfo);
+#else
+	bootmap_size= init_bootmem_node(
+			  NODE_DATA(0),
+			  memory_start >> PAGE_SHIFT,
+			  PAGE_OFFSET >> PAGE_SHIFT,
+			  END_MEM >> PAGE_SHIFT);
+			  
+	meminfo.end = END_MEM;		/* Need for kcore size. OZH */
+ 
+	free_bootmem(memory_start, END_MEM - memory_start);
+	reserve_bootmem(memory_start, bootmap_size);
+#endif
 	paging_init(&meminfo, mdesc);
 	request_standard_resources(&meminfo, mdesc);
 
@@ -564,13 +595,61 @@
 {
 	char *p = buffer;
 
+	p += sprintf(p, "\nProcessor\t: %s\n", proc_info.cpu_name);
+	p += sprintf(p, " manufacturer\t: %s\n", proc_info.manufacturer);
+#ifdef CONFIG_CPU_ARM710	
+	p += sprintf(p, " core\t\t: arm7tdmi\n");
+#endif	
+#ifdef CONFIG_CPU_ARM940T
+	p += sprintf(p, " core\t\t: arm9tdmi\n");
+#endif	
+#ifdef CONFIG_CPU_ARM926T
+	p += sprintf(p, " core\t\t: arm9tdmi\n");
+#endif	
+#ifdef CONFIG_CPU_32
+	p += sprintf(p, " mode\t\t: 32 bit\n");
+#endif	
+	p += sprintf(p, " format\t\t: ");
+	if	( ENDIANNESS == 'b')	p += sprintf(p, "Big-Endial\n");
+	else if ( ENDIANNESS == 'l')	p += sprintf(p, "Little-Endian\n");
+	else				p += sprintf(p, "Unknow-Endian\n");
+#ifdef CONFIG_CPU_S3C4530
+	{
+	int tmp;
+	tmp = (*(unsigned int *)0x3ff3000) & 0xFFFF;
+	p += sprintf(p, " speed\t\t: %lu.%02lu MHz\n",
+		      50/(tmp+1),
+		     (50/(tmp+1)) % 10);
+	
+	tmp = (*(unsigned int *)0x3ff0000) & 0x30;
+	if	(tmp == 0x00) tmp = 4;
+	else if	(tmp == 0x10) tmp = 8;
+	else if	(tmp == 0x20) tmp = 0;
+	p += sprintf(p, " cache size\t: %lu KB\n",
+		      tmp);
+	}
+#endif	
+	p += sprintf(p, " bogomips\t: %lu.%02lu\n",
+		      loops_per_jiffy / (500000/HZ),
+		     (loops_per_jiffy / (5000/HZ)) % 100);
+
+	p += sprintf(p, "\nHardware\t: %s\n", machine_name);
+
+	return p - buffer;
+}
+
+#if 0
+int get_cpuinfo(char * buffer)
+{
+	char *p = buffer;
+
 	p += sprintf(p, "Processor\t: %s %s rev %d (%s)\n",
 		     proc_info.manufacturer, proc_info.cpu_name,
 		     (int)processor_id & 15, elf_platform);
 
 	p += sprintf(p, "BogoMIPS\t: %lu.%02lu\n",
-		     loops_per_jiffy / 500000,
-		     (loops_per_jiffy / 5000) % 100);
+		     loops_per_jiffy / (500000/HZ),
+		     (loops_per_jiffy / (5000/HZ)) % 100);
 
 	p += sprintf(p, "Hardware\t: %s\n", machine_name);
 
@@ -583,3 +662,4 @@
 
 	return p - buffer;
 }
+#endif
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/signal.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/signal.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/signal.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/signal.c	2004-12-06 19:35:49.000000000 +0100
@@ -36,8 +36,6 @@
 #define SWI_THUMB_SIGRETURN	(0xdf00)
 #define SWI_THUMB_RT_SIGRETURN	(0xdf00)
 
-asmlinkage int sys_wait4(pid_t pid, unsigned long * stat_addr,
-			 int options, unsigned long *ru);
 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
 
 int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
@@ -333,16 +331,15 @@
 	/*
 	 * This is the X/Open sanctioned signal stack switching.
 	 */
-	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+	if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp))
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
 	/*
 	 * No matter what happens, 'sp' must be word
 	 * aligned otherwise nasty things could happen
 	 */
-	sp &= ~3;
-
-	return (void *)(sp - framesize);
+	/* ATPCS B01 mandates 8-byte alignment */
+	return (void *)((sp - framesize) & ~7);
 }
 
 static void setup_frame(int sig, struct k_sigaction *ka,
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/sys_arm.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/sys_arm.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/sys_arm.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/sys_arm.c	2004-12-06 19:35:49.000000000 +0100
@@ -14,7 +14,7 @@
  */
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
@@ -28,9 +28,9 @@
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
 
-/*
- * Constant strings used in inlined functions in header files
- */
+extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
+			       unsigned long new_len, unsigned long flags,
+			       unsigned long new_addr);
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -55,10 +55,19 @@
 	unsigned long prot, unsigned long flags,
 	unsigned long fd, unsigned long pgoff)
 {
-	int error = -EBADF;
+	int error = -EINVAL;
 	struct file * file = NULL;
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	/*
+	 * If we are doing a fixed mapping, and address < PAGE_SIZE,
+	 * then deny it.
+	 */
+	if (flags & MAP_FIXED && addr < PAGE_SIZE && vectors_base() == 0)
+		goto out;
+
+	error = -EBADF;
 	if (!(flags & MAP_ANONYMOUS)) {
 		file = fget(fd);
 		if (!file)
@@ -101,6 +110,31 @@
 	return error;
 }
 
+asmlinkage unsigned long
+sys_arm_mremap(unsigned long addr, unsigned long old_len,
+	       unsigned long new_len, unsigned long flags,
+	       unsigned long new_addr)
+{
+	unsigned long ret = -EINVAL;
+#ifndef CONFIG_UCLINUX
+	/*
+	 * If we are doing a fixed mapping, and address < PAGE_SIZE,
+	 * then deny it.
+	 */
+	if (flags & MREMAP_FIXED && new_addr < PAGE_SIZE &&
+	    vectors_base() == 0)
+		goto out;
+
+	down_write(&current->mm->mmap_sem);
+	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+	up_write(&current->mm->mmap_sem);
+
+out:
+#else
+	return ret;
+#endif
+}
+
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls.
@@ -173,6 +207,7 @@
 		return sys_msgget ((key_t) first, second);
 	case MSGCTL:
 		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
 	case SHMAT:
 		switch (version) {
 		default: {
@@ -205,7 +240,13 @@
  */
 asmlinkage int sys_fork(struct pt_regs *regs)
 {
+#if 0
+*ifdef CONFIG_UCLINUX		/*  Call as vfork().	
+				    FIXME. Should be changed in uClibc.	OZH */
+    	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0);
+#else
 	return do_fork(SIGCHLD, regs->ARM_sp, regs, 0);
+#endif
 }
 
 /* Clone a task - this clones the calling program thread.
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/traps.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/traps.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/kernel/traps.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/kernel/traps.c	2004-12-06 19:35:49.000000000 +0100
@@ -20,6 +20,7 @@
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/ptrace.h>
+#include <linux/elf.h>
 #include <linux/init.h>
 
 #include <asm/atomic.h>
@@ -27,7 +28,7 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/arch/vmalloc.h>
+#include <asm/unistd.h>
 
 #include "ptrace.h"
 
@@ -83,13 +84,16 @@
 	}
 }
 
+#ifndef CONFIG_UCLINUX 
 /*
- * I removed the #defines for VMALLOC_OFFSET & MODULE_RANGE because
- * a) they don't appear to be used here
- * b) VMALLOC_OFFSET should probably come from asm/arch/vmalloc.h if we ever do
- *    need it
- * --gmcnutt
+ * These constants are for searching for possible module text
+ * segments.  VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
+ * a guess of how much space is likely to be vmalloced.
  */
+#define VMALLOC_OFFSET (8*1024*1024)
+#define MODULE_RANGE (8*1024*1024)
+
+#endif
 
 static void dump_instr(struct pt_regs *regs)
 {
@@ -144,6 +148,18 @@
 		c_backtrace(fp, processor_mode(regs));
 }
 
+/*
+ * This is called from SysRq-T (show_task) to display the current
+ * call trace for each process.  Very useful.
+ */
+void show_trace_task(struct task_struct *tsk)
+{
+	if (tsk != current) {
+		unsigned int fp = tsk->thread.save->fp;
+		c_backtrace(fp, 0x10);
+	}
+}
+
 spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 /*
@@ -174,9 +190,9 @@
 		fs = get_fs();
 		set_fs(KERNEL_DS);
 
-		dump_instr(regs);
 		dump_stack(tsk, (unsigned long)(regs + 1));
 		dump_backtrace(regs, tsk);
+		dump_instr(regs);
 
 		set_fs(fs);
 	}
@@ -195,9 +211,16 @@
 
 asmlinkage void do_undefinstr(int address, struct pt_regs *regs, int mode)
 {
-	unsigned long addr = instruction_pointer(regs);
+	unsigned long addr;
 	siginfo_t info;
 
+	/*
+	 * According to the ARM ARM, PC is 2 or 4 bytes ahead, depending
+	 * whether we're in Thumb mode or not.
+	 */
+	regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
+	addr = instruction_pointer(regs);
+
 #ifdef CONFIG_DEBUG_USER
 	printk(KERN_INFO "%s (%d): undefined instruction: pc=%08lx\n",
 		current->comm, current->pid, addr);
@@ -217,6 +240,7 @@
 	die_if_kernel("Oops - undefined instruction", regs, mode);
 }
 
+#ifdef CONFIG_CPU_26
 asmlinkage void do_excpt(int address, struct pt_regs *regs, int mode)
 {
 	siginfo_t info;
@@ -239,6 +263,7 @@
 
 	die_if_kernel("Oops - address exception", regs, mode);
 }
+#endif
 
 asmlinkage void do_unexp_fiq (struct pt_regs *regs)
 {
@@ -256,33 +281,84 @@
  */
 asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
 {
+	unsigned int vectors = vectors_base();
+	mm_segment_t fs;
+
 	console_verbose();
 
 	printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
 		handler[reason], processor_modes[proc_mode]);
 
 	/*
+	 * We need to switch to kernel mode so that we can
+	 * use __get_user to safely read from kernel space.
+	 * Note that we now dump the code first, just in case
+	 * the backtrace kills us.
+	 */
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+
+	/*
 	 * Dump out the vectors and stub routines.  Maybe a better solution
 	 * would be to dump them out only if we detect that they are corrupted.
 	 */
 	printk(KERN_CRIT "Vectors:\n");
-	dump_mem(0, 0x40);
+	dump_mem(vectors, 0x40);
 	printk(KERN_CRIT "Stubs:\n");
-	dump_mem(0x200, 0x4b8);
+	dump_mem(vectors + 0x200, 0x4b8);
+
+	set_fs(fs);
 
 	die("Oops", regs, 0);
 	cli();
 	panic("bad mode");
 }
 
+static int bad_syscall(int n, struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	/* You might think just testing `handler' would be enough, but PER_LINUX
+	 * points it to no_lcall7 to catch undercover SVr4 binaries.  Gutted.
+	 */
+	if (current->personality != PER_LINUX && current->exec_domain->handler) {
+		/* Hand it off to iBCS.  The extra parameter and consequent type 
+		 * forcing is necessary because of the weird ARM calling convention.
+		 */
+		current->exec_domain->handler(n, regs);
+		return regs->ARM_r0;
+	}
+
+#ifdef CONFIG_DEBUG_USER
+	printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
+		current->pid, current->comm, n);
+	dump_instr(regs);
+#endif
+
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_code  = ILL_ILLTRP;
+	info.si_addr  = (void *)instruction_pointer(regs) -
+			 (thumb_mode(regs) ? 2 : 4);
+
+	force_sig_info(SIGILL, &info, current);
+	die_if_kernel("Oops", regs, n);
+	return regs->ARM_r0;
+}
+
 /*
- * Handle some more esoteric system calls
+ * Handle all unrecognised system calls.
+ *  0x9f0000 - 0x9fffff are some more esoteric system calls
  */
+#define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE)
 asmlinkage int arm_syscall(int no, struct pt_regs *regs)
 {
 	siginfo_t info;
 
-	switch (no) {
+	if ((no >> 16) != 0x9f)
+		return bad_syscall(no, regs);
+
+	switch (no & 0xffff) {
 	case 0: /* branch through 0 */
 		info.si_signo = SIGSEGV;
 		info.si_errno = 0;
@@ -292,9 +368,9 @@
 		force_sig_info(SIGSEGV, &info, current);
 
 		die_if_kernel("branch through zero", regs, 0);
-		break;
+		return 0;
 
-	case 1: /* SWI BREAK_POINT */
+	case NR(breakpoint): /* SWI BREAK_POINT */
 		/*
 		 * The PC is always left pointing at the next
 		 * instruction.  Fix this.
@@ -305,17 +381,36 @@
 		info.si_signo = SIGTRAP;
 		info.si_errno = 0;
 		info.si_code  = TRAP_BRKPT;
-		info.si_addr  = (void *)instruction_pointer(regs);
+		info.si_addr  = (void *)instruction_pointer(regs) -
+				 (thumb_mode(regs) ? 2 : 4);
 
 		force_sig_info(SIGTRAP, &info, current);
 		return regs->ARM_r0;
 
-	case 2:	/* sys_cacheflush */
 #ifdef CONFIG_CPU_32
-		/* r0 = start, r1 = end, r2 = flags */
+	case NR(cacheflush):	/* r0 = start, r1 = end, r2 = flags */
 		cpu_cache_clean_invalidate_range(regs->ARM_r0, regs->ARM_r1, 1);
-#endif
+		return 0;
+
+	case NR(usr26):
+		if (!(elf_hwcap & HWCAP_26BIT))
+			break;
+		regs->ARM_cpsr &= ~0x10;
+		return regs->ARM_r0;
+
+	case NR(usr32):
+		if (!(elf_hwcap & HWCAP_26BIT))
+			break;
+		regs->ARM_cpsr |= 0x10;
+		return regs->ARM_r0;
+#else
+	case NR(cacheflush):
+		return 0;
+
+	case NR(usr26):
+	case NR(usr32):
 		break;
+#endif
 
 	default:
 		/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
@@ -324,45 +419,29 @@
 		   a feature is supported.  */
 		if (no <= 0x7ff)
 			return -ENOSYS;
-#ifdef CONFIG_DEBUG_USER
-		/* experience shows that these seem to indicate that
-		 * something catastrophic has happened
-		 */
-		printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
-		dump_instr(regs);
-		if (user_mode(regs)) {
-			show_regs(regs);
-			c_backtrace(regs->ARM_fp, processor_mode(regs));
-		}
-#endif
-		force_sig(SIGILL, current);
-		die_if_kernel("Oops", regs, no);
 		break;
 	}
-	return 0;
-}
-
-asmlinkage void deferred(int n, struct pt_regs *regs)
-{
-	/* You might think just testing `handler' would be enough, but PER_LINUX
-	 * points it to no_lcall7 to catch undercover SVr4 binaries.  Gutted.
-	 */
-	if (current->personality != PER_LINUX && current->exec_domain->handler) {
-		/* Hand it off to iBCS.  The extra parameter and consequent type 
-		 * forcing is necessary because of the weird ARM calling convention.
-		 */
-		void (*handler)(int nr, struct pt_regs *regs) = (void *)current->exec_domain->handler;
-		(*handler)(n, regs);
-		return;
-	}
-
 #ifdef CONFIG_DEBUG_USER
-	printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
-		current->pid, current->comm, n);
+	/*
+	 * experience shows that these seem to indicate that
+	 * something catastrophic has happened
+	 */
+	printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
 	dump_instr(regs);
+	if (user_mode(regs)) {
+		show_regs(regs);
+		c_backtrace(regs->ARM_fp, processor_mode(regs));
+	}
 #endif
-	force_sig(SIGILL, current);
-	die_if_kernel("Oops", regs, n);
+	info.si_signo = SIGILL;
+	info.si_errno = 0;
+	info.si_code  = ILL_ILLTRP;
+	info.si_addr  = (void *)instruction_pointer(regs) -
+			 (thumb_mode(regs) ? 2 : 4);
+
+	force_sig_info(SIGILL, &info, current);
+	die_if_kernel("Oops", regs, no);
+	return 0;
 }
 
 void __bad_xchg(volatile void *ptr, int size)
@@ -449,9 +528,12 @@
 
 void __init trap_init(void)
 {
-	extern void __trap_init(void);
+	extern void __trap_init(void *);
 
-	__trap_init();
+	__trap_init((void *)vectors_base());
+	if (vectors_base() != 0)
+		printk("Relocating machine vectors to 0x%08x\n",
+			vectors_base());
 #ifdef CONFIG_CPU_32
 	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 #endif
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/Makefile linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/Makefile
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/Makefile	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/Makefile	2004-12-06 19:35:49.000000000 +0100
@@ -17,18 +17,11 @@
 obj-m		:=
 obj-n		:=
 
-export-objs	:= io.o
-
 obj-arc		:= ecard.o io-acorn.o floppydma.o
 obj-rpc		:= ecard.o io-acorn.o floppydma.o
 obj-clps7500	:= io-acorn.o
-obj-footbridge	:= io-pcio.o
 obj-l7200     	:= io-acorn.o
-obj-nexuspci	:= io-pcio.o
-obj-sa1100	:= io-pcio.o
 obj-shark	:= io-shark.o
-obj-integrator	:= io-pcio.o
-obj-clps711x	:= io-shark.o
 
 obj-y		+= $(obj-$(MACHINE))
 
@@ -49,8 +42,8 @@
   obj-y		+= uaccess-armo.o
 endif
 
-ifneq ($(MACHINE),ebsa110)
-  obj-y		+= io.o
-endif
-
 include $(TOPDIR)/Rules.make
+
+csumpartialcopy.o: csumpartialcopygeneric.S
+csumpartialcopyuser.o: csumpartialcopygeneric.S
+
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/csumpartial.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/csumpartial.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/csumpartial.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/csumpartial.S	2004-12-06 19:35:49.000000000 +0100
@@ -12,57 +12,119 @@
 
 		.text
 
-/* Function: __u32 csum_partial(const char *src, int len, __u32)
+/*
+ * Function: __u32 csum_partial(const char *src, int len, __u32 sum)
  * Params  : r0 = buffer, r1 = len, r2 = checksum
  * Returns : r0 = new checksum
  */
 
+buf	.req	r0
+len	.req	r1
+sum	.req	r2
+td0	.req	r3
+td1	.req	r4	@ save before use
+td2	.req	r5	@ save before use
+td3	.req	lr
+
+.zero:		mov	r0, sum
+		add	sp, sp, #4
+		ldr	pc, [sp], #4
+
+		/*
+		 * Handle 0 to 7 bytes, with any alignment of source and
+		 * destination pointers.  Note that when we get here, C = 0
+		 */
+.less8:		teq	len, #0			@ check for zero count
+		beq	.zero
+
+		/* we must have at least one byte. */
+		tst	buf, #1			@ odd address?
+		ldrneb	td0, [buf], #1
+		subne	len, len, #1
+		adcnes	sum, sum, td0, lsl #8
+
+.less4:		tst	len, #6
+		beq	.less8_byte
+
+		/* we are now half-word aligned */
+
+.less8_wordlp:
+#ifdef __ARM_ARCH_4__
+		ldrh	td0, [buf], #2
+		sub	len, len, #2
+#else
+		ldrb	td0, [buf], #1
+		ldrb	td3, [buf], #1
+		sub	len, len, #2
+		orr	td0, td0, td3, lsl #8
+#endif
+		adcs	sum, sum, td0
+		tst	len, #6
+		bne	.less8_wordlp
+
+.less8_byte:	tst	len, #1			@ odd number of bytes
+		ldrneb	td0, [buf], #1		@ include last byte
+		adcnes	sum, sum, td0		@ update checksum
+
+.done:		adc	r0, sum, #0		@ collect up the last carry
+		ldr	td0, [sp], #4
+		tst	td0, #1			@ check buffer alignment
+		movne	td0, r0, lsl #8		@ rotate checksum by 8 bits
+		orrne	r0, td0, r0, lsr #24
+		ldr	pc, [sp], #4		@ return
+
+.not_aligned:	tst	buf, #1			@ odd address
+		ldrneb	td0, [buf], #1		@ make even
+		subne	len, len, #1
+		adcnes	sum, sum, td0, lsl #8	@ update checksum
+
+		tst	buf, #2			@ 32-bit aligned?
+#ifdef __ARM_ARCH_4__
+		ldrneh	td0, [buf], #2		@ make 32-bit aligned
+		subne	len, len, #2
+#else
+		ldrneb	td0, [buf], #1
+		ldrneb	ip, [buf], #1
+		subne	len, len, #2
+		orrne	td0, td0, ip, lsl #8
+#endif
+		adcnes	sum, sum, td0		@ update checksum
+		mov	pc, lr
+
 ENTRY(csum_partial)
-		tst	r0, #2
-		beq	1f
-		subs	r1, r1, #2
-		addmi	r1, r1, #2
-		bmi	3f
-		bic	r0, r0, #3
-		ldr	r3, [r0], #4
-		adds	r2, r2, r3, lsr #16
-		adcs	r2, r2, #0
-1:		adds	r2, r2, #0
-		bics	ip, r1, #31
+		stmfd	sp!, {buf, lr}
+		cmp	len, #8			@ Ensure that we have at least
+		blo	.less8			@ 8 bytes to copy.
+
+		adds	sum, sum, #0		@ C = 0
+		tst	buf, #3			@ Test destination alignment
+		blne	.not_aligned		@ aligh destination, return here
+
+1:		bics	ip, len, #31
 		beq	3f
-		stmfd	sp!, {r4 - r6}
-2:		ldmia	r0!, {r3 - r6}
-		adcs	r2, r2, r3
-		adcs	r2, r2, r4
-		adcs	r2, r2, r5
-		adcs	r2, r2, r6
-		ldmia	r0!, {r3 - r6}
-		adcs	r2, r2, r3
-		adcs	r2, r2, r4
-		adcs	r2, r2, r5
-		adcs	r2, r2, r6
+
+		stmfd	sp!, {r4 - r5}
+2:		ldmia	buf!, {td0, td1, td2, td3}
+		adcs	sum, sum, td0
+		adcs	sum, sum, td1
+		adcs	sum, sum, td2
+		adcs	sum, sum, td3
+		ldmia	buf!, {td0, td1, td2, td3}
+		adcs	sum, sum, td0
+		adcs	sum, sum, td1
+		adcs	sum, sum, td2
+		adcs	sum, sum, td3
 		sub	ip, ip, #32
 		teq	ip, #0
 		bne	2b
-		adcs	r2, r2, #0
-		ldmfd	sp!, {r4 - r6}
-3:		ands	ip, r1, #0x1c
-		beq	5f
-4:		ldr	r3, [r0], #4
-		sub	ip, ip, #4
-		adcs	r2, r2, r3
-		teq	ip, #0
-		bne	4b
-		adcs	r2, r2, #0
-5:		ands	ip, r1, #3
-		moveq	r0, r2
-		RETINSTR(moveq,pc,lr)
-		mov	ip, ip, lsl #3
-		ldr	r3, [r0]
-		rsb	ip, ip, #32
-		mov	r3, r3, lsl ip
-		adds	r2, r2, r3, lsr ip
-		adc	r0, r2, #0
-		RETINSTR(mov,pc,lr)
+		ldmfd	sp!, {r4 - r5}
 
+3:		tst	len, #0x1c		@ should not change C
+		beq	.less4
 
+4:		ldr	td0, [buf], #4
+		sub	len, len, #4
+		adcs	sum, sum, td0
+		tst	len, #0x1c
+		bne	4b
+		b	.less4
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/csumpartialcopy.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/csumpartialcopy.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/csumpartialcopy.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/csumpartialcopy.S	2004-12-06 19:35:49.000000000 +0100
@@ -18,11 +18,11 @@
  */
 
 		.macro	save_regs
-		stmfd	sp!, {r4 - r8, fp, ip, lr, pc}
+		stmfd	sp!, {r1, r4 - r8, fp, ip, lr, pc}
 		.endm
 
 		.macro	load_regs,flags
-		LOADREGS(\flags,fp,{r4 - r8, fp, sp, pc})
+		LOADREGS(\flags,fp,{r1, r4 - r8, fp, sp, pc})
 		.endm
 
 		.macro	load1b, reg1
@@ -47,250 +47,6 @@
 		ldmia	r0!, {\reg1, \reg2, \reg3, \reg4}
 		.endm
 
-ENTRY(csum_partial_copy_nocheck)
-		mov	ip, sp
-		save_regs
-		sub	fp, ip, #4
-		cmp	r2, #4
-		blt	.too_small
-		tst	r1, #2			@ Test destination alignment
-		beq	.dst_aligned
-		load2b	ip, r8
-		subs	r2, r2, #2		@ We do not know if SRC is aligned...
-		orr	ip, ip, r8, lsl #8
-		adds	r3, r3, ip
-		adcs	r3, r3, #0
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1		@ Destination now aligned
-.dst_aligned:	tst	r0, #3
-		bne	.src_not_aligned
-		adds	r3, r3, #0
-		bics	ip, r2, #15		@ Routine for src & dst aligned
-		beq	2f
-1:		load4l	r4, r5, r6, r7
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r4, r5
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		tst	ip, #4
-		beq	4f
-3:		load1l	r4
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		load1l	r4
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-.exit:		tst	r2, #1
-		strneb	r4, [r1], #1
-		andne	r4, r4, #255
-		adcnes	r3, r3, r4
-		adcs	r0, r3, #0
-		load_regs	ea
+#define FN_ENTRY	ENTRY(csum_partial_copy_nocheck)
 
-.too_small:	teq	r2, #0
-		load_regs	eqea
-		cmp	r2, #2
-		blt	.too_small1
-		load2b	ip, r8
-		orr	ip, ip, r8, lsl #8
-		adds	r3, r3, ip
-		strb	ip, [r1], #1
-		strb	r8, [r1], #1
-		tst	r2, #1
-.too_small1:				@ C = 0
-		beq	.csum_exit
-		load1b	ip
-		strb	ip, [r1], #1
-		adcs	r3, r3, ip
-.csum_exit:	adc	r0, r3, #0
-		load_regs	ea
-
-.src_not_aligned:
-		cmp	r2, #4
-		blt	.too_small
-		and	ip, r0, #3
-		bic	r0, r0, #3
-		load1l	r4
-		cmp	ip, #2
-		beq	.src2_aligned
-		bhi	.src3_aligned
-		mov	r4, r4, lsr #8
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		mov	r6, r6, lsr #8
-		orr	r6, r6, r7, lsl #24
-		mov	r7, r7, lsr #8
-		orr	r7, r7, r8, lsl #24
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #8
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #8
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #24
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #8
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		b	.exit
-
-.src2_aligned:	mov	r4, r4, lsr #16
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		mov	r6, r6, lsr #16
-		orr	r6, r6, r7, lsl #16
-		mov	r7, r7, lsr #16
-		orr	r7, r7, r8, lsl #16
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #16
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #16
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #16
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #16
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		tst	r2, #1
-		adceq	r0, r3, #0
-		load_regs	eqea
-		load1b	r4
-		b	.exit
-
-.src3_aligned:	mov	r4, r4, lsr #24
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		mov	r6, r6, lsr #24
-		orr	r6, r6, r7, lsl #8
-		mov	r7, r7, lsr #24
-		orr	r7, r7, r8, lsl #8
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #24
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #24
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #8
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #24
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		load1l	r4
-		strb	r4, [r1], #1
-		adcs	r3, r3, r4, lsl #24
-		mov	r4, r4, lsr #8
-		b	.exit
+#include "csumpartialcopygeneric.S"
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/csumpartialcopyuser.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/csumpartialcopyuser.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/csumpartialcopyuser.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/csumpartialcopyuser.S	2004-12-06 19:35:49.000000000 +0100
@@ -15,10 +15,6 @@
 
 		.text
 
-/* Function: __u32 csum_partial_copy_from_user (const char *src, char *dst, int len, __u32 sum, int *err_ptr)
- * Params  : r0 = src, r1 = dst, r2 = len, r3 = sum, [sp, #0] = &err
- * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
- */
 #if defined(CONFIG_CPU_32)
 
 		.macro	save_regs
@@ -152,253 +148,16 @@
 #error Unknown CPU architecture
 #endif
 
-ENTRY(csum_partial_copy_from_user)
-		mov	ip, sp
-		save_regs
-		sub	fp, ip, #4
-		cmp	r2, #4
-		blt	.too_small
-		tst	r1, #2			@ Test destination alignment
-		beq	.dst_aligned
-		load2b	ip, r8
-		subs	r2, r2, #2		@ We do not know if SRC is aligned...
-		orr	ip, ip, r8, lsl #8
-		adds	r3, r3, ip
-		adcs	r3, r3, #0
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1		@ Destination now aligned
-.dst_aligned:	tst	r0, #3
-		bne	.src_not_aligned
-		adds	r3, r3, #0
-		bics	ip, r2, #15		@ Routine for src & dst aligned
-		beq	2f
-1:		load4l	r4, r5, r6, r7
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r4, r5
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		tst	ip, #4
-		beq	4f
-3:		load1l	r4
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		load1l	r4
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-.exit:		tst	r2, #1
-		strneb	r4, [r1], #1
-		andne	r4, r4, #255
-		adcnes	r3, r3, r4
-		adcs	r0, r3, #0
-		load_regs	ea
+/*
+ * unsigned int
+ * csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr)
+ *  r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr
+ *  Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
+ */
 
-.too_small:	teq	r2, #0
-		load_regs	eqea
-		cmp	r2, #2
-		blt	.too_small1
-		load2b	ip, r8
-		orr	ip, ip, r8, lsl #8
-		adds	r3, r3, ip
-		strb	ip, [r1], #1
-		strb	r8, [r1], #1
-		tst	r2, #1
-.too_small1:				@ C = 0
-		beq	.csum_exit
-		load1b	ip
-		strb	ip, [r1], #1
-		adcs	r3, r3, ip
-.csum_exit:	adc	r0, r3, #0
-		load_regs	ea
+#define FN_ENTRY	ENTRY(csum_partial_copy_from_user)
 
-.src_not_aligned:
-		cmp	r2, #4
-		blt	.too_small
-		and	ip, r0, #3
-		bic	r0, r0, #3
-		load1l	r4
-		cmp	ip, #2
-		beq	.src2_aligned
-		bhi	.src3_aligned
-		mov	r4, r4, lsr #8
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		mov	r6, r6, lsr #8
-		orr	r6, r6, r7, lsl #24
-		mov	r7, r7, lsr #8
-		orr	r7, r7, r8, lsl #24
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #8
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #8
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #24
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #8
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		b	.exit
-
-.src2_aligned:	mov	r4, r4, lsr #16
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		mov	r6, r6, lsr #16
-		orr	r6, r6, r7, lsl #16
-		mov	r7, r7, lsr #16
-		orr	r7, r7, r8, lsl #16
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #16
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #16
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #16
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #16
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		tst	r2, #1
-		adceq	r0, r3, #0
-		load_regs	eqea
-		load1b	r4
-		b	.exit
-
-.src3_aligned:	mov	r4, r4, lsr #24
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		mov	r6, r6, lsr #24
-		orr	r6, r6, r7, lsl #8
-		mov	r7, r7, lsr #24
-		orr	r7, r7, r8, lsl #8
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #24
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #24
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #8
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #24
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		load1l	r4
-		strb	r4, [r1], #1
-		adcs	r3, r3, r4, lsl #24
-		mov	r4, r4, lsr #8
-		b	.exit
+#include "csumpartialcopygeneric.S"
 
 /*
  * FIXME: minor buglet here
@@ -411,13 +170,13 @@
 #endif
 		.align	4
 6001:		mov	r4, #-EFAULT
-		ldr	r5, [fp, #4]
+		ldr	r5, [fp, #4]		@ *err_ptr
 		str	r4, [r5]
-		ldmia	sp, {r1, r2}		@ retrieve original arguments
+		ldmia	sp, {r1, r2}		@ retrieve dst, len
 		add	r2, r2, r1
-		mov	r3, #0			@ zero the buffer
+		mov	r0, #0			@ zero the buffer
 6002:		teq	r2, r1
-		strneb	r3, [r1], #1
+		strneb	r0, [r1], #1
 		bne	6002b
 		load_regs	ea
 #if defined(CONFIG_CPU_32)
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/delay.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/delay.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/delay.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/delay.S	2004-12-06 19:35:49.000000000 +0100
@@ -29,25 +29,29 @@
 		RETINSTR(moveq,pc,lr)
 
 /*
- * loops = (r0 * 0x10c6 * 100 * loops_per_jiffie) / 2^32
+ * loops = (r0 * 0x10c6 * 100 * loops_per_jiffy) / 2^32
+ *
+ * Oh, if only we had a cycle counter...
  */
 
 @ Delay routine
 ENTRY(__delay)
 		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
+#if 0
+		RETINSTR(movls,pc,lr)
 		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
+		RETINSTR(movls,pc,lr)
 		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
+		RETINSTR(movls,pc,lr)
 		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
+		RETINSTR(movls,pc,lr)
 		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
+		RETINSTR(movls,pc,lr)
 		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
+		RETINSTR(movls,pc,lr)
 		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
+		RETINSTR(movls,pc,lr)
 		subs	r0, r0, #1
-		bcs	SYMBOL_NAME(__delay)
+#endif
+		bhi	SYMBOL_NAME(__delay)
 		RETINSTR(mov,pc,lr)
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-readsb.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-readsb.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-readsb.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-readsb.S	2004-12-06 19:35:49.000000000 +0100
@@ -24,7 +24,9 @@
 		subs	r2, r2, ip
 		bne	.insb_aligned
 
-ENTRY(__arch_readsb)
+ENTRY(__raw_readsb)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
 		ands	ip, r1, #3
 		bne	.insb_align
 
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-readsl-armv3.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-readsl-armv3.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-readsl-armv3.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-readsl-armv3.S	2004-12-06 19:35:49.000000000 +0100
@@ -14,7 +14,9 @@
 /*
  * Note that some reads can be aligned on half-word boundaries.
  */
-ENTRY(__arch_readsl)
+ENTRY(__raw_readsl)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
 		ands	ip, r1, #3
 		bne	2f
 
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-readsw-armv3.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-readsw-armv3.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-readsw-armv3.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-readsw-armv3.S	2004-12-06 19:35:49.000000000 +0100
@@ -30,7 +30,9 @@
 		subs	r2, r2, #1
 		RETINSTR(moveq, pc, lr)
 
-ENTRY(__arch_readsw)
+ENTRY(__raw_readsw)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
 		tst	r1, #3
 		bne	.insw_align
 
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-writesb.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-writesb.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-writesb.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-writesb.S	2004-12-06 19:35:49.000000000 +0100
@@ -24,7 +24,9 @@
 		subs	r2, r2, ip
 		bne	.outsb_aligned
 
-ENTRY(__arch_writesb)
+ENTRY(__raw_writesb)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
 		ands	ip, r1, #3
 		bne	.outsb_align
 
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-writesl.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-writesl.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-writesl.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-writesl.S	2004-12-06 19:35:49.000000000 +0100
@@ -11,7 +11,9 @@
 #include <asm/assembler.h>
 #include <asm/hardware.h>
 
-ENTRY(__arch_writesl)
+ENTRY(__raw_writesl)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
 		ands	ip, r1, #3
 		bne	2f
 
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-writesw-armv3.S linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-writesw-armv3.S
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/lib/io-writesw-armv3.S	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/lib/io-writesw-armv3.S	2004-12-06 19:35:49.000000000 +0100
@@ -31,7 +31,9 @@
 		subs	r2, r2, #1
 		RETINSTR(moveq, pc, lr)
 
-ENTRY(__arch_writesw)
+ENTRY(__raw_writesw)
+		teq	r2, #0		@ do we have to check for the zero len?
+		moveq	pc, lr
 		tst	r1, #3
 		bne	.outsw_align
 
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/Makefile linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/Makefile
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/Makefile	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/Makefile	2004-12-06 19:35:49.000000000 +0100
@@ -13,25 +13,38 @@
 
 # Object file lists.
 
-obj-y		:= extable.o memory.o fault-common.o fault-$(PROCESSOR).o init.o \
-		   mm-$(PROCESSOR).o small_page.o
+obj-y		:= init.o
 obj-m		:=
 obj-n		:=
 obj-		:=
-export-objs	:= proc-syms.o
+export-objs	:= proc-syms.o discontig.o
 
+cpu32-y		:= consistent.o fault-armv.o ioremap.o mm-armv.o
+cpu32-$(CONFIG_MODULES) += proc-syms.o
+
+obj-y		+= extable.o fault-common.o
+obj-$(CONFIG_CPU_26) += fault-armo.o mm-armo.o small_page.o
+obj-$(CONFIG_CPU_32) += $(cpu32-y)
+
+obj-$(CONFIG_DISCONTIGMEM) += discontig.o
+
+# Select the processor-specific files
 p-$(CONFIG_CPU_26)	+= proc-arm2,3.o
 p-$(CONFIG_CPU_ARM610)	+= proc-arm6,7.o
 p-$(CONFIG_CPU_ARM710)	+= proc-arm6,7.o
 p-$(CONFIG_CPU_ARM720T)	+= proc-arm720.o
 p-$(CONFIG_CPU_ARM920T)	+= proc-arm920.o
-p-$(CONFIG_CPU_ARM10)	+= proc-arm10.o
+p-$(CONFIG_CPU_ARM926T)	+= proc-arm926.o
+p-$(CONFIG_CPU_ARM940T)	+= proc-arm940.o
+p-$(CONFIG_CPU_ARM1020)	+= proc-arm1020.o
 p-$(CONFIG_CPU_SA110)	+= proc-sa110.o
 p-$(CONFIG_CPU_SA1100)	+= proc-sa110.o
 
-obj-$(CONFIG_CPU_32)  	+= consistent.o ioremap.o
-ifeq ($(CONFIG_CPU_32),y)
-obj-$(CONFIG_MODULES)	+= proc-syms.o
+# Integrator follows "new style"
+# Soon, others will do too, and we can get rid of this
+MMMACH		:= mm-$(MACHINE).c
+ifeq ($(MMMACH),$(wildcard $(MMMACH)))
+obj-$(CONFIG_CPU_32)	+= $(MMMACH:.c=.o)
 endif
 
 obj-y		+= $(sort $(p-y))
@@ -39,10 +52,4 @@
 include $(TOPDIR)/Rules.make
 
 # Special dependencies
-proc-arm2,3.o:	$(TOPDIR)/include/asm-armnommu/constants.h
-proc-arm6,7.o:	$(TOPDIR)/include/asm-armnommu/constants.h
-proc-arm720.o:	$(TOPDIR)/include/asm-armnommu/constants.h
-proc-arm920.o:	$(TOPDIR)/include/asm-armnommu/constants.h
-proc-arm10.o:	$(TOPDIR)/include/asm-armnommu/constants.h
-proc-sa110.o:	$(TOPDIR)/include/asm-armnommu/constants.h
-
+$(p-y):	$(TOPDIR)/include/asm/constants.h
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/consistent.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/consistent.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/consistent.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/consistent.c	2004-12-06 19:35:49.000000000 +0100
@@ -44,11 +44,6 @@
 	size = PAGE_ALIGN(size);
 	order = get_order(size);
 
-	if (order > 0) {
-		printk("getting order %ld area\n", order);
-		__backtrace();
-	}
-
 	page = alloc_pages(gfp, order);
 	if (!page)
 		goto no_page;
@@ -57,8 +52,8 @@
 	 * We could do with a page_to_phys and page_to_bus here.
 	 */
 	virt = page_address(page);
-	*dma_handle = (dma_addr_t)virt_to_bus(virt);
-	ret = __ioremap((unsigned long)virt_to_phys(virt), size, 0);
+	*dma_handle = virt_to_bus(virt);
+	ret = __ioremap(virt_to_phys(virt), size, 0);
 	if (!ret)
 		goto no_remap;
 
@@ -72,25 +67,27 @@
 #endif
 
 	/*
-	 * free wasted pages.  We skip the first page since
-	 * we know that it will have count = 1 and won't
-	 * require freeing.
+	 * free wasted pages.  We skip the first page since we know
+	 * that it will have count = 1 and won't require freeing.
+	 * We also mark the pages in use as reserved so that
+	 * remap_page_range works.
 	 */
 	page = virt_to_page(virt);
 	free = page + (size >> PAGE_SHIFT);
 	end  = page + (1 << order);
 
-	while (++page < end) {
+	for (; page < end; page++) {
 		set_page_count(page, 1);
 		if (page >= free)
 			__free_page(page);
+		else
+			SetPageReserved(page);
 	}
 	return ret;
 
 no_remap:
 	__free_pages(page, order);
 no_page:
-	BUG();
 	return NULL;
 }
 
@@ -114,11 +111,27 @@
  * free a page as defined by the above mapping.  We expressly forbid
  * calling this from interrupt context.
  */
-void consistent_free(void *vaddr)
+void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
 {
+	struct page *page, *end;
+	void *virt;
+
 	if (in_interrupt())
 		BUG();
 
+	virt = bus_to_virt(handle);
+
+	/*
+	 * More messing around with the MM internals.  This is
+	 * sick, but then so is remap_page_range().
+	 */
+	size = PAGE_ALIGN(size);
+	page = virt_to_page(virt);
+	end = page + (size >> PAGE_SHIFT);
+
+	for (; page < end; page++)
+		ClearPageReserved(page);
+
 	__iounmap(vaddr);
 }
 
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/fault-armv.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/fault-armv.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/fault-armv.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/fault-armv.c	2004-12-06 19:35:49.000000000 +0100
@@ -24,12 +24,19 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/unaligned.h>
 
 extern void die_if_kernel(const char *str, struct pt_regs *regs, int err);
 extern void show_pte(struct mm_struct *mm, unsigned long addr);
-extern int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs);
+extern int do_page_fault(unsigned long addr, int error_code,
+			 struct pt_regs *regs);
+extern int do_translation_fault(unsigned long addr, int error_code,
+				struct pt_regs *regs);
+extern void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
+			unsigned long addr, int error_code,
+			struct pt_regs *regs);
 
 #ifdef CONFIG_ALIGNMENT_TRAP
 /*
@@ -52,6 +57,8 @@
 #define LDST_W_BIT(i)	(i & (1 << 21))		/* Writeback		*/
 #define LDST_L_BIT(i)	(i & (1 << 20))		/* Load			*/
 
+#define LDST_P_EQ_U(i)	((((i) ^ ((i) >> 1)) & (1 << 23)) == 0)
+
 #define LDSTH_I_BIT(i)	(i & (1 << 22))		/* half-word immed	*/
 #define LDM_S_BIT(i)	(i & (1 << 22))		/* write CPSR from SPSR	*/
 
@@ -115,91 +122,331 @@
 __initcall(alignment_init);
 #endif /* CONFIG_SYSCTL */
 
+union offset_union {
+	unsigned long un;
+	  signed long sn;
+};
+
+#define TYPE_ERROR	0
+#define TYPE_FAULT	1
+#define TYPE_LDST	2
+#define TYPE_DONE	3
+
+#define get8_unaligned_check(val,addr,err)		\
+	__asm__(					\
+	"1:	ldrb	%1, [%2], #1\n"			\
+	"2:\n"						\
+	"	.section .fixup,\"ax\"\n"		\
+	"	.align	2\n"				\
+	"3:	mov	%0, #1\n"			\
+	"	b	2b\n"				\
+	"	.previous\n"				\
+	"	.section __ex_table,\"a\"\n"		\
+	"	.align	3\n"				\
+	"	.long	1b, 3b\n"			\
+	"	.previous\n"				\
+	: "=r" (err), "=&r" (val), "=r" (addr)		\
+	: "0" (err), "2" (addr))
+
+#define get8t_unaligned_check(val,addr,err)		\
+	__asm__(					\
+	"1:	ldrbt	%1, [%2], #1\n"			\
+	"2:\n"						\
+	"	.section .fixup,\"ax\"\n"		\
+	"	.align	2\n"				\
+	"3:	mov	%0, #1\n"			\
+	"	b	2b\n"				\
+	"	.previous\n"				\
+	"	.section __ex_table,\"a\"\n"		\
+	"	.align	3\n"				\
+	"	.long	1b, 3b\n"			\
+	"	.previous\n"				\
+	: "=r" (err), "=&r" (val), "=r" (addr)		\
+	: "0" (err), "2" (addr))
+
+#define get16_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		get8_unaligned_check(val,a,err);		\
+		get8_unaligned_check(v,a,err);			\
+		val |= v << 8;					\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put16_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v = val, a = addr;	\
+		__asm__(					\
+		"1:	strb	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"2:	strb	%1, [%2]\n"			\
+		"3:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"	.align	2\n"				\
+		"4:	mov	%0, #1\n"			\
+		"	b	3b\n"				\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.align	3\n"				\
+		"	.long	1b, 4b\n"			\
+		"	.long	2b, 4b\n"			\
+		"	.previous\n"				\
+		: "=r" (err), "=&r" (v), "=&r" (a)		\
+		: "0" (err), "1" (v), "2" (a));			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define __put32_unaligned_check(ins,val,addr)			\
+	do {							\
+		unsigned int err = 0, v = val, a = addr;	\
+		__asm__(					\
+		"1:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"2:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"3:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"4:	"ins"	%1, [%2]\n"			\
+		"5:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"	.align	2\n"				\
+		"6:	mov	%0, #1\n"			\
+		"	b	5b\n"				\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.align	3\n"				\
+		"	.long	1b, 6b\n"			\
+		"	.long	2b, 6b\n"			\
+		"	.long	3b, 6b\n"			\
+		"	.long	4b, 6b\n"			\
+		"	.previous\n"				\
+		: "=r" (err), "=&r" (v), "=&r" (a)		\
+		: "0" (err), "1" (v), "2" (a));			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define get32_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		get8_unaligned_check(val,a,err);		\
+		get8_unaligned_check(v,a,err);			\
+		val |= v << 8;					\
+		get8_unaligned_check(v,a,err);			\
+		val |= v << 16;					\
+		get8_unaligned_check(v,a,err);			\
+		val |= v << 24;					\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put32_unaligned_check(val,addr)	 \
+	__put32_unaligned_check("strb", val, addr)
+
+#define get32t_unaligned_check(val,addr)			\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		get8t_unaligned_check(val,a,err);		\
+		get8t_unaligned_check(v,a,err);			\
+		val |= v << 8;					\
+		get8t_unaligned_check(v,a,err);			\
+		val |= v << 16;					\
+		get8t_unaligned_check(v,a,err);			\
+		val |= v << 24;					\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put32t_unaligned_check(val,addr) \
+	__put32_unaligned_check("strbt", val, addr)
+
+static void
+do_alignment_finish_ldst(unsigned long addr, unsigned long instr, struct pt_regs *regs, union offset_union offset)
+{
+	if (!LDST_U_BIT(instr))
+		offset.un = -offset.un;
+
+	if (!LDST_P_BIT(instr))
+		addr += offset.un;
+
+	if (!LDST_P_BIT(instr) || LDST_W_BIT(instr))
+		regs->uregs[RN_BITS(instr)] = addr;
+}
+
 static int
-do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
+do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs)
 {
-	unsigned int instr, rd, rn, correction, nr_regs, regbits;
-	unsigned long eaddr;
-	union { unsigned long un; signed long sn; } offset;
+	unsigned int rd = RD_BITS(instr);
 
-	if (user_mode(regs)) {
-		set_cr(cr_no_alignment);
-		ai_user += 1;
-		return 0;
-	}
+	if ((instr & 0x01f00ff0) == 0x01000090)
+		goto swp;
 
-	ai_sys += 1;
+	if ((instr & 0x90) != 0x90 || (instr & 0x60) == 0)
+		goto bad;
 
-	instr = *(unsigned long *)instruction_pointer(regs);
-	correction = 4; /* sometimes 8 on ARMv3 */
-	regs->ARM_pc += correction + 4;
+	ai_half += 1;
 
-	rd = RD_BITS(instr);
-	rn = RN_BITS(instr);
-	eaddr = regs->uregs[rn];
+	if (LDST_L_BIT(instr)) {
+		unsigned long val;
+		get16_unaligned_check(val, addr);
 
-	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;
-		}
+		/* signed half-word? */
+		if (instr & 0x40)
+			val = (signed long)((signed short) val);
 
-		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)];
+		regs->uregs[rd] = val;
+	} else
+		put16_unaligned_check(regs->uregs[rd], addr);
 
-			if (LDST_P_BIT(instr)) {
-				if (LDST_U_BIT(instr))
-					eaddr += offset.un;
-				else
-					eaddr -= offset.un;
-			}
+	return TYPE_LDST;
+
+swp:
+	printk(KERN_ERR "Alignment trap: not handling swp instruction\n");
+bad:
+	return TYPE_ERROR;
+
+fault:
+	return TYPE_FAULT;
+}
 
-			/*
-			 * This is a "hint" - we already have eaddr worked out by the
-			 * processor for us.
-			 */
-			if (addr != eaddr)
-				printk(KERN_ERR "LDRHSTRH: PC = %08lx, instr = %08x, "
-					"addr = %08lx, eaddr = %08lx\n",
-					 instruction_pointer(regs), instr, addr, eaddr);
+static int
+do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+	unsigned int rd = RD_BITS(instr);
+
+	ai_word += 1;
+
+	if (!LDST_P_BIT(instr) && LDST_W_BIT(instr))
+		goto trans;
+
+	if (LDST_L_BIT(instr))
+		get32_unaligned_check(regs->uregs[rd], addr);
+	else
+		put32_unaligned_check(regs->uregs[rd], addr);
+	return TYPE_LDST;
+
+trans:
+	if (LDST_L_BIT(instr))
+		get32t_unaligned_check(regs->uregs[rd], addr);
+	else
+		put32t_unaligned_check(regs->uregs[rd], addr);
+	return TYPE_LDST;
+
+fault:
+	return TYPE_FAULT;
+}
 
+/*
+ * LDM/STM alignment handler.
+ *
+ * There are 4 variants of this instruction:
+ *
+ * B = rn pointer before instruction, A = rn pointer after instruction
+ *              ------ increasing address ----->
+ *	        |    | r0 | r1 | ... | rx |    |
+ * PU = 01             B                    A
+ * PU = 11        B                    A
+ * PU = 00        A                    B
+ * PU = 10             A                    B
+ */
+static int
+do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+	unsigned int rd, rn, correction, nr_regs, regbits;
+	unsigned long eaddr, newaddr;
+
+	if (LDM_S_BIT(instr))
+		goto bad;
+
+	correction = 4; /* processor implementation defined */
+	regs->ARM_pc += correction;
+
+	ai_multi += 1;
+
+	/* count the number of registers in the mask to be transferred */
+	for (regbits = REGMASK_BITS(instr), nr_regs = 0; regbits; regbits >>= 1)
+		nr_regs += 4;
+
+	rn = RN_BITS(instr);
+	newaddr = eaddr = regs->uregs[rn];
+
+	if (!LDST_U_BIT(instr))
+		nr_regs = -nr_regs;
+	newaddr += nr_regs;
+	if (!LDST_U_BIT(instr))
+		eaddr = newaddr;
+
+	if (LDST_P_EQ_U(instr))	/* U = P */
+		eaddr += 4;
+
+	/*
+	 * This is a "hint" - we already have eaddr worked out by the
+	 * processor for us.
+	 */
+	if (addr != eaddr)
+		printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, "
+			"addr = %08lx, eaddr = %08lx\n",
+			 instruction_pointer(regs), instr, addr, eaddr);
+
+	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 short *)eaddr);
+				get32_unaligned_check(regs->uregs[rd], 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;
+				put32_unaligned_check(regs->uregs[rd], eaddr);
+			eaddr += 4;
 		}
 
-	default:
-		ai_skipped += 1;
-		panic("Alignment trap: not handling instruction %08X at %08lX",
-				instr, regs->ARM_pc - correction - 4);
+	if (LDST_W_BIT(instr))
+		regs->uregs[rn] = newaddr;
+	if (!LDST_L_BIT(instr) || !(REGMASK_BITS(instr) & (1 << 15)))
+		regs->ARM_pc -= correction;
+	return TYPE_DONE;
+
+fault:
+	regs->ARM_pc -= correction;
+	return TYPE_FAULT;
+
+bad:
+	printk(KERN_ERR "Alignment trap: not handling ldm with s-bit set\n");
+	return TYPE_ERROR;
+}
+
+static int
+do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+	union offset_union offset;
+	unsigned long instr, instrptr;
+	int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
+	unsigned int type;
+
+	if (user_mode(regs))
+		goto user;
+
+	ai_sys += 1;
+
+	instrptr = instruction_pointer(regs);
+	instr = *(unsigned long *)instrptr;
+
+	regs->ARM_pc += 4;
+
+	switch (CODING_BITS(instr)) {
+	case 0x00000000:	/* ldrh or strh */
+		if (LDSTH_I_BIT(instr))
+			offset.un = (instr & 0xf00) >> 4 | (instr & 15);
+		else
+			offset.un = regs->uregs[RM_BITS(instr)];
+		handler = do_alignment_ldrhstrh;
 		break;
 
-	case 0x04000000:
+	case 0x04000000:	/* ldr or str immediate */
 		offset.un = OFFSET_BITS(instr);
-		goto ldr_str;
+		handler = do_alignment_ldrstr;
+		break;
 
-	case 0x06000000:
+	case 0x06000000:	/* ldr or str register */
 		offset.un = regs->uregs[RM_BITS(instr)];
 
 		if (IS_SHIFT(instr)) {
@@ -229,97 +476,49 @@
 				break;
 			}
 		}
+		handler = do_alignment_ldrstr;
+		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;
-			}
-		}
+	case 0x08000000:	/* ldm or stm */
+		handler = do_alignment_ldmstm;
+		break;
 
-		/*
-		 * This is a "hint" - we already have eaddr worked out by the
-		 * processor for us.
-		 */
-		if (addr != eaddr)
-			printk(KERN_ERR "LDRSTR: PC = %08lx, instr = %08x, "
-				"addr = %08lx, eaddr = %08lx\n",
-				 instruction_pointer(regs), instr, addr, eaddr);
-
-		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;
+	default:
+		goto bad;
+	}
 
-			regs->uregs[rn] = eaddr;
-		} else if (LDST_W_BIT(instr))
-			regs->uregs[rn] = eaddr;
-		break;
+	type = handler(addr, instr, regs);
 
-	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;
-
-		/*
-		 * This is a "hint" - we already have eaddr worked out by the
-		 * processor for us.
-		 */
-		if (addr != eaddr)
-			printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08x, "
-				"addr = %08lx, eaddr = %08lx\n",
-				 instruction_pointer(regs), instr, addr, eaddr);
+	if (type == TYPE_ERROR || type == TYPE_FAULT)
+		goto bad_or_fault;
 
-		if ((LDST_U_BIT(instr) == 0 && LDST_P_BIT(instr) == 0) ||
-		    (LDST_U_BIT(instr)      && LDST_P_BIT(instr)))
-			eaddr += 4;
+	if (type == TYPE_LDST)
+		do_alignment_finish_ldst(addr, instr, regs, offset);
 
-		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;
-			}
+	return 0;
 
-		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;
-	}
+bad_or_fault:
+	if (type == TYPE_ERROR)
+		goto bad;
+	regs->ARM_pc -= 4;
+	/*
+	 * We got a fault - fix it up, or die.
+	 */
+	do_bad_area(current, current->mm, addr, error_code, regs);
+	return 0;
 
-	regs->ARM_pc -= correction;
+bad:
+	/*
+	 * Oops, we didn't handle the instruction.
+	 */
+	printk(KERN_ERR "Alignment trap: not handling instruction "
+		"%08lx at [<%08lx>]", instr, instrptr);
+	ai_skipped += 1;
+	return 1;
 
+user:
+	set_cr(cr_no_alignment);
+	ai_user += 1;
 	return 0;
 }
 
@@ -332,35 +531,28 @@
 /*
  * Some section permission faults need to be handled gracefully, for
  * instance, when they happen due to a __{get,put}_user during an oops).
- * In this case, we should return an error to the __{get,put}_user caller
- * instead of causing another oops.  We should also fixup this fault as
- * the user could pass a pointer to a section to the kernel.
  */
 static int
 do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs)
 {
-	unsigned long fixup;
+	struct task_struct *tsk = current;
+	do_bad_area(tsk, tsk->active_mm, addr, error_code, regs);
+	return 0;
+}
 
-	if (user_mode(regs)) {
-#ifdef CONFIG_DEBUG_USER
-		printk("%s: permission fault on section, "
-		       "address=0x%08lx, code %d\n",
-		       current->comm, addr, error_code);
-#endif
-		goto fail;
-	}
+/*
+ * Hook for things that need to trap external faults.  Note that
+ * we don't guarantee that this will be the final version of the
+ * interface.
+ */
+int (*external_fault)(unsigned long addr, struct pt_regs *regs);
 
-	fixup = search_exception_table(instruction_pointer(regs));
-	if (fixup != 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 0;
-	}
-fail:
-	return 1;	/* not fixed up */
+static int
+do_external_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+	if (external_fault)
+		return external_fault(addr, regs);
+	return 1;
 }
 
 static const struct fsr_info {
@@ -369,17 +561,17 @@
 	char	*name;
 } fsr_info[] = {
 	{ NULL,			SIGSEGV, "vector exception"		   },
-	{ do_alignment,		SIGBUS,	 "alignment exception"		   },
+	{ do_alignment,		SIGILL,	 "alignment exception"		   },
 	{ NULL,			SIGKILL, "terminal exception"		   },
-	{ do_alignment,		SIGBUS,	 "alignment exception"		   },
-	{ NULL,			SIGBUS,	 "external abort on linefetch"	   },
-	{ do_page_fault,	SIGSEGV, "page fault"			   },
-	{ NULL,			SIGBUS,	 "external abort on linefetch"	   },
-	{ do_page_fault,	SIGSEGV, "page fault"			   },
-	{ NULL,			SIGBUS,	 "external abort on non-linefetch" },
-	{ NULL,			SIGSEGV, "domain fault"			   },
-	{ NULL,			SIGBUS,	 "external abort on non-linefetch" },
-	{ NULL,			SIGSEGV, "domain fault"			   },
+	{ do_alignment,		SIGILL,	 "alignment exception"		   },
+	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
+	{ do_translation_fault,	SIGSEGV, "section translation fault"	   },
+	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
+	{ do_page_fault,	SIGSEGV, "page translation fault"	   },
+	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
+	{ NULL,			SIGSEGV, "section domain fault"		   },
+	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
+	{ NULL,			SIGSEGV, "page domain fault"		   },
 	{ NULL,			SIGBUS,	 "external abort on translation"   },
 	{ do_sect_fault,	SIGSEGV, "section permission fault"	   },
 	{ NULL,			SIGBUS,	 "external abort on translation"   },
@@ -394,14 +586,10 @@
 {
 	const struct fsr_info *inf = fsr_info + (fsr & 15);
 
-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
+#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) || defined(CONFIG_DEBUG_ERRORS)
 	if (addr == regs->ARM_pc)
 		goto sa1_weirdness;
 #endif
-#if defined(CONFIG_CPU_ARM720) && defined(CONFIG_ALIGNMENT_TRAP)
-	if (addr & 3 && (fsr & 13) != 1)
-		goto arm720_weirdness;
-#endif
 
 	if (!inf->fn)
 		goto bad;
@@ -410,19 +598,20 @@
 		return;
 bad:
 	force_sig(inf->sig, current);
-
 	printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n",
 		inf->name, fsr, addr);
 	show_pte(current->mm, addr);
 	die_if_kernel("Oops", regs, 0);
 	return;
 
-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
+#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) || defined(CONFIG_DEBUG_ERRORS)
 sa1_weirdness:
 	if (user_mode(regs)) {
 		static int first = 1;
-		if (first)
-			printk(KERN_DEBUG "Weird data abort detected\n");
+		if (first) {
+			printk(KERN_DEBUG "Fixing up bad data abort at %08lx\n", addr);
+			show_pte(current->mm, addr);
+		}
 		first = 0;
 		return;
 	}
@@ -431,37 +620,26 @@
 		goto bad;
 	return;
 #endif
-#if defined(CONFIG_CPU_ARM720) && defined(CONFIG_ALIGNMENT_TRAP)
-arm720_weirdness:
-	if (!user_mode(regs)) {
-		unsigned long instr;
-
-		instr = *(unsigned long *)instruction_pointer(regs);
-
-		if ((instr & 0x04400000) != 0x04400000) {
-			static int first = 1;
-			if (first)
-				printk("Mis-reported alignment fault at "
-					"0x%08lx, fsr 0x%02x, code 0x%02x, "
-					"PC = 0x%08lx, instr = 0x%08lx\n",
-					addr, fsr, error_code, regs->ARM_pc,
-					instr);
-			first = 0;
-			cpu_tlb_invalidate_all();
-			cpu_cache_clean_invalidate_all();
-			return;
-		}
-	}
-
-	if (!inf->fn || inf->fn(addr, error_code, regs))
-		goto bad;
-	return;
-#endif
 }
 
-asmlinkage int
+asmlinkage void
 do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
 {
-	do_page_fault(addr, 0, regs);
-	return 1;
+	do_translation_fault(addr, 0, regs);
+}
+
+/*
+ * if PG_dcache_dirty is set for the page, we need to ensure that any
+ * cache entries for the kernels virtual memory range are written
+ * back to the page.
+ */
+void check_pgcache_dirty(struct page *page)
+{
+#ifndef CONFIG_UCLINUX
+	if (VALID_PAGE(page) && page->mapping &&
+	    test_and_clear_bit(PG_dcache_dirty, &page->flags)) {
+		unsigned long kvirt = (unsigned long)page_address(page);
+		cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0);
+	}
+#endif
 }
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/fault-common.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/fault-common.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/fault-common.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/fault-common.c	2004-12-06 19:35:49.000000000 +0100
@@ -51,56 +51,220 @@
  */
 void show_pte(struct mm_struct *mm, unsigned long addr)
 {
-	/* No pte in nommu, I think --gmcnutt */
+#ifndef CONFIG_UCLINUX
+	pgd_t *pgd;
+
+	if (!mm)
+		mm = &init_mm;
+
+	printk(KERN_ALERT "pgd = %p\n", 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)");
+			break;
+		}
+
+		pmd = pmd_offset(pgd, addr);
+		printk(", *pmd = %08lx", pmd_val(*pmd));
+
+		if (pmd_none(*pmd))
+			break;
+
+		if (pmd_bad(*pmd)) {
+			printk("(bad)");
+			break;
+		}
+
+		pte = pte_offset(pmd, addr);
+		printk(", *pte = %08lx", pte_val(*pte));
+#ifdef CONFIG_CPU_32
+		printk(", *ppte = %08lx", pte_val(pte[-PTRS_PER_PTE]));
+#endif
+	} while(0);
+
+	printk("\n");
+#else
+	printk("%s %d\n",__FILE__,__LINE__);
+#endif
+}
+
+/*
+ * Oops.  The kernel tried to access some page that wasn't present.
+ */
+static void
+__do_kernel_fault(struct mm_struct *mm, unsigned long addr, int error_code,
+		  struct pt_regs *regs)
+{
+	unsigned long fixup;
+
+	/*
+	 * 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;
+	}
+
+	/*
+	 * No handler, we'll have to terminate things with extreme prejudice.
+	 */
+	printk(KERN_ALERT
+		"Unable to handle kernel %s at virtual address %08lx\n",
+		(addr < PAGE_SIZE) ? "NULL pointer dereference" :
+		"paging request", addr);
+
+	show_pte(mm, addr);
+	die("Oops", regs, error_code);
+	do_exit(SIGKILL);
+}
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * User mode accesses just cause a SIGSEGV
+ */
+static void
+__do_user_fault(struct task_struct *tsk, unsigned long addr, int error_code,
+		int code, struct pt_regs *regs)
+{
+	struct siginfo si;
+
+#ifdef CONFIG_DEBUG_USER
+	printk(KERN_DEBUG "%s: unhandled page fault at pc=0x%08lx, "
+	       "lr=0x%08lx (bad address=0x%08lx, code %d)\n",
+	       tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, error_code);
+#endif
+
+	tsk->thread.address = addr;
+	tsk->thread.error_code = error_code;
+	tsk->thread.trap_no = 14;
+	si.si_signo = SIGSEGV;
+	si.si_errno = 0;
+	si.si_code = code;
+	si.si_addr = (void *)addr;
+	force_sig_info(SIGSEGV, &si, tsk);
+}
+
+void
+do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
+	    int error_code, struct pt_regs *regs)
+{
+	/*
+	 * If we are in kernel mode at this point, we
+	 * have no context to handle this fault with.
+	 */
+	if (user_mode(regs))
+		__do_user_fault(tsk, addr, error_code, SEGV_MAPERR, regs);
+	else
+		__do_kernel_fault(mm, addr, error_code, regs);
 }
 
 static int
-__do_page_fault(struct mm_struct *mm, unsigned long addr, int mode,
+__do_page_fault(struct mm_struct *mm, unsigned long addr, int error_code,
 		struct task_struct *tsk)
 {
+#ifndef CONFIG_UCLINUX
+	struct vm_area_struct *vma;
+	int fault, mask;
+
+	vma = find_vma(mm, addr);
+	fault = -2; /* bad map area */
+	if (!vma)
+		goto out;
+	if (vma->vm_start > addr)
+		goto check_stack;
+
+	/*
+	 * Ok, we have a good vm_area for this
+	 * memory access, so we can handle it.
+	 */
+good_area:
+	if (READ_FAULT(error_code)) /* read? */
+		mask = VM_READ|VM_EXEC;
+	else
+		mask = VM_WRITE;
+
+	fault = -1; /* bad access type */
+	if (!(vma->vm_flags & mask))
+		goto out;
+
+	/*
+	 * If for any reason at all we couldn't handle
+	 * the fault, make sure we exit gracefully rather
+	 * than endlessly redo the fault.
+	 */
+survive:
+	fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(error_code));
+
+	/*
+	 * Handle the "normal" cases first - successful and sigbus
+	 */
+	switch (fault) {
+	case 2:
+		tsk->maj_flt++;
+		return fault;
+	case 1:
+		tsk->min_flt++;
+	case 0:
+		return fault;
+	}
+
+	fault = -3; /* out of memory */
+	if (tsk->pid != 1)
+		goto out;
+
 	/*
-	 * In the normal ARM code we return -2 if we can't find the vma.
-	 * Well, with no mmu, we'll never find the vma.
-	 * I don't even know if we'll ever call this function...
-	 * --gmcnutt
+	 * If we are out of memory for pid1,
+	 * sleep for a while and retry
 	 */
-	return -2;
+	tsk->policy |= SCHED_YIELD;
+	schedule();
+	goto survive;
+
+check_stack:
+	if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
+		goto good_area;
+out:
+	return fault;
+#else
+	printk("%s %d\n",__FILE__,__LINE__);
+	return 0;
+#endif
 }
 
-int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
+int do_page_fault(unsigned long addr, int error_code, struct pt_regs *regs)
 {
+#ifdef CONFIG_UCLINUX
 	struct task_struct *tsk;
 	struct mm_struct *mm;
-	unsigned long fixup;
 	int fault;
 
 	tsk = current;
 	mm  = tsk->mm;
 
 	/*
-	 * We fault-in kernel-space virtual memory on-demand. The
-	 * 'reference' page table is init_mm.pgd.
-	 *
-	 * NOTE! We MUST NOT take any locks for this case. We may
-	 * be in an interrupt or a critical region, and should
-	 * only copy the information from the master page table,
-	 * nothing more.
-	 */
-	if (addr >= TASK_SIZE)
-		goto vmalloc_fault;
-
-	/*
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
 	 */
 	if (in_interrupt() || !mm)
 		goto no_context;
 
-	down_write(&mm->mmap_sem);
-	fault = __do_page_fault(mm, addr, mode, tsk);
-	up_write(&mm->mmap_sem);
+	down_read(&mm->mmap_sem);
+	fault = __do_page_fault(mm, addr, error_code, tsk);
+	up_read(&mm->mmap_sem);
 
-ret:
 	/*
 	 * Handle the "normal" case first
 	 */
@@ -128,28 +292,9 @@
 		 */
 		printk("VM: killing process %s\n", tsk->comm);
 		do_exit(SIGKILL);
-	} else {
-		/*
-		 * Something tried to access memory that isn't in our memory map..
-		 * User mode accesses just cause a SIGSEGV
-		 */
-		struct siginfo si;
-
-#ifdef CONFIG_DEBUG_USER
-		printk(KERN_DEBUG "%s: unhandled page fault 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
-
-		tsk->thread.address = addr;
-		tsk->thread.error_code = mode;
-		tsk->thread.trap_no = 14;
-		si.si_signo = SIGSEGV;
-		si.si_errno = 0;
-		si.si_code = fault == -1 ? SEGV_ACCERR : SEGV_MAPERR;
-		si.si_addr = (void *)addr;
-		force_sig_info(SIGSEGV, &si, tsk);
-	}
+	} else
+		__do_user_fault(tsk, addr, error_code, fault == -1 ?
+				SEGV_ACCERR : SEGV_MAPERR, regs);
 	return 0;
 
 
@@ -163,7 +308,7 @@
 	 * or user mode.
 	 */
 	tsk->thread.address = addr;
-	tsk->thread.error_code = mode;
+	tsk->thread.error_code = error_code;
 	tsk->thread.trap_no = 14;
 	force_sig(SIGBUS, tsk);
 
@@ -172,39 +317,73 @@
 		return 0;
 
 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);
+	__do_kernel_fault(mm, addr, error_code, regs);
+	return 0;
+#else
+	printk("%s %d\n",__FILE__,__LINE__);
+	return 0;
 #endif
-		regs->ARM_pc = fixup;
-		return 0;
-	}
+}
 
-	/*
-	 * Oops. The kernel tried to access some bad page. We'll have to
-	 * terminate things with extreme prejudice.
-	 */
-	printk(KERN_ALERT
-		"Unable to handle kernel %s at virtual address %08lx\n",
-		(addr < PAGE_SIZE) ? "NULL pointer dereference" :
-		"paging request", addr);
+/*
+ * First Level Translation Fault Handler
+ *
+ * We enter here because the first level page table doesn't contain
+ * a valid entry for the address.
+ *
+ * If the address is in kernel space (>= TASK_SIZE), then we are
+ * probably faulting in the vmalloc() area.
+ *
+ * If the init_task's first level page tables contains the relevant
+ * entry, we copy the it to this task.  If not, we send the process
+ * a signal, fixup the exception, or oops the kernel.
+ *
+ * NOTE! We MUST NOT take any locks for this case. We may be in an
+ * interrupt or a critical region, and should only copy the information
+ * from the master page table, nothing more.
+ */
+int do_translation_fault(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+#ifndef CONFIG_UCLINUX
+	struct task_struct *tsk;
+	struct mm_struct *mm;
+	int offset;
+	pgd_t *pgd, *pgd_k;
+	pmd_t *pmd, *pmd_k;
 
-	show_pte(mm, addr);
-	die("Oops", regs, mode);
-	do_exit(SIGKILL);
+	if (addr < TASK_SIZE)
+		return do_page_fault(addr, error_code, regs);
 
+	tsk = current;
+	mm  = tsk->active_mm;
+
+	offset = __pgd_offset(addr);
+
+	pgd_k = init_mm.pgd + offset;
+	pgd   = mm->pgd + offset;
+
+	if (pgd_none(*pgd_k))
+		goto bad_area;
+
+#if 0	/* note that we are two-level */
+	if (!pgd_present(*pgd))
+		set_pgd(pgd, *pgd_k);
+#endif
+
+	pmd_k = pmd_offset(pgd_k, addr);
+	pmd   = pmd_offset(pgd, addr);
+
+	if (pmd_none(*pmd_k))
+		goto bad_area;
+
+	set_pmd(pmd, *pmd_k);
 	return 0;
 
-vmalloc_fault:
-	/*
-	 * I blew away __do_vmalloc_fault because it was mucking with vma stuff
-	 * mmnommu doesn't support. I noted that it returns -2 for unsupported
-	 * memory areas, and I think any page fault in physical memory falls
-	 * into this category, so we'll emulate that here.
-	 * --gmcnutt
-	 */
-	fault = -2;
-	goto ret;
+bad_area:
+	do_bad_area(tsk, mm, addr, error_code, regs);
+	return 0;
+#else
+	printk("%s %d\n",__FILE__,__LINE__);
+	return 0;
+#endif
 }
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/init.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/init.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/init.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/init.c	2004-12-06 19:35:49.000000000 +0100
@@ -49,6 +49,7 @@
 #define TABLE_SIZE	((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
 
 static unsigned long totalram_pages;
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern char _stext, _text, _etext, _end, __init_begin, __init_end;
 
 /*
@@ -58,52 +59,43 @@
 static struct meminfo meminfo __initdata = { 0, };
 
 /*
- * empty_bad_page is the page that is used for page faults when
- * linux is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
- * unused etc..
- *
- * empty_bad_pte_table is the accompanying page-table: it is
- * initialized to point to BAD_PAGE entries.
- *
  * empty_zero_page is a special page that is used for
  * zero-initialized data and COW.
  */
 struct page *empty_zero_page;
-struct page *empty_bad_page;
-pte_t *empty_bad_pte_table;
 
-pte_t *get_bad_pte_table(void)
-{
-	pte_t v;
-	int i;
+#ifndef CONFIG_NO_PGT_CACHE
+struct pgtable_cache_struct quicklists;
 
-	v = pte_mkdirty(mk_pte(empty_bad_page, PAGE_SHARED));
 
-	for (i = 0; i < PTRS_PER_PTE; i++)
-		set_pte(empty_bad_pte_table + i, v);
+int do_check_pgt_cache(int low, int high)
+{
+	int freed = 0;
 
-	return empty_bad_pte_table;
+	if(pgtable_cache_size > high) {
+		do {
+			if(pgd_quicklist) {
+				free_pgd_slow(get_pgd_fast());
+				freed++;
+			}
+			if(pmd_quicklist) {
+				pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
+				freed++;
+			}
+			if(pte_quicklist) {
+				pte_free_slow(pte_alloc_one_fast(NULL, 0));
+				freed++;
+			}
+		} while(pgtable_cache_size > low);
+	}
+	return freed;
 }
-
-void __handle_bad_pmd(pmd_t *pmd)
+#else
+int do_check_pgt_cache(int low, int high)
 {
-	pmd_ERROR(*pmd);
-#ifdef CONFIG_DEBUG_ERRORS
-	__backtrace();
-#endif
-	set_pmd(pmd, mk_user_pmd(get_bad_pte_table()));
+	return 0;
 }
-
-void __handle_bad_pmd_kernel(pmd_t *pmd)
-{
-	pmd_ERROR(*pmd);
-#ifdef CONFIG_DEBUG_ERRORS
-	__backtrace();
 #endif
-	set_pmd(pmd, mk_kernel_pmd(get_bad_pte_table()));
-}
 
 void show_mem(void)
 {
@@ -184,38 +176,28 @@
 {
 	unsigned int start_pfn, bank, bootmap_pfn;
 
-	// Start with the first unused page frame number.
 	start_pfn   = V_PFN_UP(&_end);
 	bootmap_pfn = 0;
 
-	// Look for a bank in the desired node which has enough room to hold
-	// the bootmap pages on a page boundary.
 	for (bank = 0; bank < mi->nr_banks; bank ++) {
 		unsigned int start, end;
 
-		// Is this bank in the section of contiguous memory which the 
-		// caller wants us to use?
 		if (mi->bank[bank].node != node)
 			continue;
 
-		// Find the page frame numbers which span this bank.
 		start = O_PFN_UP(mi->bank[bank].start);
 		end   = O_PFN_DOWN(mi->bank[bank].size +
 				   mi->bank[bank].start);
 
-		// Is this bank already full?
 		if (end < start_pfn)
 			continue;
 
-		// Is this bank partially full?
 		if (start < start_pfn)
 			start = start_pfn;
 
-		// Um... sanity check, I guess.
 		if (end <= start)
 			continue;
 
-		// Will the bootmap fit in this bank?
 		if (end - start >= bootmap_pages) {
 			bootmap_pfn = start;
 			break;
@@ -362,18 +344,16 @@
 	 * Register the kernel text and data with bootmem.
 	 * Note that this can only be in node 0.
 	 */
-#ifdef CONFIG_ARCH_DSC21
-#ifdef CONFIG_REVISIT
-#error This part depends on our kernels odd location
-	/*
-	 * For the DSC21, as long as we're putting part of the kernel into SRAM
-	 * (below SDRAM) we don't want to try and do this. And we don't need to
-	 * do this, because the kernel is not where our memory manager can step
-	 * on it.
-	 * --gmcnutt
-	 */
 	reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
-#endif
+
+#ifdef CONFIG_CPU_32
+	/*
+	 * Reserve the page tables.  These are already in use,
+	 * and can only be in node 0.
+	 */
+	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
+			     PTRS_PER_PGD * sizeof(void *));
+
 #endif
 	/*
 	 * And don't forget to reserve the allocator bitmap,
@@ -382,6 +362,23 @@
 	reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT,
 			     bootmap_pages << PAGE_SHIFT);
 
+	/*
+	 * Hmm... This should go elsewhere, but we really really
+	 * need to stop things allocating the low memory; we need
+	 * a better implementation of GFP_DMA which does not assume
+	 * that DMA-able memory starts at zero.
+	 */
+	if (machine_is_integrator())
+		reserve_bootmem_node(pgdat, 0, __pa(swapper_pg_dir));
+	/*
+	 * These should likewise go elsewhere.  They pre-reserve
+	 * the screen memory region at the start of main system
+	 * memory.
+	 */
+	if (machine_is_archimedes() || machine_is_a5k())
+		reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
+	if (machine_is_p720t())
+		reserve_bootmem_node(pgdat, PAGE_OFFSET, 0x00014000);
 }
 
 /*
@@ -477,18 +474,23 @@
  */
 void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
 {
-	void *zero_page, *bad_page, *bad_table;
+	void *zero_page;
 	int node;
 
 	memcpy(&meminfo, mi, sizeof(meminfo));
 
 	/*
-	 * allocate what we need for the bad pages.
-	 * note that we count on this going ok.
+	 * allocate the zero page.  Note that we count on this going ok.
 	 */
 	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
-	bad_page  = alloc_bootmem_low_pages(PAGE_SIZE);
-	bad_table = alloc_bootmem_low_pages(TABLE_SIZE);
+#ifndef CONFIG_UCLINUX
+	/*
+	 * initialise the page tables.
+	 */
+	memtable_init(mi);
+	if (mdesc->map_io)
+		mdesc->map_io();
+	flush_tlb_all();
 
 	/*
 	 * initialise the zones within each node
@@ -535,17 +537,27 @@
 		free_area_init_node(node, pgdat, 0, zone_size,
 				bdata->node_boot_start, zhole_size);
 	}
+#else
+	{
+	  unsigned long zone_size[MAX_NR_ZONES] = {0,0,0};
+	  
+#if 0									/* Will try kernel from DMA. OZH */
+	  zone_size[ZONE_DMA] =
+#else	  
+	  zone_size[ZONE_NORMAL] =
+#endif
+	  (END_MEM - PAGE_OFFSET) >> PAGE_SHIFT;
 
+	  free_area_init_node(0, NULL, NULL, zone_size, PAGE_OFFSET, NULL);
+	}
+#endif
 	/*
 	 * finish off the bad pages once
 	 * the mem_map is initialised
 	 */
 	memzero(zero_page, PAGE_SIZE);
-	memzero(bad_page, PAGE_SIZE);
-
 	empty_zero_page = virt_to_page(zero_page);
-	empty_bad_page  = virt_to_page(bad_page);
-	empty_bad_pte_table = ((pte_t *)bad_table) + TABLE_OFFSET;
+	flush_dcache_page(empty_zero_page);
 }
 
 /*
@@ -575,6 +587,7 @@
 	for (node = 0; node < numnodes; node++)
 		totalram_pages += free_all_bootmem_node(NODE_DATA(node));
 
+	//	SetPageReserved(virt_to_page(PAGE_OFFSET));
 	/*
 	 * Since our memory may not be contiguous, calculate the
 	 * real number of pages we have in this system
@@ -584,16 +597,15 @@
 	num_physpages = 0;
 	for (i = 0; i < meminfo.nr_banks; i++) {
 		num_physpages += meminfo.bank[i].size >> PAGE_SHIFT;
-		printk(" %ldMB", meminfo.bank[i].size >> 20);
+		printk(" %ldK", meminfo.bank[i].size >> 10);
 	}
 
-	printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
+	printk(" = %luK total\n", num_physpages >> (10 - PAGE_SHIFT));
 	printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
 		"%dK data, %dK init)\n",
 		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 		codepages >> 10, datapages >> 10, initpages >> 10);
 
-#ifdef CONFIG_SYSCTL
 	if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
 		extern int sysctl_overcommit_memory;
 		/*
@@ -603,7 +615,6 @@
 		 */
 		sysctl_overcommit_memory = 1;
 	}
-#endif
 }
 
 static inline void free_area(unsigned long addr, unsigned long end, char *s)
@@ -624,7 +635,16 @@
 
 void free_initmem(void)
 {
-	if (!machine_is_integrator()) {
+	if (!machine_is_integrator() &&
+/*
+	    !machine_is_p52() &&
+	    !machine_is_atmel() &&
+*/
+	    !machine_is_cx821xx() &&
+	    !machine_is_cx861xx() &&
+	    !machine_is_uClinkII() &&
+	    !machine_is_evS3C4530LII() &&
+	    !machine_is_evS3C4530HEI()) {
 		free_area((unsigned long)(&__init_begin),
 			  (unsigned long)(&__init_end),
 			  "init");
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/mm-armv.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/mm-armv.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/mm/mm-armv.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/mm/mm-armv.c	2004-12-06 19:35:49.000000000 +0100
@@ -22,12 +22,6 @@
 
 #include <asm/mach/map.h>
 
-unsigned long *valid_addr_bitmap;
-
-extern unsigned long get_page_2k(int priority);
-extern void free_page_2k(unsigned long page);
-extern pte_t *get_bad_pte_table(void);
-
 /*
  * These are useful for identifing cache coherency
  * problems by allowing the cache or the cache and
@@ -69,91 +63,362 @@
 #define clean_cache_area(start,size) \
 	cpu_cache_clean_invalidate_range((unsigned long)start, ((unsigned long)start) + size, 0);
 
+
+/*
+ * need to get a 16k page for level 1
+ */
+pgd_t *get_pgd_slow(struct mm_struct *mm)
+{
+#ifndef CONFIG_UCLINUX
+	pgd_t *new_pgd, *init_pgd;
+	pmd_t *new_pmd, *init_pmd;
+	pte_t *new_pte, *init_pte;
+
+	new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
+	if (!new_pgd)
+		goto no_pgd;
+
+	memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));
+
+	init_pgd = pgd_offset_k(0);
+
+	if (vectors_base() == 0) {
+		init_pmd = pmd_offset(init_pgd, 0);
+		init_pte = pte_offset(init_pmd, 0);
+
+		/*
+		 * This lock is here just to satisfy pmd_alloc and pte_lock
+		 */
+		spin_lock(&mm->page_table_lock);
+
+		/*
+		 * On ARM, first page must always be allocated since it
+		 * contains the machine vectors.
+		 */
+		new_pmd = pmd_alloc(mm, new_pgd, 0);
+		if (!new_pmd)
+			goto no_pmd;
+
+		new_pte = pte_alloc(mm, new_pmd, 0);
+		if (!new_pte)
+			goto no_pte;
+
+		set_pte(new_pte, *init_pte);
+
+		spin_unlock(&mm->page_table_lock);
+	}
+
+	/*
+	 * Copy over the kernel and IO PGD entries
+	 */
+	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
+		       (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
+
+	/*
+	 * FIXME: this should not be necessary
+	 */
+	clean_cache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
+
+	return new_pgd;
+
+no_pte:
+	spin_unlock(&mm->page_table_lock);
+	pmd_free(new_pmd);
+	free_pages((unsigned long)new_pgd, 2);
+	return NULL;
+
+no_pmd:
+	spin_unlock(&mm->page_table_lock);
+	free_pages((unsigned long)new_pgd, 2);
+	return NULL;
+
+no_pgd:
+	return NULL;
+#else
+	return NULL;
+#endif
+
+}
+
 void free_pgd_slow(pgd_t *pgd)
 {
-	if (pgd) { /* can pgd be NULL? */
-		pmd_t *pmd;
-		pte_t *pte;
-
-		/* pgd is always present and good */
-		pmd = (pmd_t *)pgd;
-		if (pmd_none(*pmd))
-			goto free;
-		if (pmd_bad(*pmd)) {
-			pmd_ERROR(*pmd);
-			pmd_clear(pmd);
-			goto free;
-		}
+#ifndef CONFIG_UCLINUX
+	pmd_t *pmd;
+	pte_t *pte;
+
+	if (!pgd)
+		return;
 
-		pte = pte_offset(pmd, 0);
+	/* pgd is always present and good */
+	pmd = (pmd_t *)pgd;
+	if (pmd_none(*pmd))
+		goto free;
+	if (pmd_bad(*pmd)) {
+		pmd_ERROR(*pmd);
 		pmd_clear(pmd);
-		pte_free(pte);
-		pmd_free(pmd);
+		goto free;
 	}
+
+	pte = pte_offset(pmd, 0);
+	pmd_clear(pmd);
+	pte_free(pte);
+	pmd_free(pmd);
 free:
 	free_pages((unsigned long) pgd, 2);
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
 }
 
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
+/*
+ * Create a SECTION PGD between VIRT and PHYS in domain
+ * DOMAIN with protection PROT
+ */
+static inline void
+alloc_init_section(unsigned long virt, unsigned long phys, int prot)
 {
-	pte_t *pte;
+#ifndef CONFIG_UCLINUX
+	pmd_t pmd;
 
-	pte = (pte_t *)get_page_2k(GFP_KERNEL);
-	if (pmd_none(*pmd)) {
-		if (pte) {
-			memzero(pte, 2 * PTRS_PER_PTE * sizeof(pte_t));
-			clean_cache_area(pte, PTRS_PER_PTE * sizeof(pte_t));
-			pte += PTRS_PER_PTE;
-			set_pmd(pmd, mk_user_pmd(pte));
-			return pte + offset;
-		}
-		set_pmd(pmd, mk_user_pmd(get_bad_pte_table()));
-		return NULL;
-	}
-	free_page_2k((unsigned long)pte);
-	if (pmd_bad(*pmd)) {
-		__handle_bad_pmd(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + offset;
+	pmd_val(pmd) = phys | prot;
+
+	set_pmd(pmd_offset(pgd_offset_k(virt), virt), pmd);
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
 }
 
-pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
+/*
+ * Add a PAGE mapping between VIRT and PHYS in domain
+ * DOMAIN with protection PROT.  Note that due to the
+ * way we map the PTEs, we must allocate two PTE_SIZE'd
+ * blocks - one for the Linux pte table, and one for
+ * the hardware pte table.
+ */
+static inline void
+alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot)
 {
-	pte_t *pte;
+#ifndef CONFIG_UCLINUX
+	pmd_t *pmdp;
+	pte_t *ptep;
 
-	pte = (pte_t *)get_page_2k(GFP_KERNEL);
-	if (pmd_none(*pmd)) {
-		if (pte) {
-			memzero(pte, 2 * PTRS_PER_PTE * sizeof(pte_t));
-			clean_cache_area(pte, PTRS_PER_PTE * sizeof(pte_t));
-			pte += PTRS_PER_PTE;
-			set_pmd(pmd, mk_kernel_pmd(pte));
-			return pte + offset;
-		}
-		set_pmd(pmd, mk_kernel_pmd(get_bad_pte_table()));
-		return NULL;
-	}
-	free_page_2k((unsigned long)pte);
-	if (pmd_bad(*pmd)) {
-		__handle_bad_pmd_kernel(pmd);
-		return NULL;
+	pmdp = pmd_offset(pgd_offset_k(virt), virt);
+
+	if (pmd_none(*pmdp)) {
+		pte_t *ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
+						      sizeof(pte_t));
+
+		ptep += PTRS_PER_PTE;
+
+		set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain)));
 	}
-	return (pte_t *) pmd_page(*pmd) + offset;
+	ptep = pte_offset(pmdp, virt);
+
+	set_pte(ptep, mk_pte_phys(phys, __pgprot(prot)));
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
 }
 
-void free_pte_slow(pte_t *pte)
+/*
+ * Clear any PGD mapping.  On a two-level page table system,
+ * the clearance is done by the middle-level functions (pmd)
+ * rather than the top-level (pgd) functions.
+ */
+static inline void clear_mapping(unsigned long virt)
 {
-	free_page_2k((unsigned long)(pte - PTRS_PER_PTE));
+#ifndef CONFIG_UCLINUX
+	pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
 }
 
+/*
+ * Create the page directory entries and any necessary
+ * page tables for the mapping specified by `md'.  We
+ * are able to cope here with varying sizes and address
+ * offsets, and we take full advantage of sections.
+ */
+static void __init create_mapping(struct map_desc *md)
+{
+#ifndef CONFIG_UCLINUX
+	unsigned long virt, length;
+	int prot_sect, prot_pte;
+	long off;
+
+	prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+		   (md->prot_read  ? L_PTE_USER       : 0) |
+		   (md->prot_write ? L_PTE_WRITE      : 0) |
+		   (md->cacheable  ? L_PTE_CACHEABLE  : 0) |
+		   (md->bufferable ? L_PTE_BUFFERABLE : 0);
+
+	prot_sect = PMD_TYPE_SECT | PMD_DOMAIN(md->domain) |
+		    (md->prot_read  ? PMD_SECT_AP_READ    : 0) |
+		    (md->prot_write ? PMD_SECT_AP_WRITE   : 0) |
+		    (md->cacheable  ? PMD_SECT_CACHEABLE  : 0) |
+		    (md->bufferable ? PMD_SECT_BUFFERABLE : 0);
+
+	virt   = md->virtual;
+	off    = md->physical - virt;
+	length = md->length;
+
+	while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) {
+		alloc_init_page(virt, virt + off, md->domain, prot_pte);
+
+		virt   += PAGE_SIZE;
+		length -= PAGE_SIZE;
+	}
+
+	while (length >= PGDIR_SIZE) {
+		alloc_init_section(virt, virt + off, prot_sect);
 
+		virt   += PGDIR_SIZE;
+		length -= PGDIR_SIZE;
+	}
+
+	while (length >= PAGE_SIZE) {
+		alloc_init_page(virt, virt + off, md->domain, prot_pte);
+
+		virt   += PAGE_SIZE;
+		length -= PAGE_SIZE;
+	}
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
+}
+
+/*
+ * In order to soft-boot, we need to insert a 1:1 mapping in place of
+ * the user-mode pages.  This will then ensure that we have predictable
+ * results when turning the mmu off
+ */
 void setup_mm_for_reboot(char mode)
 {
+#ifndef CONFIG_UCLINUX
+	pgd_t *pgd;
+	pmd_t pmd;
+	int i;
+
+	if (current->mm && current->mm->pgd)
+		pgd = current->mm->pgd;
+	else
+		pgd = init_mm.pgd;
+
+	for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++) {
+		pmd_val(pmd) = (i << PGDIR_SHIFT) |
+			PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
+			PMD_TYPE_SECT;
+		set_pmd(pmd_offset(pgd + i, i << PGDIR_SHIFT), pmd);
+	}
+#else
+	printk("%s %i\n",__FILE__,__LINE__);
+#endif
+}
+
 /*
- * No MMU? Nothing to do.
- * --gmcnutt
+ * Setup initial mappings.  We use the page we allocated for zero page to hold
+ * the mappings, which will get overwritten by the vectors in traps_init().
+ * The mappings must be in virtual address order.
  */
+void __init memtable_init(struct meminfo *mi)
+{
+	struct map_desc *init_maps, *p, *q;
+	unsigned long address = 0;
+	int i;
+
+	init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
+
+	for (i = 0; i < mi->nr_banks; i++) {
+		if (mi->bank[i].size == 0)
+			continue;
+
+		p->physical   = mi->bank[i].start;
+		p->virtual    = __phys_to_virt(p->physical);
+		p->length     = mi->bank[i].size;
+		p->domain     = DOMAIN_KERNEL;
+		p->prot_read  = 0;
+		p->prot_write = 1;
+		p->cacheable  = 1;
+		p->bufferable = 1;
+
+		p ++;
+	}
+
+#ifdef FLUSH_BASE
+	p->physical   = FLUSH_BASE_PHYS;
+	p->virtual    = FLUSH_BASE;
+	p->length     = PGDIR_SIZE;
+	p->domain     = DOMAIN_KERNEL;
+	p->prot_read  = 1;
+	p->prot_write = 0;
+	p->cacheable  = 1;
+	p->bufferable = 1;
+
+	p ++;
+#endif
+
+#ifdef FLUSH_BASE_MINICACHE
+	p->physical   = FLUSH_BASE_PHYS + PGDIR_SIZE;
+	p->virtual    = FLUSH_BASE_MINICACHE;
+	p->length     = PGDIR_SIZE;
+	p->domain     = DOMAIN_KERNEL;
+	p->prot_read  = 1;
+	p->prot_write = 0;
+	p->cacheable  = 1;
+	p->bufferable = 0;
+
+	p ++;
+#endif
+
+	/*
+	 * Go through the initial mappings, but clear out any
+	 * pgdir entries that are not in the description.
+	 */
+	q = init_maps;
+	do {
+		if (address < q->virtual || q == p) {
+			clear_mapping(address);
+			address += PGDIR_SIZE;
+		} else {
+			create_mapping(q);
+
+			address = q->virtual + q->length;
+			address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
+
+			q ++;
+		}
+	} while (address != 0);
+
+	/*
+	 * Create a mapping for the machine vectors at virtual address 0
+	 * or 0xffff0000.  We should always try the high mapping.
+	 */
+	init_maps->physical   = virt_to_phys(init_maps);
+#ifndef CONFIG_UCLINUX
+	init_maps->virtual    = vectors_base();
+#endif
+	init_maps->length     = PAGE_SIZE;
+	init_maps->domain     = DOMAIN_USER;
+	init_maps->prot_read  = 0;
+	init_maps->prot_write = 0;
+	init_maps->cacheable  = 1;
+	init_maps->bufferable = 0;
+
+	create_mapping(init_maps);
+
+	flush_cache_all();
+}
+
+/*
+ * Create the architecture specific mappings
+ */
+void __init iotable_init(struct map_desc *io_desc)
+{
+	int i;
+
+	for (i = 0; io_desc[i].last == 0; i++)
+		create_mapping(io_desc + i);
 }
 
 static inline void free_memmap(int node, unsigned long start, unsigned long end)
@@ -211,3 +476,48 @@
 	for (node = 0; node < numnodes; node++)
 		free_unused_memmap_node(node, mi);
 }
+
+/*
+ * PTE table allocation cache.
+ *
+ * This is a move away from our custom 2K page allocator.  We now use the
+ * slab cache to keep track of these objects.
+ *
+ * With this, it is questionable as to whether the PGT cache gains us
+ * anything.  We may be better off dropping the PTE stuff from our PGT
+ * cache implementation.
+ */
+#ifndef CONFIG_UCLINUX
+kmem_cache_t *pte_cache;
+
+/*
+ * The constructor gets called for each object within the cache when the
+ * cache page is created.  Note that if slab tries to misalign the blocks,
+ * we BUG() loudly.
+ */
+static void pte_cache_ctor(void *pte, kmem_cache_t *cache, unsigned long flags)
+{
+	unsigned long block = (unsigned long)pte;
+
+	if (block & 2047)
+		BUG();
+
+	memzero(pte, 2 * PTRS_PER_PTE * sizeof(pte_t));
+	cpu_cache_clean_invalidate_range(block, block +
+			PTRS_PER_PTE * sizeof(pte_t), 0);
+}
+
+
+void __init pgtable_cache_init(void)
+{
+	pte_cache = kmem_cache_create("pte-cache",
+				2 * PTRS_PER_PTE * sizeof(pte_t), 0, 0,
+				pte_cache_ctor, NULL);
+	if (!pte_cache)
+		BUG();
+}
+#else
+void __init pgtable_cache_init(void)
+{
+}
+#endif
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/tools/getconstants.c linux-2.4.6.uc0pre0.actiontec/arch/armnommu/tools/getconstants.c
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/tools/getconstants.c	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/tools/getconstants.c	2004-12-06 19:35:49.000000000 +0100
@@ -14,14 +14,8 @@
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 
-/*
- * Make sure that the compiler and target are compatible
- */
-#if (defined(__APCS_32__) && defined(CONFIG_CPU_26))
-#error Your compiler targets APCS-32 but this kernel requires APCS-26.
-#endif
-#if (defined(__APCS_26__) && defined(CONFIG_CPU_32))
-#error Your compiler targets APCS-26 but this kernel requires APCS-32.
+#ifndef __APCS_32__
+#error APCS-32 required
 #endif
 
 #define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
@@ -66,7 +60,5 @@
 
 DEFN("PAGE_SZ",			PAGE_SIZE);
 
-DEFN("KSWI_BASE",		0x900000);
-DEFN("KSWI_SYS_BASE",		0x9f0000);
 DEFN("SYS_ERROR0",		0x9f0000);
 }
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/tools/mach-types linux-2.4.6.uc0pre0.actiontec/arch/armnommu/tools/mach-types
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/tools/mach-types	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/tools/mach-types	2004-12-06 19:35:49.000000000 +0100
@@ -1,69 +1,365 @@
-# Database of machine macros and numbers
+#
+# This file is linux/arch/arm/tools/mach-types
 #
 # Please do not send patches to this file; it is automatically generated!
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Fri Jan 19 10:49:57 2001
+# Last update: Tue Jul 29 14:17:26 2003
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
 ebsa110			ARCH_EBSA110		EBSA110			0
-riscpc			ARCH_RPC		RISCPC			1
+riscpc			ARCH_RPC			RISCPC			1
 nexuspci		ARCH_NEXUSPCI		NEXUSPCI		3
 ebsa285			ARCH_EBSA285		EBSA285			4
 netwinder		ARCH_NETWINDER		NETWINDER		5
-cats			ARCH_CATS		CATS			6
-tbox			ARCH_TBOX		TBOX			7
-co285			ARCH_CO285		CO285			8
+cats			ARCH_CATS			CATS			6
+tbox			ARCH_TBOX			TBOX			7
+co285			ARCH_CO285			CO285			8
 clps7110		ARCH_CLPS7110		CLPS7110		9
-archimedes		ARCH_ARC		ARCHIMEDES		10
-a5k			ARCH_A5K		A5K			11
-etoile			ARCH_ETOILE		ETOILE			12
+archimedes		ARCH_ARC			ARCHIMEDES		10
+a5k				ARCH_A5K			A5K				11
+etoile			ARCH_ETOILE			ETOILE			12
 lacie_nas		ARCH_LACIE_NAS		LACIE_NAS		13
 clps7500		ARCH_CLPS7500		CLPS7500		14
-shark			ARCH_SHARK		SHARK			15
+shark			ARCH_SHARK			SHARK			15
 brutus			SA1100_BRUTUS		BRUTUS			16
 personal_server		ARCH_PERSONAL_SERVER	PERSONAL_SERVER		17
-itsy			SA1100_ITSY		ITSY			18
-l7200			ARCH_L7200		L7200			19
-pleb			SA1100_PLEB		PLEB			20
+itsy			SA1100_ITSY			ITSY			18
+l7200			ARCH_L7200			L7200			19
+pleb			SA1100_PLEB			PLEB			20
 integrator		ARCH_INTEGRATOR		INTEGRATOR		21
-bitsy			SA1100_BITSY		BITSY			22
+h3600			SA1100_H3600		H3600			22
 ixp1200			ARCH_IXP1200		IXP1200			23
-p720t			ARCH_P720T		P720T			24
+p720t			ARCH_P720T			P720T			24
 assabet			SA1100_ASSABET		ASSABET			25
 victor			SA1100_VICTOR		VICTOR			26
-lart			SA1100_LART		LART			27
-ranger			ARCH_RANGER		RANGER			28
-graphicsclient		SA1100_GRAPHICSCLIENT	GRAPHICSCLIENT		29
+lart			SA1100_LART			LART			27
+ranger			SA1100_RANGER		RANGER			28
+graphicsclient	SA1100_GRAPHICSCLIENT	GRAPHICSCLIENT		29
 xp860			SA1100_XP860		XP860			30
-cerf			SA1100_CERF		CERF			31
+cerf			SA1100_CERF			CERF			31
 nanoengine		SA1100_NANOENGINE	NANOENGINE		32
-fpic			SA1100_FPIC		FPIC			33
+fpic			SA1100_FPIC			FPIC			33
 extenex1		SA1100_EXTENEX1		EXTENEX1		34
 sherman			SA1100_SHERMAN		SHERMAN			35
 accelent_sa		SA1100_ACCELENT		ACCELENT_SA		36
-accelent_l7200		ARCH_L7200_ACCELENT	ACCELENT_L7200		37
+accelent_l7200	ARCH_L7200_ACCELENT	ACCELENT_L7200	37
 netport			SA1100_NETPORT		NETPORT			38
 pangolin		SA1100_PANGOLIN		PANGOLIN		39
-yopy			SA1100_YOPY		YOPY			40
-coolidge		SA1100_COOLIDGE		coolidge		41
-huw_webpanel		SA1100_HUW_WEBPANEL	HUW_WEBPANEL		42
-spotme			ARCH_SPOTME		SPOTME			43
+yopy			SA1100_YOPY			YOPY			40
+coolidge		SA1100_COOLIDGE		COOLIDGE		41
+huw_webpanel	SA1100_HUW_WEBPANEL	HUW_WEBPANEL	42
+spotme			ARCH_SPOTME			SPOTME			43
 freebird		ARCH_FREEBIRD		FREEBIRD		44
-ti925			ARCH_TI925		TI925			45
+ti925			ARCH_TI925			TI925			45
 riscstation		ARCH_RISCSTATION	RISCSTATION		46
-cavy			SA1100_CAVY		CAVY			47
+cavy			SA1100_CAVY			CAVY			47
 jornada720		SA1100_JORNADA720	JORNADA720		48
 omnimeter		SA1100_OMNIMETER	OMNIMETER		49
 edb7211			ARCH_EDB7211		EDB7211			50
 citygo			SA1100_CITYGO		CITYGO			51
 pfs168			SA1100_PFS168		PFS168			52
-spot			SA1100_SPOT		SPOT			53
-flexanet		ARCH_FLEXANET		FLEXANET		54
-webpal			ARCH_WEBPAL		WEBPAL			55
-dsc21                   ARCH_DSC21              DSC21                   56
-
-# The following are unallocated
-empeg			SA1100_EMPEG		EMPEG
+spot			SA1100_SPOT			SPOT			53
+flexanet		SA1100_FLEXANET		FLEXANET		54
+webpal			ARCH_WEBPAL			WEBPAL			55
+linpda			SA1100_LINPDA		LINPDA			56
+anakin			ARCH_ANAKIN			ANAKIN			57
+mvi				SA1100_MVI			MVI				58
+jupiter			SA1100_JUPITER		JUPITER			59
+psionw			ARCH_PSIONW			PSIONW			60
+aln				SA1100_ALN			ALN				61
+epxa			ARCH_CAMELOT		CAMELOT			62
+gds2200			SA1100_GDS2200		GDS2200			63
+psion_series7	SA1100_PSION_SERIES7	PSION_SERIES7		64
+xfile			SA1100_XFILE		XFILE			65
+accelent_ep9312	ARCH_ACCELENT_EP9312	ACCELENT_EP9312		66
+ic200			ARCH_IC200			IC200			67
+creditlart		SA1100_CREDITLART	CREDITLART		68
+htm				SA1100_HTM			HTM				69
+iq80310			ARCH_IQ80310		IQ80310			70
+freebot			SA1100_FREEBOT		FREEBOT			71
+entel			ARCH_ENTEL			ENTEL			72
+enp3510			ARCH_ENP3510		ENP3510			73
+trizeps			SA1100_TRIZEPS		TRIZEPS			74
+nesa			SA1100_NESA			NESA			75
+venus			ARCH_VENUS			VENUS			76
+tardis			ARCH_TARDIS			TARDIS			77
+mercury			ARCH_MERCURY		MERCURY			78
+empeg			SA1100_EMPEG		EMPEG			79
+adi_evb			ARCH_I80200FCC		I80200FCC		80
+itt_cpb			SA1100_ITT_CPB		ITT_CPB			81
+svc				SA1100_SVC			SVC				82
+alpha2			SA1100_ALPHA2		ALPHA2			84
+alpha1			SA1100_ALPHA1		ALPHA1			85
+netarm			ARCH_NETARM			NETARM			86
+simpad			SA1100_SIMPAD		SIMPAD			87
+pda1			ARCH_PDA1			PDA1			88
+lubbock			ARCH_LUBBOCK		LUBBOCK			89
+aniko			ARCH_ANIKO			ANIKO			90
+clep7212		ARCH_CLEP7212		CLEP7212		91
+cs89712			ARCH_CS89712		CS89712			92
+weararm			SA1100_WEARARM		WEARARM			93
+possio_px		SA1100_POSSIO_PX	POSSIO_PX		94
+sidearm			SA1100_SIDEARM		SIDEARM			95
+stork			SA1100_STORK		STORK			96
+shannon			SA1100_SHANNON		SHANNON			97
+ace				ARCH_ACE			ACE				98
+ballyarm		SA1100_BALLYARM		BALLYARM		99
+simputer		SA1100_SIMPUTER		SIMPUTER		100
+nexterm			SA1100_NEXTERM		NEXTERM			101
+sa1100_elf		SA1100_SA1100_ELF	SA1100_ELF		102
+gator			SA1100_GATOR		GATOR			103
+granite			ARCH_GRANITE		GRANITE			104
+consus			SA1100_CONSUS		CONSUS			105
+aaed2000		ARCH_AAED2000		AAED2000		106
+cdb89712		ARCH_CDB89712		CDB89712		107
+graphicsmaster	SA1100_GRAPHICSMASTER	GRAPHICSMASTER		108
+adsbitsy		SA1100_ADSBITSY		ADSBITSY		109
+pxa_idp			ARCH_PXA_IDP		PXA_IDP			110
+plce			ARCH_PLCE			PLCE			111
+pt_system3		SA1100_PT_SYSTEM3	PT_SYSTEM3		112
+murphy			ARCH_MEDALB			MEDALB			113
+eagle			ARCH_EAGLE			EAGLE			114
+dsc21			ARCH_DSC21			DSC21			115
+dsc24			ARCH_DSC24			DSC24			116
+ti5472			ARCH_TI5472			TI5472			117
+autcpu12		ARCH_AUTCPU12		AUTCPU12		118
+uengine			ARCH_UENGINE		UENGINE			119
+bluestem		SA1100_BLUESTEM		BLUESTEM		120
+xingu8			ARCH_XINGU8			XINGU8			121
+bushstb			ARCH_BUSHSTB		BUSHSTB			122
+epsilon1		SA1100_EPSILON1		EPSILON1		123
+balloon			SA1100_BALLOON		BALLOON			124
+puppy			ARCH_PUPPY			PUPPY			125
+elroy			SA1100_ELROY		ELROY			126
+gms720			ARCH_GMS720			GMS720			127
+s24x			ARCH_S24X			S24X			128
+jtel_clep7312	ARCH_JTEL_CLEP7312	JTEL_CLEP7312	129
+cx821xx			ARCH_CX821XX		CX821XX			130
+edb7312			ARCH_EDB7312		EDB7312			131
+bsa1110			SA1100_BSA1110		BSA1110			132
+powerpin		ARCH_POWERPIN		POWERPIN		133
+openarm			ARCH_OPENARM		OPENARM			134
+whitechapel		SA1100_WHITECHAPEL	WHITECHAPEL		135
+h3100			SA1100_H3100		H3100			136
+h3800			SA1100_H3800		H3800			137
+blue_v1			ARCH_BLUE_V1		BLUE_V1			138
+pxa_cerf		ARCH_PXA_CERF		PXA_CERF		139
+arm7tevb		ARCH_ARM7TEVB		ARM7TEVB		140
+d7400			SA1100_D7400		D7400			141
+piranha			ARCH_PIRANHA		PIRANHA			142
+sbcamelot		SA1100_SBCAMELOT	SBCAMELOT		143
+kings			SA1100_KINGS		KINGS			144
+smdk2400		ARCH_SMDK2400		SMDK2400		145
+collie			SA1100_COLLIE		COLLIE			146
+idr				ARCH_IDR			IDR				47
+badge4			SA1100_BADGE4		BADGE4			148
+webnet			ARCH_WEBNET			WEBNET			149
+d7300			SA1100_D7300		D7300			150
+cep				SA1100_CEP			CEP				151
+fortunet		ARCH_FORTUNET		FORTUNET		152
+vc547x			ARCH_VC547X			VC547X			153
+filewalker		SA1100_FILEWALKER	FILEWALKER		154
+netgateway		SA1100_NETGATEWAY	NETGATEWAY		155
+symbol2800		SA1100_SYMBOL2800	SYMBOL2800		156
+suns			SA1100_SUNS			SUNS			157
+frodo			SA1100_FRODO		FRODO			158
+ms301			SA1100_MACH_TYTE_MS301	MACH_TYTE_MS301		159
+mx1ads			ARCH_MX1ADS			MX1ADS			160
+h7201			ARCH_H7201			H7201			161
+h7202			ARCH_H7202			H7202			162
+amico			ARCH_AMICO			AMICO			163
+iam				SA1100_IAM			IAM				164
+tt530			SA1100_TT530		TT530			165
+sam2400			ARCH_SAM2400		SAM2400			166
+jornada56x		SA1100_JORNADA56X	JORNADA56X		167
+active			SA1100_ACTIVE		ACTIVE			168
+iq80321			ARCH_IQ80321		IQ80321			169
+wid				SA1100_WID			WID				170
+sabinal			ARCH_SABINAL		SABINAL			171
+ixp425_matacumbe	ARCH_IXP425_MATACUMBE	IXP425_MATACUMBE	172
+miniprint		SA1100_MINIPRINT	MINIPRINT		173
+adm510x			ARCH_ADM510X		ADM510X			174
+svs200			SA1100_SVS200		SVS200			175
+atg_tcu			ARCH_ATG_TCU		ATG_TCU			176
+jornada820		SA1100_JORNADA820	JORNADA820		177
+s3c44b0			ARCH_S3C44B0		S3C44B0			178
+margis2			ARCH_MARGIS2		MARGIS2			179
+ks8695			ARCH_KS8695			KS8695			180
+brh				ARCH_BRH			BRH				181
+s3c2410			ARCH_S3C2410		S3C2410			182
+possio_px30		ARCH_POSSIO_PX30	POSSIO_PX30		183
+s3c2800			ARCH_S3C2800		S3C2800			184
+fleetwood		SA1100_FLEETWOOD	FLEETWOOD		185
+omaha			ARCH_OMAHA			OMAHA			186
+ta7				ARCH_TA7			TA7				187
+nova			SA1100_NOVA			NOVA			188
+hmk				ARCH_HMK			HMK				189
+karo			ARCH_KARO			KARO			190
+fester			SA1100_FESTER		FESTER			191
+gpi				ARCH_GPI			GPI				192
+smdk2410		ARCH_SMDK2410		SMDK2410		193
+premium			ARCH_PREMIUM		PREMIUM			194
+nexio			SA1100_NEXIO		NEXIO			195
+bitbox			SA1100_BITBOX		BITBOX			196
+g200			SA1100_G200			G200			197
+gill			SA1100_GILL			GILL			198
+pxa_mercury		ARCH_PXA_MERCURY	PXA_MERCURY		199
+ceiva			ARCH_CEIVA			CEIVA			200
+fret			SA1100_FRET			FRET			201
+emailphone		SA1100_EMAILPHONE	EMAILPHONE		202
+h3900			ARCH_H3900			H3900			203
+pxa1			ARCH_PXA1			PXA1			204
+koan369			SA1100_KOAN369		KOAN369			205
+cogent			ARCH_COGENT			COGENT			206
+esl_simputer		ARCH_ESL_SIMPUTER	ESL_SIMPUTER		207
+esl_simputer_clr	ARCH_ESL_SIMPUTER_CLR	ESL_SIMPUTER_CLR	208
+esl_simputer_bw		ARCH_ESL_SIMPUTER_BW	ESL_SIMPUTER_BW		209
+hhp_cradle		ARCH_HHP_CRADLE		HHP_CRADLE		210
+he500			ARCH_HE500			HE500			211
+inhandelf2		SA1100_INHANDELF2	INHANDELF2		212
+inhandftip		SA1100_INHANDFTIP	INHANDFTIP		213
+dnp1110			SA1100_DNP1110		DNP1110			214
+pnp1110			SA1100_PNP1110		PNP1110			215
+csb226			ARCH_CSB226			CSB226			216
+arnold			SA1100_ARNOLD		ARNOLD			217
+psiboard		SA1100_PSIBOARD		PSIBOARD		218
+jz8028			ARCH_JZ8028			JZ8028			219
+h5400			ARCH_IPAQ3			IPAQ3			220
+forte			SA1100_FORTE		FORTE			221
+acam			SA1100_ACAM			ACAM			222
+abox			SA1100_ABOX			ABOX			223
+atmel			ARCH_ATMEL			ATMEL			224
+sitsang			ARCH_SITSANG		SITSANG			225
+cpu1110lcdnet	SA1100_CPU1110LCDNET	CPU1110LCDNET		226
+mpl_vcma9		ARCH_MPL_VCMA9		MPL_VCMA9		227
+opus_a1			ARCH_OPUS_A1		OPUS_A1			228
+daytona			ARCH_DAYTONA		DAYTONA			229
+killbear		SA1100_KILLBEAR		KILLBEAR		230
+yoho			ARCH_YOHO			YOHO			231
+jasper			ARCH_JASPER			JASPER			232
+dsc25			ARCH_DSC25			DSC25			233
+innovator		ARCH_INNOVATOR		INNOVATOR		234
+ramses			ARCH_RAMSES			RAMSES			235
+s28x			ARCH_S28X			S28X			236
+mport3			ARCH_MPORT3			MPORT3			237
+pxa_eagle250	ARCH_PXA_EAGLE250	PXA_EAGLE250	238
+pdb				ARCH_PDB			PDB				239
+blue_2g			SA1100_BLUE_2G		BLUE_2G			240
+bluearch		SA1100_BLUEARCH		BLUEARCH		241
+ixdp2400		ARCH_IXMB2400		IXMB2400		242
+ixdp2800		ARCH_IXMB2800		IXMB2800		243
+explorer		SA1100_EXPLORER		EXPLORER		244
+ixdp425			ARCH_IXDP425		IXDP425			245
+chimp			ARCH_CHIMP			CHIMP			246
+stork_nest		ARCH_STORK_NEST		STORK_NEST		247
+stork_egg		ARCH_STORK_EGG		STORK_EGG		248
+wismo			SA1100_WISMO		WISMO			249
+ezlinx			ARCH_EZLINX			EZLINX			250
+at91rm9200		ARCH_AT91			AT91			251
+orion			ARCH_ORION			ORION			252
+neptune			ARCH_NEPTUNE		NEPTUNE			253
+hackkit			SA1100_HACKKIT		HACKKIT			254
+pxa_wins30		ARCH_PXA_WINS30		PXA_WINS30		255
+lavinna			SA1100_LAVINNA		LAVINNA			256
+pxa_uengine		ARCH_PXA_UENGINE	PXA_UENGINE		257
+innokom			ARCH_INNOKOM		INNOKOM			258
+bms				ARCH_BMS			BMS				259
+ixcdp1100		ARCH_IXCDP1100		IXCDP1100		260
+prpmc1100		ARCH_PRPMC1100		PRPMC1100		261
+at91rm9200dk	ARCH_AT91RM9200DK	AT91RM9200DK	262
+armstick		ARCH_ARMSTICK		ARMSTICK		263
+armonie			ARCH_ARMONIE		ARMONIE			264
+mport1			ARCH_MPORT1			MPORT1			265
+s3c5410			ARCH_S3C5410		S3C5410			266
+zcp320a			ARCH_ZCP320A		ZCP320A			267
+i_box			ARCH_I_BOX			I_BOX			268
+stlc1502		ARCH_STLC1502		STLC1502		269
+siren			ARCH_SIREN			SIREN			270
+greenlake		ARCH_GREENLAKE		GREENLAKE		271
+argus			ARCH_ARGUS			ARGUS			272
+combadge		SA1100_COMBADGE		COMBADGE		273
+rokepxa			ARCH_ROKEPXA		ROKEPXA			274
+cintegrator		ARCH_CINTEGRATOR	CINTEGRATOR		275
+guidea07		ARCH_GUIDEA07		GUIDEA07		276
+tat257			ARCH_TAT257			TAT257			277
+igp2425			ARCH_IGP2425		IGP2425			278
+bluegrama		ARCH_BLUEGRAMMA		BLUEGRAMMA		279
+ipod			ARCH_IPOD			IPOD			280
+adsbitsyx		ARCH_ADSBITSYX		ADSBITSYX		281
+trizeps2		ARCH_TRIZEPS2		TRIZEPS2		282
+viper			ARCH_VIPER			VIPER			283
+adsbitsyplus	SA1100_ADSBITSYPLUS	ADSBITSYPLUS	284
+adsagc			SA1100_ADSAGC		ADSAGC			285
+stp7312			ARCH_STP7312		STP7312			286
+nx_phnx			ARCH_PXA255			PXA255			287
+wep_ep250		ARCH_WEP_EP250		WEP_EP250		288
+inhandelf3		ARCH_INHANDELF3		INHANDELF3		289
+adi_coyote		ARCH_ADI_COYOTE		ADI_COYOTE		290
+iyonix			ARCH_IYONIX			IYONIX			291
+damicam1		ARCH_DAMICAM_SA1110	DAMICAM_SA1110	292
+meg03			ARCH_MEG03			MEG03			293
+pxa_whitechapel	ARCH_PXA_WHITECHAPEL	PXA_WHITECHAPEL		294
+nwsc			ARCH_NWSC			NWSC			295
+nwlarm			ARCH_NWLARM			NWLARM			296
+ixp425_mguard	ARCH_IXP425_MGUARD	IXP425_MGUARD	297
+pxa_netdcu4		ARCH_PXA_NETDCU4	PXA_NETDCU4		298
+ixdp2401		ARCH_IXDP2401		IXDP2401		299
+ixdp2801		ARCH_IXDP2801		IXDP2801		300
+zodiac			ARCH_ZODIAC			ZODIAC			301
+armmodul		ARCH_ARMMODUL		ARMMODUL		302
+ketop			SA1100_KETOP		KETOP			303
+av7200			ARCH_AV7200			AV7200			304
+arch_ti925		ARCH_ARCH_TI925		ARCH_TI925		305
+acq200			ARCH_ACQ200			ACQ200			306
+pt_dafit		SA1100_PT_DAFIT		PT_DAFIT		307
+ihba			ARCH_IHBA			IHBA			308
+quinque			ARCH_QUINQUE		QUINQUE			309
+nimbraone		ARCH_NIMBRAONE		NIMBRAONE		310
+nimbra29x		ARCH_NIMBRA29X		NIMBRA29X		311
+nimbra210		ARCH_NIMBRA210		NIMBRA210		312
+hhp_d95xx		ARCH_HHP_D95XX		HHP_D95XX		313
+labarm			ARCH_LABARM			LABARM			314
+m825xx			ARCH_M825XX			M825XX			315
+m7100			SA1100_M7100		M7100			316
+nipc2			ARCH_NIPC2			NIPC2			317
+fu7202			ARCH_FU7202			FU7202			318
+adsagx			ARCH_ADSAGX			ADSAGX			319
+pxa_pooh		ARCH_PXA_POOH		PXA_POOH		320
+bandon			ARCH_BANDON			BANDON			321
+pcm7210			ARCH_PCM7210		PCM7210			322
+nms9200			ARCH_NMS9200		NMS9200			323
+logodl			ARCH_LOGODL			LOGODL			324
+m7140			SA1100_M7140		M7140			325
+korebot			ARCH_KOREBOT		KOREBOT			326
+iq31244			ARCH_IQ31244		IQ31244			327
+koan393			SA1100_KOAN393		KOAN393			328
+inhandftip3		ARCH_INHANDFTIP3	INHANDFTIP3		329
+gonzo			ARCH_GONZO			GONZO			330
+bast			ARCH_BAST			BAST			331
+scanpass		ARCH_SCANPASS		SCANPASS		332
+ep7312_pooh		ARCH_EP7312_POOH	EP7312_POOH		333
+ta7s			ARCH_TA7S			TA7S			334
+ta7v			ARCH_TA7V			TA7V			335
+icarus			SA1100_ICARUS		ICARUS			336
+h1900			ARCH_H1900			H1900			337
+gemini			SA1100_GEMINI		GEMINI			338
+axim			ARCH_AXIM			AXIM			339
+audiotron		ARCH_AUDIOTRON		AUDIOTRON		340
+h2200			ARCH_H2200			H2200			341
+loox600			ARCH_LOOX600		LOOX600			342
+niop			ARCH_NIOP			NIOP			343
+dm310			ARCH_DM310			DM310			344
+seedpxa_c2		ARCH_SEEDPXA_C2		SEEDPXA_C2		345
+ixp4xx_mguardpci	ARCH_IXP4XX_MGUARD_PCI	IXP4XX_MGUARD_PCI	346
+h1940			ARCH_H1940			H1940			347
+scorpio			ARCH_SCORPIO		SCORPIO			348
+viva			ARCH_VIVA			VIVA			349
+pxa_xcard		ARCH_PXA_XCARD		PXA_XCARD		350
+csb335			ARCH_CSB335			CSB335			351
+ixrd425			ARCH_IXRD425		IXRD425			352
+iq80315			ARCH_IQ80315		IQ80315			353
+nmp7312			ARCH_NMP7312		NMP7312			354
+cx861xx			ARCH_CX861XX		CX861XX			355
diff -ur linux-2.4.6.uc0pre0.orig/arch/armnommu/vmlinux-armv.lds.in linux-2.4.6.uc0pre0.actiontec/arch/armnommu/vmlinux-armv.lds.in
--- linux-2.4.6.uc0pre0.orig/arch/armnommu/vmlinux-armv.lds.in	2004-12-06 19:34:58.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/arch/armnommu/vmlinux-armv.lds.in	2004-12-06 19:35:49.000000000 +0100
@@ -2,37 +2,14 @@
  * taken from the i386 version by Russell King
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  */
+ 
+INCLUDE arch/armnommu/mach-uClinkII/romfs.ld 
 OUTPUT_ARCH(arm)
 ENTRY(stext)
 SECTIONS
 {
-	. = TEXTADDR;
-	.text : {			/* Real text segment		*/
-		_text = .;		/* Text and read-only data	*/
-			*(.text)
-			*(.fixup)
-			*(.gnu.warning)
-			*(.text.lock)	/* out-of-line lock text */
-			*(.rodata)
-			*(.glue_7)
-			*(.glue_7t)
-			*(.kstrtab)
-		. = ALIGN(16);
-		__start___ex_table = .;	/* Exception table		*/
-			*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;	/* Kernel symbol table		*/
-			*(__ksymtab)
-		__stop___ksymtab = .;
-
-		*(.got)			/* Global offset table		*/
-
-		_etext = .;		/* End of text section		*/
-	}
-
-	. = ALIGN(4096);
 
+	. = TEXTADDR;
 	.init : {			/* Init code and data		*/
 		_stext = .;
 		__init_begin = .;
@@ -61,11 +38,38 @@
 		*(.exitcall.exit)
 	}
 
-	. = DATAADDR;
+	.text : {			/* Real text segment		*/
+		_text = .;		/* Text and read-only data	*/
+			*(.text)
+			*(.fixup)
+			*(.gnu.warning)
+			*(.text.lock)	/* out-of-line lock text */
+			*(.rodata)
+			*(.glue_7)
+			*(.glue_7t)
+			*(.kstrtab)
+		. = ALIGN(16);
+		__start___ex_table = .;	/* Exception table		*/
+			*(__ex_table)
+		__stop___ex_table = .;
 
+		__start___ksymtab = .;	/* Kernel symbol table		*/
+			*(__ksymtab)
+		__stop___ksymtab = .;
 
-	. = ALIGN(8192); /* Do I need this? --gmcnutt */
+		__start___kallsyms = .; /* All kernel symbols           */
+			*(__kallsyms)
+		__stop___kallsyms = .;
 
+		*(.got)			/* Global offset table		*/
+
+		_etext = .;		/* End of text section		*/
+	}
+
+	. = ALIGN(8192);
+
+	__data_start = .;
+	__data_rom_start = .;
 	.data : {
 		/*
 		 * first, the init task union, aligned
@@ -85,9 +89,17 @@
 		*(.data)
 		CONSTRUCTORS
 
+		. = ALIGN(32);	/* To be sure to align .fs . OZH */
 		_edata = .;
+		
 	}
 
+	.fs :	{
+		_romfs = ABSOLUTE (.);
+		. = . + romfs_size;
+		_end_romfs = ABSOLUTE (.);
+		}
+
 	.bss : {
 		__bss_start = .;	/* BSS				*/
 		*(.bss)
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/bitops.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/bitops.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/bitops.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/bitops.h	2004-12-06 19:35:49.000000000 +0100
@@ -24,12 +24,62 @@
  * Function prototypes to keep gcc -Wall happy.
  */
 extern void set_bit(int nr, volatile void * addr);
+
+static inline void __set_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7));
+}
+
 extern void clear_bit(int nr, volatile void * addr);
+
+static inline void __clear_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7));
+}
+
 extern void change_bit(int nr, volatile void * addr);
 
+static inline void __change_bit(int nr, volatile void *addr)
+{
+	((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7));
+}
+
 extern int test_and_set_bit(int nr, volatile void * addr);
+
+static inline int __test_and_set_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval | mask;
+	return oldval & mask;
+}
+
 extern int test_and_clear_bit(int nr, volatile void * addr);
+
+static inline int __test_and_clear_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval & ~mask;
+	return oldval & mask;
+}
+
 extern int test_and_change_bit(int nr, volatile void * addr);
+
+static inline int __test_and_change_bit(int nr, volatile void *addr)
+{
+	unsigned int mask = 1 << (nr & 7);
+	unsigned int oldval;
+
+	oldval = ((unsigned char *) addr)[nr >> 3];
+	((unsigned char *) addr)[nr >> 3] = oldval ^ mask;
+	return oldval & mask;
+}
+
 extern int find_first_zero_bit(void * addr, unsigned size);
 extern int find_next_zero_bit(void * addr, int size, int offset);
 
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/byteorder.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/byteorder.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/byteorder.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/byteorder.h	2004-12-06 19:35:49.000000000 +0100
@@ -8,7 +23,11 @@
 #  define __SWAB_64_THRU_32__
 #endif
 
+#ifdef __ARMEB__
+#include <linux/byteorder/big_endian.h>
+#else
 #include <linux/byteorder/little_endian.h>
+#endif
 
 #endif
 
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/cpu-multi32.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/cpu-multi32.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/cpu-multi32.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/cpu-multi32.h	2004-12-06 19:35:49.000000000 +0100
@@ -154,6 +154,6 @@
 #define cpu_set_pmd(pmdp, pmd)			processor.pgtable.set_pmd(pmdp, pmd)
 #define cpu_set_pte(ptep, pte)			processor.pgtable.set_pte(ptep, pte)
 
-#define cpu_switch_mm(pgd,tsk)			cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
+#define cpu_switch_mm(pgd,tsk)			cpu_set_pgd(__virt_to_phys(pgd))
 
 #endif
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/cpu-single.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/cpu-single.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/cpu-single.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/cpu-single.h	2004-12-06 19:35:49.000000000 +0100
@@ -84,6 +84,6 @@
 extern void cpu_set_pte(pte_t *ptep, pte_t pte);
 extern volatile void cpu_reset(unsigned long addr);
 
-#define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
+#define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys(pgd))
 
 #endif
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/elf.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/elf.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/elf.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/elf.h	2004-12-06 19:35:49.000000000 +0100
@@ -30,7 +30,7 @@
  */
 #define ELF_CLASS	ELFCLASS32
 #ifdef __ARMEB__
-#define ELF_DATA	ELFDATA2LSB;
+#define ELF_DATA	ELFDATA2MSB;
 #else
 #define ELF_DATA	ELFDATA2LSB;
 #endif
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/hardirq.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/hardirq.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/hardirq.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/hardirq.h	2004-12-06 19:35:49.000000000 +0100
@@ -4,10 +4,9 @@
 #include <linux/config.h>
 #include <linux/threads.h>
 
-/* entry.S is sensitive to the offsets of these fields */
+/* softirq.h is sensitive to the offsets of these fields */
 typedef struct {
-	unsigned int __softirq_active;
-	unsigned int __softirq_mask;
+	unsigned int __softirq_pending;
 	unsigned int __local_irq_count;
 	unsigned int __local_bh_count;
 	unsigned int __syscall_count;
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/io.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/io.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/io.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/io.h	2004-12-06 19:35:49.000000000 +0100
@@ -71,6 +71,15 @@
 extern void insw(unsigned int port, void *from, int len);
 extern void insl(unsigned int port, void *from, int len);
 
+extern void __raw_writesb(unsigned int addr, void *data, int bytelen);
+extern void __raw_writesw(unsigned int addr, void *data, int wordlen);
+extern void __raw_writesl(unsigned int addr, void *data, int longlen);
+
+extern void __raw_readsb(unsigned int addr, void *data, int bytelen);
+extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
+extern void __raw_readsl(unsigned int addr, void *data, int longlen);
+
+
 #define outsb_p(port,from,len)		outsb(port,from,len)
 #define outsw_p(port,from,len)		outsw(port,from,len)
 #define outsl_p(port,from,len)		outsl(port,from,len)
@@ -104,11 +113,13 @@
 		_ret = __ioremap(iomem_to_phys(_off),_size,0);	\
 	_ret;							\
  })
+
+#define __arch_iounmap __iounmap
 #endif
 
 #define ioremap(off,sz)			__arch_ioremap((off),(sz),0)
 #define ioremap_nocache(off,sz)		__arch_ioremap((off),(sz),1)
-#define iounmap(_addr)			__iounmap(_addr)
+#define iounmap(_addr)			__arch_iounmap(_addr)
 
 /*
  * DMA-consistent mapping functions.  These allocate/free a region of
@@ -117,7 +128,7 @@
  * is in pci.h
  */
 extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
-extern void consistent_free(void *vaddr);
+extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
 extern void consistent_sync(void *vaddr, size_t size, int rw);
 
 #define __raw_writeb(v,a)		__arch_putb(v,a)
@@ -188,7 +199,7 @@
 	return retval;
 }
 
-#else	/* __mem_pci */
+#elif !defined(readb)
 
 #define readb(addr)			(__readwrite_bug("readb"),0)
 #define readw(addr)			(__readwrite_bug("readw"),0)
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/ioctls.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/ioctls.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/ioctls.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/ioctls.h	2004-12-06 19:35:49.000000000 +0100
@@ -65,6 +65,7 @@
 
 #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/irq.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/irq.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/irq.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/irq.h	2004-12-06 19:35:49.000000000 +0100
@@ -8,7 +8,7 @@
 #endif
 
 #ifndef NR_IRQS
-#define NR_IRQS	128
+#define NR_IRQS	32
 #endif
 
 /*
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/memory.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/memory.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/memory.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/memory.h	2004-12-06 19:35:49.000000000 +0100
@@ -22,20 +22,20 @@
  * Virtual, bus and physical addresses are all the same when there's no MMU.
  * --gmcnutt
  */
-#define virt_to_bus(x) x
-#define bus_to_virt(x) x
-#define virt_to_phys(x) x
-#define phys_to_virt(x) x
+#define virt_to_bus(x) ((unsigned long) (x))
+#define bus_to_virt(x) ((void *) (x))
+#define virt_to_phys(x) ((unsigned long) (x))
+#define phys_to_virt(x) ((void *) (x))
 
 /*
  * For some reason other asm/.h files refer to these instead of the more 
  * public macros above.
  * --gmcnutt
  */
-#define __virt_to_bus(x) x
-#define __bus_to_virt(x) x
-#define __virt_to_phys(x) x
-#define __phys_to_virt(x) x
+#define __virt_to_bus(x) ((unsigned long) (x))
+#define __bus_to_virt(x) ((void *) (x))
+#define __virt_to_phys(x) ((unsigned long) (x))
+#define __phys_to_virt(x) ((void *) (x))
 
 
 /*
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/mmzone.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/mmzone.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/mmzone.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/mmzone.h	2004-12-06 19:35:49.000000000 +0100
@@ -10,6 +10,21 @@
 #ifndef __ASM_MMZONE_H
 #define __ASM_MMZONE_H
 
+/*
+ * Currently defined in arch/arm/mm/discontig.c
+ */
+extern pg_data_t discontig_node_data[];
+
+/*
+ * Return a pointer to the node data for node n.
+ */
+#define NODE_DATA(nid)		(&discontig_node_data[nid])
+
+/*
+ * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
+ */
+#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
+
 #include <asm/arch/mmzone.h>
 
 #endif
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/module.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/module.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/module.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/module.h	2004-12-06 19:35:49.000000000 +0100
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_ARM_MODULE_H */
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/page.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/page.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/page.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/page.h	2004-12-06 19:35:49.000000000 +0100
@@ -1,6 +1,8 @@
 #ifndef _ASMARM_PAGE_H
 #define _ASMARM_PAGE_H
 
+#include <linux/config.h>
+#include <asm/arch/memory.h>
 #include <asm/proc/page.h>
 
 #define PAGE_SIZE       (1UL << PAGE_SHIFT)
@@ -91,11 +93,10 @@
 
 #endif /* !__ASSEMBLY__ */
 
-#include <linux/config.h>
-#include <asm/arch/memory.h>
 
-#define __pa(x)			__virt_to_phys((unsigned long)(x))
-#define __va(x)			((void *)__phys_to_virt((unsigned long)(x)))
+
+#define __pa(x)			__virt_to_phys(x)
+#define __va(x)			__phys_to_virt(x)
 
 #ifndef CONFIG_DISCONTIGMEM
 
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/pci.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/pci.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/pci.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/pci.h	2004-12-06 19:35:49.000000000 +0100
@@ -41,7 +41,7 @@
 pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
 		    dma_addr_t dma_handle)
 {
-	consistent_free(vaddr);
+	consistent_free(vaddr, size, dma_handle);
 }
 
 /* Map a single buffer of the indicated size for DMA in streaming mode.
@@ -54,7 +54,7 @@
 pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 {
 	consistent_sync(ptr, size, direction);
-	return (dma_addr_t)virt_to_bus(ptr);
+	return virt_to_bus(ptr);
 }
 
 /* Unmap a single streaming mode DMA translation.  The dma_addr and size
@@ -92,7 +92,7 @@
 
 	for (i = 0; i < nents; i++, sg++) {
 		consistent_sync(sg->address, sg->length, direction);
-		sg->dma_address = (dma_addr_t)virt_to_bus(sg->address);
+		sg->dma_address = virt_to_bus(sg->address);
 	}
 
 	return nents;
@@ -120,7 +120,7 @@
 extern inline void
 pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
 {
-	consistent_sync((void*)bus_to_virt(dma_handle), size, direction);
+	consistent_sync(bus_to_virt(dma_handle), size, direction);
 }
 
 /* Make physical memory consistent for a set of streaming
@@ -148,6 +148,9 @@
 	return 1;
 }
 
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_controller_num(PDEV)	(0)
+
 #endif /* __KERNEL__ */
  
 #endif
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/pgalloc.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/pgalloc.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/pgalloc.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/pgalloc.h	2004-12-06 19:35:49.000000000 +0100
@@ -29,6 +24,13 @@
  */
 #define flush_tlb_pgtables(mm,start,end)	do { } while (0)
 
+#ifndef CONFIG_UCLINUX /* kf */ 
+/*
+ * Processor specific parts...
+ */
+#include <asm/proc/pgalloc.h>
+
+#endif
 /*
  * Page table cache stuff
  */
@@ -66,20 +68,20 @@
 	return (pgd_t *)ret;
 }
 
-/* We don't use pmd cache, so this is a dummy routine */
-#define get_pmd_fast()		((pmd_t *)0)
-
-extern __inline__ void free_pmd_fast(pmd_t *pmd)
+extern __inline__ void free_pgd_fast(pgd_t *pgd)
 {
+	__pgd_next(pgd) = (unsigned long) pgd_quicklist;
+	pgd_quicklist = (unsigned long *) pgd;
+	pgtable_cache_size++;
 }
 
-extern __inline__ pte_t *get_pte_fast(void)
+static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
 {
 	unsigned long *ret;
 
 	if((ret = pte_quicklist) != NULL) {
 		pte_quicklist = (unsigned long *)__pte_next(ret);
-		ret[0] = ret[1];
+		ret[0] = 0;
 		clean_dcache_entry(ret);
 		pgtable_cache_size--;
 	}
@@ -95,81 +97,47 @@
 
 #else	/* CONFIG_NO_PGT_CACHE */
 
-#define pgd_quicklist		((unsigned long *)0)
-#define pmd_quicklist		((unsigned long *)0)
-#define pte_quicklist		((unsigned long *)0)
+#define pgd_quicklist			((unsigned long *)0)
+#define pmd_quicklist			((unsigned long *)0)
+#define pte_quicklist			((unsigned long *)0)
 
-#define get_pgd_fast()		((pgd_t *)0)
-#define get_pmd_fast()		((pmd_t *)0)
-#define get_pte_fast()		((pte_t *)0)
+#define get_pgd_fast()			((pgd_t *)0)
+#define pte_alloc_one_fast(mm,addr)	((pte_t *)0)
 
-#define free_pmd_fast(pmd)	free_pmd_slow(pmd)
-#define free_pte_fast(pte)	free_pte_slow(pte)
+#define free_pgd_fast(pgd)		free_pgd_slow(pgd)
+#define free_pte_fast(pte)		pte_free_slow(pte)
 
 #endif	/* CONFIG_NO_PGT_CACHE */
 
-extern void free_pgd_slow(pgd_t *pgd);
-
-#define free_pmd_slow(pmd)	do { } while (0)
+#define pte_free(pte)			free_pte_fast(pte)
 
-extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long addr_preadjusted);
-extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long addr_preadjusted);
-extern void free_pte_slow(pte_t *pte);
 
 /*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
+ * Since we have only two-level page tables, these are trivial
  */
-#define pte_free_kernel(pte)	free_pte_fast(pte)
-#define pte_free(pte)		free_pte_fast(pte)
+#define pmd_alloc_one_fast(mm,addr)	({ BUG(); ((pmd_t *)1); })
+#define pmd_alloc_one(mm,addr)		({ BUG(); ((pmd_t *)2); })
+#define pmd_free_slow(pmd)		do { } while (0)
+#define pmd_free_fast(pmd)		do { } while (0)
+#define pmd_free(pmd)			do { } while (0)
+#define pgd_populate(mm,pmd,pte)	BUG()
 
-#ifndef pte_alloc_kernel
-extern __inline__ pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address)
-{
-	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
-	if (pmd_none(*pmd)) {
-		pte_t *page = (pte_t *) get_pte_fast();
-
-		if (!page)
-			return get_pte_kernel_slow(pmd, address);
-		set_pmd(pmd, mk_kernel_pmd(page));
-		return page + address;
-	}
-	if (pmd_bad(*pmd)) {
-		__handle_bad_pmd_kernel(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + address;
-}
-#endif
+extern pgd_t *get_pgd_slow(struct mm_struct *mm);
+extern void free_pgd_slow(pgd_t *pgd);
 
-extern __inline__ pte_t *pte_alloc(pmd_t * pmd, unsigned long address)
+extern __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
-	if (pmd_none(*pmd)) {
-		pte_t *page = (pte_t *) get_pte_fast();
-
-		if (!page)
-			return get_pte_slow(pmd, address);
-		set_pmd(pmd, mk_user_pmd(page));
-		return page + address;
-	}
-	if (pmd_bad(*pmd)) {
-		__handle_bad_pmd(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + address;
-}
+	pgd_t *pgd;
 
-#define pmd_free_kernel		pmd_free
-#define pmd_free(pmd)		do { } while (0)
+	pgd = get_pgd_fast();
+	if (!pgd)
+		pgd = get_pgd_slow(mm);
 
-#define pmd_alloc_kernel	pmd_alloc
-extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
-{
-	return (pmd_t *) pgd;
+	return pgd;
 }
 
+#define pgd_free(pgd)			free_pgd_fast(pgd)
+
+extern int do_check_pgt_cache(int, int);
 
 #endif
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/pgtable.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/pgtable.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/pgtable.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/pgtable.h	2004-12-06 19:35:49.000000000 +0100
@@ -11,8 +11,7 @@
 #define _ASMARM_PGTABLE_H
 
 #include <linux/config.h>
-//#include <asm/arch/memory.h>
-#include <asm/memory.h>
+#include <asm/arch/memory.h>
 #include <asm/proc-fns.h>
 
 /*
@@ -76,12 +75,6 @@
 extern struct page *empty_zero_page;
 #define ZERO_PAGE(vaddr)	(empty_zero_page)
 
-/*
- * Handling allocation failures during page table setup.
- */
-extern void __handle_bad_pmd(pmd_t *pmd);
-extern void __handle_bad_pmd_kernel(pmd_t *pmd);
-
 #define pte_none(pte)		(!pte_val(pte))
 #define pte_clear(ptep)		set_pte((ptep), __pte(0))
 
@@ -99,6 +92,7 @@
 #endif
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
+#define pmd_present(pmd)	(pmd_val(pmd))
 #define pmd_clear(pmdp)		set_pmd(pmdp, __pmd(0))
 
 /*
@@ -165,8 +159,6 @@
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
-#define update_mmu_cache(vma,address,pte) do { } while (0)
-
 /* Encode and decode a swap entry.
  *
  * We support up to 32GB of swap on 4k machines
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-armv/cache.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-armv/cache.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-armv/cache.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-armv/cache.h	2004-12-06 19:35:49.000000000 +0100
@@ -154,3 +154,9 @@
 			cpu_tlb_invalidate_page((_page),		\
 				 ((_vma)->vm_flags & VM_EXEC));		\
 	} while (0)
+
+/*
+ * 32-bit ARM Processors don't have any MMU cache
+ */
+#define update_mmu_cache(vma,address,pte) do { } while (0)
+
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-armv/pgtable.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-armv/pgtable.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-armv/pgtable.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-armv/pgtable.h	2004-12-06 19:35:49.000000000 +0100
@@ -48,8 +48,9 @@
 #define pmd_bad(pmd)		(pmd_val(pmd) & 2)
 #define set_pmd(pmdp,pmd)	cpu_set_pmd(pmdp,pmd)
 
-extern __inline__ pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
+static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
 {
+#ifndef CONFIG_UCLINUX
 	unsigned long pte_ptr = (unsigned long)ptep;
 	pmd_t pmd;
 
@@ -62,14 +63,15 @@
 	pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot;
 
 	return pmd;
+#else
+	pmd_t pmd;
+	return pmd;
+#endif
 }
 
-/* these are aliases for the above function */
-#define mk_user_pmd(ptep)	__mk_pmd(ptep, _PAGE_USER_TABLE)
-#define mk_kernel_pmd(ptep)	__mk_pmd(ptep, _PAGE_KERNEL_TABLE)
-
-extern __inline__ unsigned long pmd_page(pmd_t pmd)
+static inline unsigned long pmd_page(pmd_t pmd)
 {
+#ifndef CONFIG_UCLINUX
 	unsigned long ptr;
 
 	ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
@@ -77,6 +79,9 @@
 	ptr += PTRS_PER_PTE * sizeof(void *);
 
 	return __phys_to_virt(ptr);
+#else
+	return 0;
+#endif
 }
 
 /****************
@@ -161,7 +166,6 @@
 PTE_BIT_FUNC(mkdirty,   |= L_PTE_DIRTY);
 PTE_BIT_FUNC(mkold,     &= ~L_PTE_YOUNG);
 PTE_BIT_FUNC(mkyoung,   |= L_PTE_YOUNG);
-PTE_BIT_FUNC(nocache,   &= ~L_PTE_CACHEABLE);
 
 /*
  * Mark the prot value as uncacheable and unbufferable.
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-armv/system.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-armv/system.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-armv/system.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-armv/system.h	2004-12-06 19:35:49.000000000 +0100
@@ -12,17 +12,36 @@
 
 #include <linux/config.h>
 
-/*
- * set_cr -- sets a register in the coprocessor. Probably not applicable
- * to an MMU-less system, since if we don't have an MMU we probably don't
- * have a coprocessor.
- * --gmcnutt
- */
-#define set_cr(x)		
+#define set_cr(x)					\
+	__asm__ __volatile__(				\
+	"mcr	p15, 0, %0, c1, c0	@ set CR"	\
+	: : "r" (x))
+
+#define CR_M	(1 << 0)	/* MMU enable				*/
+#define CR_A	(1 << 1)	/* Alignment abort enable		*/
+#define CR_C	(1 << 2)	/* Dcache enable			*/
+#define CR_W	(1 << 3)	/* Write buffer enable			*/
+#define CR_P	(1 << 4)	/* 32-bit exception handler		*/
+#define CR_D	(1 << 5)	/* 32-bit data address range		*/
+#define CR_L	(1 << 6)	/* Implementation defined		*/
+#define CD_B	(1 << 7)	/* Big endian				*/
+#define CR_S	(1 << 8)	/* System MMU protection		*/
+#define CD_R	(1 << 9)	/* ROM MMU protection			*/
+#define CR_F	(1 << 10)	/* Implementation defined		*/
+#define CR_Z	(1 << 11)	/* Implementation defined		*/
+#define CR_I	(1 << 12)	/* Icache enable			*/
+#define CR_V	(1 << 13)	/* Vectors relocated to 0xffff0000	*/
+#define CR_RR	(1 << 14)	/* Round Robin cache replacement	*/
 
 extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
 extern unsigned long cr_alignment;	/* defined in entry-armv.S */
 
+#ifdef __ARM_ARCH_4__
+#define vectors_base()	((cr_alignment & CR_V) ? 0xffff0000 : 0)
+#else
+#define vectors_base()	(0)
+#endif
+
 /*
  * A couple of speedups for the ARM
  */
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-armv/uaccess.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-armv/uaccess.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-armv/uaccess.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-armv/uaccess.h	2004-12-06 19:35:49.000000000 +0100
@@ -37,7 +37,7 @@
 #include <linux/config.h>
 #ifdef CONFIG_UCLINUX
 #define __range_ok(addr,size) 0
-#define __addr_ok(addr) 0
+#define __addr_ok(addr) 1
 
 #else
 /* We use 33-bit arithmetic here... */
@@ -111,7 +111,7 @@
 	"	.align	3\n"					\
 	"	.long	1b, 3b\n"				\
 	"	.previous"					\
-	: "=r" (err), "=r" (x)					\
+	: "=r" (err), "=&r" (x)					\
 	: "r" (addr), "i" (-EFAULT), "0" (err))
 
 #define __get_user_asm_half(x,addr,err)				\
@@ -137,7 +137,7 @@
 	"	.align	3\n"					\
 	"	.long	1b, 3b\n"				\
 	"	.previous"					\
-	: "=r" (err), "=r" (x)					\
+	: "=r" (err), "=&r" (x)					\
 	: "r" (addr), "i" (-EFAULT), "0" (err))
 
 extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n);
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-fns.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-fns.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/proc-fns.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/proc-fns.h	2004-12-06 19:35:49.000000000 +0100
@@ -60,6 +60,22 @@
 #   define CPU_NAME arm920
 #  endif
 # endif
+# ifdef CONFIG_CPU_ARM926T
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm926
+#  endif
+# endif
+# ifdef CONFIG_CPU_ARM940T
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME arm940
+#  endif
+# endif
 # ifdef CONFIG_CPU_SA110
 #  ifdef CPU_NAME
 #   undef  MULTI_CPU
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/procinfo.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/procinfo.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/procinfo.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/procinfo.h	2004-12-06 19:35:49.000000000 +0100
@@ -46,10 +46,13 @@
 
 #endif	/* __ASSEMBLY__ */
 
-#define HWCAP_SWP	1
-#define HWCAP_HALF	2
-#define HWCAP_THUMB	4
-#define HWCAP_26BIT	8	/* Play it safe */
+#define HWCAP_SWP	 1
+#define HWCAP_HALF	 2
+#define HWCAP_THUMB	 4
+#define HWCAP_26BIT	 8	/* Play it safe */
+#define HWCAP_FAST_MULT	 16
+#define HWCAP_FPA        32
+#define HWCAP_VFP        64
+#define HWCAP_EDSP	 128
 
 #endif
-
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/semaphore.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/semaphore.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/semaphore.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/semaphore.h	2004-12-06 19:35:49.000000000 +0100
@@ -7,6 +7,7 @@
 #include <linux/linkage.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
+#include <linux/rwsem.h>
 
 #include <asm/atomic.h>
 #include <asm/proc/locks.h>
@@ -124,133 +125,4 @@
 	__up_op(sem, __up_wakeup);
 }
 
-/* rw mutexes (should that be mutices? =) -- throw rw
- * spinlocks and semaphores together, and this is what we
- * end up with...
- *
- * The lock is initialized to BIAS.  This way, a writer
- * subtracts BIAS ands gets 0 for the case of an uncontended
- * lock.  Readers decrement by 1 and see a positive value
- * when uncontended, negative if there are writers waiting
- * (in which case it goes to sleep).
- *
- * In terms of fairness, this should result in the lock
- * flopping back and forth between readers and writers
- * under heavy use.
- *
- *              -ben
- */
-struct rw_semaphore {
-	atomic_t                count;
-	volatile unsigned char  write_bias_granted;
-	volatile unsigned char  read_bias_granted;
-	volatile unsigned char  pad1;
-	volatile unsigned char  pad2;
-	wait_queue_head_t       wait;
-	wait_queue_head_t	write_bias_wait;
-#if WAITQUEUE_DEBUG
-	long			__magic;
-	atomic_t		readers;
-	atomic_t		writers;
-#endif
-};
-
-#if WAITQUEUE_DEBUG
-#define __RWSEM_DEBUG_INIT	, ATOMIC_INIT(0), ATOMIC_INIT(0)
-#else
-#define __RWSEM_DEBUG_INIT	/* */
-#endif
-
-#define __RWSEM_INITIALIZER(name,count) \
-{ ATOMIC_INIT(count), 0, 0, 0, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
-	__WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \
-	__SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
-
-#define __DECLARE_RWSEM_GENERIC(name,count) \
-	struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
-
-#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS)
-#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
-#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
-
-extern inline void init_rwsem(struct rw_semaphore *sem)
-{
-	atomic_set(&sem->count, RW_LOCK_BIAS);
-	sem->read_bias_granted = 0;
-	sem->write_bias_granted = 0;
-	init_waitqueue_head(&sem->wait);
-	init_waitqueue_head(&sem->write_bias_wait);
-#if WAITQUEUE_DEBUG
-	sem->__magic = (long)&sem->__magic;
-	atomic_set(&sem->readers, 0);
-	atomic_set(&sem->writers, 0);
-#endif
-}
-
-extern struct rw_semaphore *__down_read_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *__down_write_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *__rwsem_wake(struct rw_semaphore *sem);
-
-extern inline void down_read(struct rw_semaphore *sem)
-{
-#if WAITQUEUE_DEBUG
-	CHECK_MAGIC(sem->__magic);
-#endif
-	__down_op_read(sem, __down_read_failed);
-#if WAITQUEUE_DEBUG
-	if (sem->write_bias_granted)
-		BUG();
-	if (atomic_read(&sem->writers))
-		BUG();
-	atomic_inc(&sem->readers);
-#endif
-}
-
-extern inline void down_write(struct rw_semaphore *sem)
-{
-#if WAITQUEUE_DEBUG
-	CHECK_MAGIC(sem->__magic);
-#endif
-	__down_op_write(sem, __down_write_failed);
-#if WAITQUEUE_DEBUG
-	if (atomic_read(&sem->writers))
-		BUG();
-	if (atomic_read(&sem->readers))
-		BUG();
-	if (sem->read_bias_granted)
-		BUG();
-	if (sem->write_bias_granted)
-		BUG();
-	atomic_inc(&sem->writers);
-#endif
-}
-
-extern inline void up_read(struct rw_semaphore *sem)
-{
-#if WAITQUEUE_DEBUG
-	if (sem->write_bias_granted)
-		BUG();
-	if (atomic_read(&sem->writers))
-		BUG();
-	atomic_dec(&sem->readers);
-#endif
-	__up_op_read(sem, __rwsem_wake);
-}
-
-extern inline void up_write(struct rw_semaphore *sem)
-{
-#if WAITQUEUE_DEBUG
-	if (sem->read_bias_granted)
-		BUG();
-	if (sem->write_bias_granted)
-		BUG();
-	if (atomic_read(&sem->readers))
-		BUG();
-	if (atomic_read(&sem->writers) != 1)
-		BUG();
-	atomic_dec(&sem->writers);
-#endif
-	__up_op_write(sem, __rwsem_wake);
-}
-
 #endif
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/setup.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/setup.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/setup.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/setup.h	2004-12-06 19:35:49.000000000 +0100
@@ -204,10 +204,21 @@
 	int (*parse)(const struct tag *);
 };
 
+#define __tag __attribute__((unused, __section__(".taglist")))
+#define __tagtable(tag, fn) \
+static struct tagtable __tagtable_##fn __tag = { tag, fn }
+
+#define tag_member_present(tag,member)				\
+	((unsigned long)(&((struct tag *)0L)->member + 1)	\
+		<= (tag)->hdr.size * 4)
+
+#define tag_next(t)	((struct tag *)((u32 *)(t) + (t)->hdr.size))
+#define tag_size(type)	((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
+
 /*
  * Memory map description
  */
-#define NR_BANKS 4
+#define NR_BANKS 8
 
 struct meminfo {
 	int nr_banks;
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/socket.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/socket.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/socket.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/socket.h	2004-12-06 19:35:49.000000000 +0100
@@ -43,6 +43,8 @@
 #define SO_TIMESTAMP		29
 #define SCM_TIMESTAMP		SO_TIMESTAMP
 
+#define SO_ACCEPTCONN		30
+
 /* Nast libc5 fixup - bletch */
 #if defined(__KERNEL__)
 /* Socket types. */
@@ -56,6 +58,7 @@
 					/* level.  For writing rarp and	*/
 					/* other similar things on the	*/
 					/* user level.			*/
+#define	SOCK_MAX	(SOCK_PACKET+1)
 #endif
 
 #endif /* _ASM_SOCKET_H */
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/softirq.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/softirq.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/softirq.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/softirq.h	2004-12-06 19:35:49.000000000 +0100
@@ -4,12 +4,23 @@
 #include <asm/atomic.h>
 #include <asm/hardirq.h>
 
-#define cpu_bh_disable(cpu)	do { local_bh_count(cpu)++; barrier(); } while (0)
-#define cpu_bh_enable(cpu)	do { barrier(); local_bh_count(cpu)--; } while (0)
+#define __cpu_bh_enable(cpu) \
+		do { barrier(); local_bh_count(cpu)--; } while (0)
+#define cpu_bh_disable(cpu) \
+		do { local_bh_count(cpu)++; barrier(); } while (0)
 
 #define local_bh_disable()	cpu_bh_disable(smp_processor_id())
-#define local_bh_enable()	cpu_bh_enable(smp_processor_id())
+#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
+#define __cpu_raise_softirq(cpu,nr) set_bit((nr), &softirq_pending(cpu))
+#define raise_softirq(nr)	__cpu_raise_softirq(smp_processor_id(), (nr))
 
 #define in_softirq()		(local_bh_count(smp_processor_id()) != 0)
 
+#define local_bh_enable()						\
+do {									\
+	unsigned int *ptr = &local_bh_count(smp_processor_id());	\
+	if (!--*ptr && ptr[-2])						\
+		__asm__("bl%? __do_softirq": : : "lr");/* out of line */\
+} while (0)
+
 #endif	/* __ASM_SOFTIRQ_H */
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/termios.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/termios.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/termios.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/termios.h	2004-12-06 19:35:49.000000000 +0100
@@ -61,10 +61,11 @@
 #define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
 #define N_R3964		9	/* Reserved for Simatic R3964 module */
 #define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA		11	/* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */
+#define N_IRDA		11	/* Linux IrDa - http://irda.sourceforge.net/ */
 #define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
 #define N_HDLC		13	/* synchronous HDLC */
 #define N_SYNC_PPP	14
+#define N_HCI		15  /* Bluetooth HCI UART */
 
 #ifdef __KERNEL__
 
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/uaccess.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/uaccess.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/uaccess.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/uaccess.h	2004-12-06 19:35:49.000000000 +0100
@@ -43,6 +43,7 @@
  *         current->addr_limit setting as a check. I don't know that we ever
  *         set that up the way it expects it.
  */
+
 #define access_ok(type,addr,size)	(__range_ok(addr,size) == 0)
 
 extern __inline__ int verify_area(int type, const void * addr, unsigned long size)
@@ -81,6 +82,8 @@
 {
 	if (access_ok(VERIFY_READ, from, n))
 		__do_copy_from_user(to, from, n);
+	else /* security hole */
+	  memzero(to, n);
 	return n;
 }
 
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/unistd.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/unistd.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/unistd.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/unistd.h	2004-12-06 19:35:49.000000000 +0100
@@ -82,7 +82,7 @@
 #define __NR_sigpending			(__NR_SYSCALL_BASE+ 73)
 #define __NR_sethostname		(__NR_SYSCALL_BASE+ 74)
 #define __NR_setrlimit			(__NR_SYSCALL_BASE+ 75)
-#define __NR_old_getrlimit		(__NR_SYSCALL_BASE+ 76)	/* Back compat 2GB limited rlimit */
+#define __NR_getrlimit			(__NR_SYSCALL_BASE+ 76)	/* Back compat 2GB limited rlimit */
 #define __NR_getrusage			(__NR_SYSCALL_BASE+ 77)
 #define __NR_gettimeofday		(__NR_SYSCALL_BASE+ 78)
 #define __NR_settimeofday		(__NR_SYSCALL_BASE+ 79)
@@ -197,7 +197,7 @@
 					/* 188 reserved */
 					/* 189 reserved */
 #define __NR_vfork			(__NR_SYSCALL_BASE+190)
-#define __NR_getrlimit			(__NR_SYSCALL_BASE+191)	/* SuS compliant getrlimit */
+#define __NR_ugetrlimit			(__NR_SYSCALL_BASE+191)	/* SuS compliant getrlimit */
 #define __NR_mmap2			(__NR_SYSCALL_BASE+192)
 #define __NR_truncate64			(__NR_SYSCALL_BASE+193)
 #define __NR_ftruncate64		(__NR_SYSCALL_BASE+194)
@@ -224,6 +224,19 @@
 #define __NR_setfsuid32			(__NR_SYSCALL_BASE+215)
 #define __NR_setfsgid32			(__NR_SYSCALL_BASE+216)
 #define __NR_getdents64			(__NR_SYSCALL_BASE+217)
+#define __NR_pivot_root			(__NR_SYSCALL_BASE+218)
+#define __NR_mincore			(__NR_SYSCALL_BASE+219)
+#define __NR_madvise			(__NR_SYSCALL_BASE+220)
+#define __NR_fcntl64			(__NR_SYSCALL_BASE+221)
+
+/*
+ * The following SWIs are ARM private.
+ */
+#define __ARM_NR_BASE			(__NR_SYSCALL_BASE+0x0f0000)
+#define __ARM_NR_breakpoint		(__ARM_NR_BASE+1)
+#define __ARM_NR_cacheflush		(__ARM_NR_BASE+2)
+#define __ARM_NR_usr26			(__ARM_NR_BASE+3)
+#define __ARM_NR_usr32			(__ARM_NR_BASE+4)
 
 #define __sys2(x) #x
 #define __sys1(x) __sys2(x)
@@ -400,7 +413,6 @@
 
 static inline pid_t waitpid(pid_t pid, int *wait_stat, int options)
 {
-	extern long sys_wait4(int, int *, int, struct rusage *);
 	return sys_wait4((int)pid, wait_stat, options, NULL);
 }
 
@@ -412,7 +424,6 @@
 
 static inline pid_t wait(int * wait_stat)
 {
-	extern long sys_wait4(int, int *, int, struct rusage *);
 	return sys_wait4(-1, wait_stat, 0, NULL);
 }
 
diff -ur linux-2.4.6.uc0pre0.orig/include/asm-armnommu/virtconvert.h linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/virtconvert.h
--- linux-2.4.6.uc0pre0.orig/include/asm-armnommu/virtconvert.h	2004-12-06 19:34:59.000000000 +0100
+++ linux-2.4.6.uc0pre0.actiontec/include/asm-armnommu/virtconvert.h	2004-12-06 19:35:49.000000000 +0100
@@ -7,8 +7,6 @@
 
 #ifdef __KERNEL__
 
-
-#define mm_vtop(vaddr)		((unsigned long) vaddr)
 #define mm_vtop(vaddr)		((unsigned long) vaddr)
 
 #endif

