Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (197 commits)
  sh: add spi header and r2d platform data V3
  sh: update r7780rp interrupt code
  sh: remove consistent alloc stuff from the machine vector
  sh: use declared coherent memory for dreamcast pci ethernet adapter
  sh: declared coherent memory support V2
  sh: Add support for SDK7780 board.
  sh: constify function pointer tables
  sh: Kill off -traditional for linker script.
  cdrom: Add support for Sega Dreamcast GD-ROM.
  sh: Kill off hs7751rvoip reference from arch/sh/Kconfig.
  sh: Drop r7780rp_defconfig, use r7780mp_defconfig as kbuild default.
  sh: Kill off dead HS771RVoIP board support.
  sh: r7785rp: Fix up DECLARE_INTC_DESC() arg mismatch.
  sh: r7785rp: Hook up the rest of the HL7785 FPGA IRQ vectors.
  sh: r2d - enable sm501 usb host function
  sh: remove voyagergx
  sh: r2d - add lcd planel timings to sm501 platform data
  sh: Add OHCI and UDC platform devices for SH7720.
  sh: intc - remove default interrupt priority tables
  sh: Correct pte size mismatch for X2 TLB.
  ...
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt
index 555c8cf..af3b925 100644
--- a/Documentation/cpu-freq/user-guide.txt
+++ b/Documentation/cpu-freq/user-guide.txt
@@ -45,6 +45,7 @@
 ARM Integrator
 ARM-SA1100
 ARM-SA1110
+Intel PXA
 
 
 1.2 x86
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index cb12ae1..53a6389 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -141,6 +141,7 @@
 - ppc64
 - ia64 (Does not support probes on instruction slot1.)
 - sparc64 (Return probes not yet implemented.)
+- arm
 
 3. Configuring Kprobes
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a04f507..de211ac 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -180,8 +180,8 @@
 	bool "Atmel AT91"
 	select GENERIC_GPIO
 	help
-	  This enables support for systems based on the Atmel AT91RM9200
-	  and AT91SAM9xxx processors.
+	  This enables support for systems based on the Atmel AT91RM9200,
+	  AT91SAM9 and AT91CAP9 processors.
 
 config ARCH_CLPS7500
 	bool "Cirrus CL-PS7500FE"
@@ -217,6 +217,7 @@
 	bool "EP93xx-based"
 	select ARM_AMBA
 	select ARM_VIC
+	select GENERIC_GPIO
 	help
 	  This enables support for the Cirrus EP93xx series of CPUs.
 
@@ -333,6 +334,16 @@
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 
+config ARCH_ORION
+	bool "Marvell Orion"
+	depends on MMU
+	select PCI
+	select GENERIC_GPIO
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	help
+	  Support for Marvell Orion System on Chip family.
+
 config ARCH_PNX4008
 	bool "Philips Nexperia PNX4008 Mobile"
 	help
@@ -345,6 +356,7 @@
 	select GENERIC_GPIO
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select TICK_ONESHOT
 	help
 	  Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
 
@@ -366,6 +378,7 @@
 	select ARCH_DISCONTIGMEM_ENABLE
 	select ARCH_MTD_XIP
 	select GENERIC_GPIO
+	select GENERIC_TIME
 	help
 	  Support for StrongARM 11x0 based boards.
 
@@ -409,6 +422,17 @@
 	help
 	  Support for TI's OMAP platform (OMAP1 and OMAP2).
 
+config ARCH_MSM7X00A
+	bool "Qualcomm MSM7X00A"
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	help
+	  Support for Qualcomm MSM7X00A based systems.  This runs on the ARM11
+	  apps processor of the MSM7X00A and depends on a shared memory
+	  interface to the ARM9 modem processor which runs the baseband stack
+	  and controls some vital subsystems (clock and power control, etc).
+	  <http://www.cdmatech.com/products/msm7200_chipset_solution.jsp>
+
 endchoice
 
 source "arch/arm/mach-clps711x/Kconfig"
@@ -441,6 +465,8 @@
 
 source "arch/arm/mach-omap2/Kconfig"
 
+source "arch/arm/mach-orion/Kconfig"
+
 source "arch/arm/plat-s3c24xx/Kconfig"
 source "arch/arm/plat-s3c/Kconfig"
 
@@ -477,6 +503,8 @@
 
 source "arch/arm/mach-ks8695/Kconfig"
 
+source "arch/arm/mach-msm/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
@@ -657,6 +685,7 @@
 	default 128 if ARCH_L7200
 	default 200 if ARCH_EBSA110 || ARCH_S3C2410
 	default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
+	default AT91_TIMER_HZ if ARCH_AT91
 	default 100
 
 config AEABI
@@ -716,7 +745,7 @@
 		   ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
 		   ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
 		   ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \
-		   ARCH_KS8695
+		   ARCH_KS8695 || MACH_RD88F5182
 	help
 	  If you say Y here, the LEDs on your machine will be used
 	  to provide useful information about your current system status.
@@ -867,7 +896,7 @@
 
 endmenu
 
-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
 
 menu "CPU Frequency scaling"
 
@@ -903,6 +932,12 @@
 
 	  If in doubt, say N.
 
+config CPU_FREQ_PXA
+	bool
+	depends on CPU_FREQ && ARCH_PXA && PXA25x
+	default y
+	select CPU_FREQ_DEFAULT_GOV_USERSPACE
+
 endmenu
 
 endif
@@ -951,7 +986,7 @@
 
 config VFP
 	bool "VFP-format floating point maths"
-	depends on CPU_V6 || CPU_ARM926T
+	depends on CPU_V6 || CPU_ARM926T || CPU_V7 || CPU_FEROCEON
 	help
 	  Say Y to include VFP support code in the kernel. This is needed
 	  if your hardware includes a VFP unit.
@@ -961,6 +996,18 @@
 
 	  Say N if your target does not have VFP hardware.
 
+config VFPv3
+	bool
+	depends on VFP
+	default y if CPU_V7
+
+config NEON
+	bool "Advanced SIMD (NEON) Extension support"
+	depends on VFPv3 && CPU_V7
+	help
+	  Say Y to include support code for NEON, the ARMv7 Advanced SIMD
+	  Extension.
+
 endmenu
 
 menu "Userspace binary formats"
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 18101f5..192ee01 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -43,6 +43,12 @@
 	  you are concerned with the code size or don't want to see these
 	  messages.
 
+config DEBUG_STACK_USAGE
+	bool "Enable stack utilization instrumentation"
+	depends on DEBUG_KERNEL
+	help
+	  Enables the display of the minimum amount of free stack which each
+	  task has ever had available in the sysrq-T output.
 
 # These options are only for real kernel hackers who want to get their hands dirty.
 config DEBUG_LL
diff --git a/arch/arm/Kconfig.instrumentation b/arch/arm/Kconfig.instrumentation
index 63b8c6d..453ad8e 100644
--- a/arch/arm/Kconfig.instrumentation
+++ b/arch/arm/Kconfig.instrumentation
@@ -43,6 +43,16 @@
 config OPROFILE_ARM11_CORE
 	bool
 
+config KPROBES
+	bool "Kprobes"
+	depends on KALLSYMS && MODULES && !UML && !XIP_KERNEL
+	help
+	  Kprobes allows you to trap at almost any kernel address and
+	  execute a callback function.  register_kprobe() establishes
+	  a probepoint and specifies the callback.  Kprobes is useful
+	  for kernel debugging, non-intrusive instrumentation and testing.
+	  If in doubt, say "N".
+
 config MARKERS
 	bool "Activate markers"
 	help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 35e56c9..7b8ff66 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -139,6 +139,8 @@
  machine-$(CONFIG_ARCH_KS8695)     := ks8695
   incdir-$(CONFIG_ARCH_MXC)	   := mxc
  machine-$(CONFIG_ARCH_MX3)	   := mx3
+ machine-$(CONFIG_ARCH_ORION)	   := orion
+ machine-$(CONFIG_ARCH_MSM7X00A)   := msm
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 5fde99f..de9d9ee 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -44,10 +44,6 @@
 OBJS		+= head-sharpsl.o
 endif
 
-ifeq ($(CONFIG_ARCH_AT91RM9200),y)
-OBJS		+= head-at91rm9200.o
-endif
-
 ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
 ifeq ($(CONFIG_CPU_CP15),y)
 OBJS		+= big-endian.o
diff --git a/arch/arm/boot/compressed/head-at91rm9200.S b/arch/arm/boot/compressed/head-at91rm9200.S
deleted file mode 100644
index 11782cc..0000000
--- a/arch/arm/boot/compressed/head-at91rm9200.S
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * linux/arch/arm/boot/compressed/head-at91rm9200.S
- *
- *  Copyright (C) 2003 SAN People
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-#include <asm/mach-types.h>
-
-		.section	".start", "ax"
-
-		@ Atmel AT91RM9200-DK : 262
-		mov	r3,	#(MACH_TYPE_AT91RM9200DK & 0xff)
-		orr	r3, r3, #(MACH_TYPE_AT91RM9200DK & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ Cogent CSB337 : 399
-		mov	r3,	#(MACH_TYPE_CSB337 & 0xff)
-		orr	r3, r3, #(MACH_TYPE_CSB337 & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ Cogent CSB637 : 648
-		mov	r3,	#(MACH_TYPE_CSB637 & 0xff)
-		orr	r3, r3,	#(MACH_TYPE_CSB637 & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ Atmel AT91RM9200-EK : 705
-		mov	r3,	#(MACH_TYPE_AT91RM9200EK & 0xff)
-		orr	r3, r3, #(MACH_TYPE_AT91RM9200EK & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ Conitec Carmeva : 769
-		mov	r3,	#(MACH_TYPE_CARMEVA & 0xff)
-		orr	r3, r3, #(MACH_TYPE_CARMEVA & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ KwikByte KB920x : 612
-		mov	r3,	#(MACH_TYPE_KB9200 & 0xff)
-		orr	r3, r3, #(MACH_TYPE_KB9200 & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ Embest ATEB9200 : 923
-		mov	r3,	#(MACH_TYPE_ATEB9200 & 0xff)
-		orr	r3, r3,	#(MACH_TYPE_ATEB9200 & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ Sperry-Sun KAFA : 662
-		mov	r3,	#(MACH_TYPE_KAFA & 0xff)
-		orr	r3, r3,	#(MACH_TYPE_KAFA & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ picotux 200 : 963
-		mov	r3,	#(MACH_TYPE_PICOTUX2XX & 0xff)
-		orr	r3, r3, #(MACH_TYPE_PICOTUX2XX & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ Ajeco 1ARM : 1075
-		mov	r3,	#(MACH_TYPE_ONEARM & 0xff)
-		orr	r3, r3, #(MACH_TYPE_ONEARM & 0xff00)
-		cmp	r7, r3
-		beq	99f
-
-		@ Unknown board, use the AT91RM9200DK board
-		@ mov	r7, #MACH_TYPE_AT91RM9200
-		mov	r7,	#(MACH_TYPE_AT91RM9200DK & 0xff)
-		orr	r7, r7, #(MACH_TYPE_AT91RM9200DK & 0xff00)
-
-99:
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 5cac46a..3c2c8f2 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -623,6 +623,12 @@
 		b	__armv4_mmu_cache_off
 		b	__armv4_mmu_cache_flush
 
+		.word	0x56055310		@ Feroceon
+		.word	0xfffffff0
+		b	__armv4_mmu_cache_on
+		b	__armv4_mmu_cache_off
+		b	__armv5tej_mmu_cache_flush
+
 		@ These match on the architecture ID
 
 		.word	0x00020000		@ ARMv4T
@@ -641,7 +647,7 @@
 		.word	0x000f0000
 		b	__armv4_mmu_cache_on
 		b	__armv4_mmu_cache_off
-		b	__armv4_mmu_cache_flush
+		b	__armv5tej_mmu_cache_flush
 
 		.word	0x0007b000		@ ARMv6
 		.word	0x000ff000
@@ -821,6 +827,13 @@
 		mcr	p15, 0, r10, c7, c10, 4	@ drain WB
 		mov	pc, lr
 
+__armv5tej_mmu_cache_flush:
+1:		mrc	p15, 0, r15, c7, c14, 3	@ test,clean,invalidate D cache
+		bne	1b
+		mcr	p15, 0, r0, c7, c5, 0	@ flush I cache
+		mcr	p15, 0, r0, c7, c10, 4	@ drain WB
+		mov	pc, lr
+
 __armv4_mmu_cache_flush:
 		mov	r2, #64*1024		@ default: 32K dcache size (*2)
 		mov	r11, #32		@ default: 32 byte line size
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index bf1075e..f53bca4 100644
--- a/arch/arm/common/rtctime.c
+++ b/arch/arm/common/rtctime.c
@@ -20,7 +20,6 @@
 #include <linux/capability.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
-#include <linux/rtc.h>
 
 #include <asm/rtc.h>
 #include <asm/semaphore.h>
diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig
new file mode 100644
index 0000000..e32e736
--- /dev/null
+++ b/arch/arm/configs/at91cap9adk_defconfig
@@ -0,0 +1,1143 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24-rc8
+# Wed Jan 23 22:55:57 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+CONFIG_ARCH_AT91CAP9=y
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91CAP9 Board Type
+#
+CONFIG_MACH_AT91CAP9ADK=y
+
+#
+# AT91 Board Options
+#
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=100
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_AT91=y
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_ATMEL_SSC=y
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+CONFIG_LOGO_LINUX_VGA16=y
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_AT91=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+CONFIG_INSTRUMENTATION=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/colibri_defconfig b/arch/arm/configs/colibri_defconfig
new file mode 100644
index 0000000..c3e3418
--- /dev/null
+++ b/arch/arm/configs/colibri_defconfig
@@ -0,0 +1,1481 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24-rc3
+# Mon Dec  3 13:36:09 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LSF=y
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_MACH_EM_X270 is not set
+CONFIG_MACH_COLIBRI=y
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_ARMCORE is not set
+CONFIG_PXA27x=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_SUSPEND=y
+# CONFIG_APM_EMULATION is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_QUEUE=m
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_PXA_FICP is not set
+# CONFIG_MCS_FIR is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIUSB is not set
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+CONFIG_CFG80211=y
+CONFIG_NL80211=y
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+# CONFIG_MTD_CFI_NOSWAP is not set
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+CONFIG_MTD_PXA2XX=y
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=y
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
+CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
+# CONFIG_MTD_NAND_SHARPSL is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_ONENAND=y
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+# CONFIG_MTD_ONENAND_GENERIC is not set
+# CONFIG_MTD_ONENAND_OTP is not set
+# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
+# CONFIG_MTD_ONENAND_SIM is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=8
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+CONFIG_IDE_ARCH_OBSOLETE_INIT=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+CONFIG_DM9000=y
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_USB_ZD1201 is not set
+CONFIG_HOSTAP=y
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+# CONFIG_ZD1211RW is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_PXA27x is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+CONFIG_TOUCHSCREEN_UCB1400=y
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_PXA is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_SA1100_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+CONFIG_USB_GADGET_DUMMY_HCD=y
+CONFIG_USB_DUMMY_HCD=m
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_PXA is not set
+CONFIG_NEW_LEDS=y
+# CONFIG_LEDS_CLASS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+CONFIG_RTC_DRV_PCF8583=m
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SA1100 is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=1
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=m
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+CONFIG_INSTRUMENTATION=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 970c8c7..4264e27 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -367,7 +367,6 @@
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-CONFIG_MTD_OBSOLETE_CHIPS=y
 CONFIG_MTD_SHARP=y
 # CONFIG_MTD_XIP is not set
 
diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig
new file mode 100644
index 0000000..ed487b9
--- /dev/null
+++ b/arch/arm/configs/eseries_pxa_defconfig
@@ -0,0 +1,1499 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-hh17
+# Fri Nov  9 20:23:03 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_BOARD_IRQ_MAP_SMALL is not set
+CONFIG_BOARD_IRQ_MAP_BIG=y
+CONFIG_DMABOUNCE=y
+
+#
+# Intel PXA2xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+CONFIG_TOSHIBA_TMIO_OHCI=y
+CONFIG_ARCH_ESERIES=y
+CONFIG_MACH_E330=y
+CONFIG_MACH_E740=y
+CONFIG_MACH_E750=y
+CONFIG_MACH_E400=y
+CONFIG_MACH_E800=y
+CONFIG_E330_LCD=y
+CONFIG_E740_LCD=y
+CONFIG_E750_LCD=y
+CONFIG_E400_LCD=y
+CONFIG_E800_LCD=y
+CONFIG_ESERIES_UDC=y
+CONFIG_E330_TC6387XB=y
+CONFIG_E740_T7L66XB=y
+CONFIG_E400_T7L66XB=y
+CONFIG_E750_E800_TC6393XB=y
+CONFIG_E740_PCMCIA=m
+CONFIG_E750_PCMCIA=m
+CONFIG_E800_PCMCIA=m
+# CONFIG_MACH_A620 is not set
+# CONFIG_MACH_A716 is not set
+# CONFIG_MACH_A730 is not set
+# CONFIG_ARCH_H1900 is not set
+# CONFIG_ARCH_H2200 is not set
+# CONFIG_MACH_H3900 is not set
+# CONFIG_MACH_H4000 is not set
+# CONFIG_MACH_H4700 is not set
+# CONFIG_MACH_HX2750 is not set
+# CONFIG_ARCH_H5400 is not set
+# CONFIG_MACH_HIMALAYA is not set
+# CONFIG_MACH_HTCUNIVERSAL is not set
+# CONFIG_MACH_HTCALPINE is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_HTCAPACHE is not set
+# CONFIG_MACH_BLUEANGEL is not set
+
+#
+# HTC_HW6X00
+#
+# CONFIG_MACH_HTCBEETLES is not set
+# CONFIG_MACH_HW6900 is not set
+# CONFIG_MACH_HTCATHENA is not set
+# CONFIG_ARCH_AXIMX3 is not set
+# CONFIG_ARCH_AXIMX5 is not set
+# CONFIG_MACH_X50 is not set
+# CONFIG_ARCH_ROVERP1 is not set
+# CONFIG_ARCH_ROVERP5P is not set
+# CONFIG_MACH_XSCALE_PALMLD is not set
+# CONFIG_MACH_T3XSCALE is not set
+# CONFIG_MACH_RECON is not set
+# CONFIG_MACH_GHI270HG is not set
+# CONFIG_MACH_GHI270 is not set
+# CONFIG_MACH_LOOXC550 is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+CONFIG_PXA25x=y
+
+#
+# Linux As Bootloader
+#
+# CONFIG_LAB is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PXA2XX=m
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+# CONFIG_TXTOFFSET_DELTA is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_DPM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+# CONFIG_APM_EMULATION is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_IEEE80211_SOFTMAC is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_SHARPSL is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=6144
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=m
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=m
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=m
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+# CONFIG_BLK_DEV_SD is not set
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_USB_ZD1201 is not set
+CONFIG_HOSTAP=m
+# CONFIG_HOSTAP_FIRMWARE is not set
+# CONFIG_HOSTAP_CS is not set
+# CONFIG_ACX is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_TSDEV=m
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_LED_TRIGGER is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_WM97XX=m
+CONFIG_TOUCHSCREEN_WM9705=y
+CONFIG_TOUCHSCREEN_WM9712=y
+CONFIG_TOUCHSCREEN_WM9713=y
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_PXA is not set
+# CONFIG_RS232_SERIAL is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_TIHTC is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+# CONFIG_POWER_SUPPLY is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_ADC is not set
+
+#
+# Compaq/iPAQ Drivers
+#
+
+#
+# Compaq/HP iPAQ Drivers
+#
+# CONFIG_IPAQ_SLEEVE is not set
+# CONFIG_SLEEVE_DEBUG is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_ASIC2 is not set
+# CONFIG_HTC_ASIC3 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_BBKEYS is not set
+# CONFIG_HTC_ASIC3_DS1WM is not set
+# CONFIG_SOC_SAMCOP is not set
+# CONFIG_SOC_HAMCOP is not set
+# CONFIG_SOC_MQ11XX is not set
+CONFIG_SOC_T7L66XB=y
+# CONFIG_SOC_TC6387XB is not set
+CONFIG_SOC_TC6393XB=y
+# CONFIG_SOC_TSC2101 is not set
+# CONFIG_SOC_TSC2200 is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CORGI=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_IMAGEON is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
+CONFIG_FB_W100=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_VSFB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+CONFIG_FONT_ACORN_8x8=y
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_PXA2XX_AC97 is not set
+# CONFIG_SND_RECON is not set
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# SoC audio support
+#
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC=m
+
+#
+# SoC Platforms
+#
+
+#
+# SoC Audio for the Atmel AT91
+#
+
+#
+# SoC Audio for the Intel PXA2xx
+#
+CONFIG_SND_PXA2XX_SOC=m
+CONFIG_SND_PXA2XX_SOC_AC97=m
+CONFIG_SND_PXA2XX_SOC_E740_WM9705=m
+CONFIG_SND_PXA2XX_SOC_E750_WM9705=m
+CONFIG_SND_PXA2XX_SOC_E800_WM9712=m
+# CONFIG_SND_PXA2XX_SOC_MAGICIAN is not set
+# CONFIG_SND_PXA2XX_SOC_BLUEANGEL is not set
+# CONFIG_SND_PXA2XX_SOC_H5000 is not set
+
+#
+# SoC Audio for the Freescale i.MX
+#
+
+#
+# SoC Audio for the Samsung S3C24XX
+#
+# CONFIG_SND_SOC_AC97_CODEC is not set
+# CONFIG_SND_SOC_WM8711 is not set
+# CONFIG_SND_SOC_WM8510 is not set
+# CONFIG_SND_SOC_WM8731 is not set
+# CONFIG_SND_SOC_WM8750 is not set
+# CONFIG_SND_SOC_WM8753 is not set
+# CONFIG_SND_SOC_WM8772 is not set
+# CONFIG_SND_SOC_WM8971 is not set
+# CONFIG_SND_SOC_WM8956 is not set
+# CONFIG_SND_SOC_WM8960 is not set
+# CONFIG_SND_SOC_WM8976 is not set
+# CONFIG_SND_SOC_WM8974 is not set
+# CONFIG_SND_SOC_WM8980 is not set
+CONFIG_SND_SOC_WM9705=m
+# CONFIG_SND_SOC_WM9713 is not set
+CONFIG_SND_SOC_WM9712=m
+# CONFIG_SND_SOC_UDA1380 is not set
+# CONFIG_SND_SOC_AK4535 is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=m
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DYNAMIC_MINORS=y
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+CONFIG_USB_GADGET_PXA2XX=y
+CONFIG_USB_PXA2XX=y
+# CONFIG_USB_PXA2XX_SMALL is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_MQ11XX is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+# CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_CHAR is not set
+# CONFIG_USB_PXA2XX_GPIO is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_PXA is not set
+CONFIG_MMC_TMIO=y
+# CONFIG_MMC_SAMCOP is not set
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
index add03c9..988b4d1 100644
--- a/arch/arm/configs/iop13xx_defconfig
+++ b/arch/arm/configs/iop13xx_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22
-# Thu Jul 19 15:57:52 2007
+# Linux kernel version: 2.6.24-rc5
+# Wed Dec 12 16:11:03 2007
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -26,15 +26,11 @@
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
@@ -45,10 +41,15 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -69,7 +70,6 @@
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -130,6 +130,7 @@
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
@@ -151,9 +152,12 @@
 CONFIG_MACH_IQ81340MC=y
 
 #
-# IOP13XX IMU Support
+# Boot options
 #
-# CONFIG_IOP_IMU is not set
+
+#
+# Power management
+#
 CONFIG_PLAT_IOP=y
 
 #
@@ -185,10 +189,7 @@
 CONFIG_PCI_SYSCALL=y
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+CONFIG_PCI_LEGACY=y
 # CONFIG_PCCARD is not set
 
 #
@@ -207,6 +208,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
 # CONFIG_RESOURCES_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
@@ -246,6 +248,7 @@
 # Power management options
 #
 # CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
 
 #
 # Networking
@@ -285,6 +288,7 @@
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -324,10 +328,6 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -356,6 +356,7 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -383,6 +384,7 @@
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -423,6 +425,7 @@
 CONFIG_MTD_PHYSMAP_LEN=0x0
 CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 # CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -463,6 +466,11 @@
 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 
 #
 # SCSI device support
@@ -499,12 +507,9 @@
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 CONFIG_SCSI_ISCSI_ATTRS=y
-CONFIG_SCSI_SAS_ATTRS=y
 # CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -515,6 +520,7 @@
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
@@ -555,14 +561,8 @@
 # CONFIG_DM_ZERO is not set
 # CONFIG_DM_MULTIPATH is not set
 # CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
+# CONFIG_DM_UEVENT is not set
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -577,6 +577,8 @@
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
 # CONFIG_NET_ETHERNET is not set
 CONFIG_NETDEV_1000=y
@@ -585,6 +587,7 @@
 CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -592,6 +595,7 @@
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -600,11 +604,14 @@
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
 # CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
@@ -639,7 +646,6 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -688,12 +694,10 @@
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
@@ -758,9 +762,9 @@
 # CONFIG_SPI is not set
 # CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -768,12 +772,13 @@
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -787,14 +792,17 @@
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -806,11 +814,13 @@
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_TIFM_CORE is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -818,19 +828,6 @@
 # CONFIG_MFD_SM501 is not set
 
 #
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -840,14 +837,16 @@
 #
 # Graphics support
 #
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_FB is not set
 
 #
 # Console display driver support
@@ -862,6 +861,7 @@
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -877,16 +877,15 @@
 #
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
-
-#
-# Real Time Clock
-#
+# CONFIG_NEW_LEDS is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
+CONFIG_DMADEVICES=y
 
 #
-# DMA Engine support
+# DMA Devices
 #
+CONFIG_INTEL_IOP_ADMA=y
 CONFIG_DMA_ENGINE=y
 
 #
@@ -895,12 +894,6 @@
 # CONFIG_NET_DMA is not set
 
 #
-# DMA Devices
-#
-# CONFIG_INTEL_IOATDMA is not set
-CONFIG_INTEL_IOP_ADMA=y
-
-#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -912,7 +905,6 @@
 # CONFIG_EXT3_FS_SECURITY is not set
 # CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -952,7 +944,6 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -969,10 +960,12 @@
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 # CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
@@ -981,10 +974,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -1037,10 +1027,6 @@
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_437 is not set
@@ -1081,21 +1067,16 @@
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
-
-#
-# Profiling support
-#
+CONFIG_INSTRUMENTATION=y
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
@@ -1104,6 +1085,7 @@
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
 CONFIG_DEBUG_USER=y
 
 #
@@ -1112,6 +1094,7 @@
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_XOR_BLOCKS=y
 CONFIG_ASYNC_CORE=y
 CONFIG_ASYNC_MEMCPY=y
@@ -1136,6 +1119,7 @@
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_LRW=y
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -1150,11 +1134,13 @@
 CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_KHAZAD=y
 CONFIG_CRYPTO_ANUBIS=y
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=y
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
 CONFIG_CRYPTO_HW=y
 
 #
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index 027aef2..83f40d4 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22
-# Thu Jul 19 16:00:36 2007
+# Linux kernel version: 2.6.24-rc5
+# Wed Dec 12 15:49:08 2007
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -26,15 +26,11 @@
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
@@ -45,9 +41,14 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -69,7 +70,6 @@
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -130,6 +130,7 @@
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
@@ -153,6 +154,15 @@
 CONFIG_ARCH_IQ31244=y
 CONFIG_MACH_N2100=y
 CONFIG_IOP3XX_ATU=y
+# CONFIG_MACH_EM7210 is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
 CONFIG_PLAT_IOP=y
 
 #
@@ -182,11 +192,8 @@
 CONFIG_PCI=y
 CONFIG_PCI_SYSCALL=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 
 #
@@ -205,6 +212,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
 # CONFIG_RESOURCES_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
@@ -244,6 +252,7 @@
 # Power management options
 #
 # CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
 
 #
 # Networking
@@ -282,6 +291,7 @@
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -321,10 +331,6 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -353,6 +359,7 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -382,6 +389,7 @@
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -417,6 +425,7 @@
 CONFIG_MTD_PHYSMAP_LEN=0x0
 CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -459,6 +468,11 @@
 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 # CONFIG_IDE is not set
 
 #
@@ -496,12 +510,9 @@
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -512,6 +523,7 @@
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
@@ -576,6 +588,7 @@
 # CONFIG_PATA_OLDPIIX is not set
 # CONFIG_PATA_NETCELL is not set
 # CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
 # CONFIG_PATA_PDC_OLD is not set
@@ -606,14 +619,8 @@
 # CONFIG_DM_ZERO is not set
 # CONFIG_DM_MULTIPATH is not set
 # CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
+# CONFIG_DM_UEVENT is not set
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -628,6 +635,8 @@
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
@@ -641,13 +650,16 @@
 # CONFIG_DM9000 is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
 # CONFIG_FEALNX is not set
@@ -667,6 +679,7 @@
 CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -675,6 +688,7 @@
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -683,11 +697,14 @@
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
 # CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
@@ -703,7 +720,6 @@
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
@@ -732,7 +748,6 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -781,12 +796,10 @@
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
@@ -852,9 +865,9 @@
 # CONFIG_SPI is not set
 # CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -862,12 +875,13 @@
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -881,14 +895,17 @@
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -900,11 +917,13 @@
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_TIFM_CORE is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -912,19 +931,6 @@
 # CONFIG_MFD_SM501 is not set
 
 #
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -935,14 +941,16 @@
 #
 # Graphics support
 #
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_FB is not set
 
 #
 # Console display driver support
@@ -957,6 +965,7 @@
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 
 #
 # USB Input Devices
@@ -1013,6 +1022,7 @@
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
@@ -1070,16 +1080,60 @@
 #
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
-
-#
-# Real Time Clock
-#
+# CONFIG_NEW_LEDS is not set
 CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
 
 #
-# DMA Engine support
+# RTC interfaces
 #
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+CONFIG_RTC_DRV_RS5C372=y
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_INTEL_IOP_ADMA=y
 CONFIG_DMA_ENGINE=y
 
 #
@@ -1088,12 +1142,6 @@
 CONFIG_NET_DMA=y
 
 #
-# DMA Devices
-#
-# CONFIG_INTEL_IOATDMA is not set
-CONFIG_INTEL_IOP_ADMA=y
-
-#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1105,7 +1153,6 @@
 # CONFIG_EXT3_FS_SECURITY is not set
 # CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -1145,7 +1192,6 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1162,10 +1208,12 @@
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 # CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
@@ -1174,10 +1222,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -1224,26 +1269,17 @@
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
-
-#
-# Profiling support
-#
+CONFIG_INSTRUMENTATION=y
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
@@ -1270,10 +1306,13 @@
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_ERRORS is not set
 CONFIG_DEBUG_LL=y
@@ -1285,6 +1324,7 @@
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_XOR_BLOCKS=y
 CONFIG_ASYNC_CORE=y
 CONFIG_ASYNC_MEMCPY=y
@@ -1309,6 +1349,7 @@
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_LRW=y
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -1323,11 +1364,13 @@
 CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_KHAZAD=y
 CONFIG_CRYPTO_ANUBIS=y
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_CRC32C=y
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
 CONFIG_CRYPTO_HW=y
 
 #
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
index 721ee64..917afb5 100644
--- a/arch/arm/configs/iop33x_defconfig
+++ b/arch/arm/configs/iop33x_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22
-# Thu Jul 19 16:05:59 2007
+# Linux kernel version: 2.6.24-rc5
+# Wed Dec 12 16:11:27 2007
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -26,15 +26,11 @@
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
@@ -45,9 +41,14 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -69,7 +70,6 @@
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -130,6 +130,7 @@
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
@@ -150,6 +151,14 @@
 #
 CONFIG_ARCH_IQ80331=y
 CONFIG_MACH_IQ80332=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
 CONFIG_PLAT_IOP=y
 
 #
@@ -179,11 +188,8 @@
 CONFIG_PCI=y
 CONFIG_PCI_SYSCALL=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 
 #
@@ -202,6 +208,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
 # CONFIG_RESOURCES_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
@@ -241,6 +248,7 @@
 # Power management options
 #
 # CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
 
 #
 # Networking
@@ -279,6 +287,7 @@
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -318,10 +327,6 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 # CONFIG_NET_SCHED is not set
 
 #
@@ -350,6 +355,7 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -379,6 +385,7 @@
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -419,6 +426,7 @@
 CONFIG_MTD_PHYSMAP_LEN=0x0
 CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -459,6 +467,11 @@
 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 # CONFIG_IDE is not set
 
 #
@@ -496,12 +509,9 @@
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -512,6 +522,7 @@
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
@@ -552,14 +563,8 @@
 # CONFIG_DM_ZERO is not set
 # CONFIG_DM_MULTIPATH is not set
 # CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
+# CONFIG_DM_UEVENT is not set
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -574,6 +579,8 @@
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
 # CONFIG_NET_ETHERNET is not set
 CONFIG_NETDEV_1000=y
@@ -582,6 +589,7 @@
 CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -589,6 +597,7 @@
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -597,11 +606,14 @@
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
 # CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
@@ -636,7 +648,6 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
@@ -685,12 +696,10 @@
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
@@ -755,9 +764,9 @@
 # CONFIG_SPI is not set
 # CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -765,12 +774,13 @@
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
 # CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -784,14 +794,17 @@
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -803,11 +816,13 @@
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_TIFM_CORE is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -815,19 +830,6 @@
 # CONFIG_MFD_SM501 is not set
 
 #
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -837,14 +839,16 @@
 #
 # Graphics support
 #
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_FB is not set
 
 #
 # Console display driver support
@@ -859,6 +863,7 @@
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -874,16 +879,15 @@
 #
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
-
-#
-# Real Time Clock
-#
+# CONFIG_NEW_LEDS is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
+CONFIG_DMADEVICES=y
 
 #
-# DMA Engine support
+# DMA Devices
 #
+CONFIG_INTEL_IOP_ADMA=y
 CONFIG_DMA_ENGINE=y
 
 #
@@ -892,12 +896,6 @@
 CONFIG_NET_DMA=y
 
 #
-# DMA Devices
-#
-# CONFIG_INTEL_IOATDMA is not set
-CONFIG_INTEL_IOP_ADMA=y
-
-#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -909,7 +907,6 @@
 # CONFIG_EXT3_FS_SECURITY is not set
 # CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -949,7 +946,6 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -969,10 +965,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -1019,26 +1012,17 @@
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
-
-#
-# Profiling support
-#
+CONFIG_INSTRUMENTATION=y
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
@@ -1065,10 +1049,13 @@
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_ERRORS is not set
 CONFIG_DEBUG_LL=y
@@ -1079,6 +1066,7 @@
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_XOR_BLOCKS=y
 CONFIG_ASYNC_CORE=y
 CONFIG_ASYNC_MEMCPY=y
diff --git a/arch/arm/configs/littleton_defconfig b/arch/arm/configs/littleton_defconfig
new file mode 100644
index 0000000..1db4969
--- /dev/null
+++ b/arch/arm/configs/littleton_defconfig
@@ -0,0 +1,783 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24-rc5
+# Fri Dec 21 11:06:19 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+
+#
+# Supported PXA3xx Processor Variants
+#
+CONFIG_CPU_PXA300=y
+CONFIG_CPU_PXA310=y
+# CONFIG_CPU_PXA320 is not set
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_ZYLONITE is not set
+CONFIG_MACH_LITTLETON=y
+# CONFIG_MACH_ARMCORE is not set
+CONFIG_PXA3xx=y
+CONFIG_PXA_SSP=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSC3=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_IO_36=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS2,38400 mem=64M"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/msm_defconfig b/arch/arm/configs/msm_defconfig
new file mode 100644
index 0000000..ae4c5e6
--- /dev/null
+++ b/arch/arm/configs/msm_defconfig
@@ -0,0 +1,895 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.23
+# Wed Nov  7 01:36:45 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_GPIOS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_PANIC_TIMEOUT=0
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_GOLDFISH is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+CONFIG_ARCH_MSM7X00A=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# MSM7200 Board Type
+#
+CONFIG_MACH_HALIBUT=y
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+# CONFIG_SERIAL_MSM_NOINIT is not set
+CONFIG_MSM_SMD=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyMSM,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+CONFIG_MTD_MSM_NAND=y
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_GOLDFISH_NAND is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=y
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+CONFIG_MSM_RMNET=y
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GOLDFISH_EVENTS is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_MEP is not set
+CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI=y
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_UINPUT is not set
+CONFIG_INPUT_GPIO=y
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DCC_TTY=y
+# CONFIG_GOLDFISH_TTY is not set
+CONFIG_BINDER=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_MSM=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+CONFIG_SENSORS_PCA9633=y
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+CONFIG_SENSORS_AKM8976=y
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_HWMON is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_LOW_MEMORY_KILLER=y
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_MSM=y
+# CONFIG_FB_GOLDFISH is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# USB Function Support
+#
+CONFIG_USB_FUNCTION=y
+CONFIG_USB_FUNCTION_MSM_HSUSB=y
+# CONFIG_USB_FUNCTION_NULL is not set
+# CONFIG_USB_FUNCTION_ZERO is not set
+# CONFIG_USB_FUNCTION_LOOPBACK is not set
+CONFIG_USB_FUNCTION_ADB=y
+# CONFIG_MMC is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Android
+#
+# CONFIG_ANDROID_GADGET is not set
+# CONFIG_ANDROID_RAM_CONSOLE is not set
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_VIBRATOR=y
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_9BYTE_TAGS is not set
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/orion_defconfig b/arch/arm/configs/orion_defconfig
new file mode 100644
index 0000000..17a55de
--- /dev/null
+++ b/arch/arm/configs/orion_defconfig
@@ -0,0 +1,1384 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24-rc3
+# Wed Nov 28 15:13:57 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+CONFIG_ARCH_ORION=y
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Orion Implementations
+#
+CONFIG_MACH_DB88F5281=y
+CONFIG_MACH_RD88F5182=y
+CONFIG_MACH_KUROBOX_PRO=y
+CONFIG_MACH_DNS323=y
+CONFIG_MACH_TS209=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_FEROCEON=y
+CONFIG_CPU_FEROCEON_OLD_ID=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_FTL=y
+CONFIG_NFTL=y
+# CONFIG_NFTL_RW is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+CONFIG_MTD_CFI_I4=y
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_NAND_ORION=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+CONFIG_SCSI_MVSATA=y
+
+#
+# Sata options
+#
+# CONFIG_MV_SATA_SUPPORT_ATAPI is not set
+# CONFIG_MV_SATA_ENABLE_1MB_IOS is not set
+CONFIG_SATA_NO_DEBUG=y
+# CONFIG_SATA_DEBUG_ON_ERROR is not set
+# CONFIG_SATA_FULL_DEBUG is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+CONFIG_SKGE=y
+CONFIG_SKY2=y
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+CONFIG_MV643XX_ETH=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+CONFIG_I2C_MV64XXX=y
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_SL811_HCD=y
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+CONFIG_USB_PRINTER=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+# CONFIG_USB_STORAGE_ISD200 is not set
+CONFIG_USB_STORAGE_DPCM=y
+# CONFIG_USB_STORAGE_USBAT is not set
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_GPIO is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+CONFIG_RTC_DRV_RS5C372=y
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+CONFIG_RTC_DRV_M41T80=y
+# CONFIG_RTC_DRV_M41T80_WDT is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LDM_DEBUG=y
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+CONFIG_INSTRUMENTATION=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_USER=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig
new file mode 100644
index 0000000..17b9b24
--- /dev/null
+++ b/arch/arm/configs/pcm027_defconfig
@@ -0,0 +1,1096 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24-rc6
+# Fri Dec 21 10:52:09 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_ARMCORE is not set
+CONFIG_MACH_PCM027=y
+CONFIG_MACH_PCM990_BASEBOARD=y
+CONFIG_PXA27x=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x00000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PXA2XX is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+CONFIG_SENSORS_EEPROM=y
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_PXA2XX_PCM=y
+CONFIG_SND_PXA2XX_AC97=y
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+CONFIG_RTC_DRV_PCF8563=m
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=m
+CONFIG_FS_MBCACHE=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_NFS_DIRECTIO=y
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 593b565..faa7619 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -19,6 +19,7 @@
 obj-$(CONFIG_PCI)		+= bios32.o isa.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_KPROBES)		+= kprobes.o kprobes-decode.o
 obj-$(CONFIG_OABI_COMPAT)	+= sys_oabi-compat.o
 
 obj-$(CONFIG_CRUNCH)		+= crunch.o crunch-bits.o
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index 0a3e9ad..2f080a3 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -216,7 +216,7 @@
 
 		request_dma(DMA_ISA_CASCADE, "cascade");
 
-		for (i = 0; i < sizeof(dma_resources) / sizeof(dma_resources[0]); i++)
+		for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
 			request_resource(&ioport_resource, dma_resources + i);
 	}
 }
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 29dec08..a46d5b4 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -11,8 +11,8 @@
  *
  *  Low-level vector interface routines
  *
- *  Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
- *  it to save wrong values...  Be aware!
+ *  Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction
+ *  that causes it to save wrong values...  Be aware!
  */
 
 #include <asm/memory.h>
@@ -58,6 +58,12 @@
 
 	.endm
 
+#ifdef CONFIG_KPROBES
+	.section	.kprobes.text,"ax",%progbits
+#else
+	.text
+#endif
+
 /*
  * Invalid mode handlers
  */
@@ -112,8 +118,8 @@
 #define SPFIX(code...)
 #endif
 
-	.macro	svc_entry
-	sub	sp, sp, #S_FRAME_SIZE
+	.macro	svc_entry, stack_hole=0
+	sub	sp, sp, #(S_FRAME_SIZE + \stack_hole)
  SPFIX(	tst	sp, #4		)
  SPFIX(	bicne	sp, sp, #4	)
 	stmib	sp, {r1 - r12}
@@ -121,7 +127,7 @@
 	ldmia	r0, {r1 - r3}
 	add	r5, sp, #S_SP		@ here for interlock avoidance
 	mov	r4, #-1			@  ""  ""      ""       ""
-	add	r0, sp, #S_FRAME_SIZE   @  ""  ""      ""       ""
+	add	r0, sp, #(S_FRAME_SIZE + \stack_hole)
  SPFIX(	addne	r0, r0, #4	)
 	str	r1, [sp]		@ save the "real" r0 copied
 					@ from the exception stack
@@ -242,7 +248,14 @@
 
 	.align	5
 __und_svc:
+#ifdef CONFIG_KPROBES
+	@ If a kprobe is about to simulate a "stmdb sp..." instruction,
+	@ it obviously needs free stack space which then will belong to
+	@ the saved context.
+	svc_entry 64
+#else
 	svc_entry
+#endif
 
 	@
 	@ call emulation code, which returns using r9 if it has emulated
@@ -480,6 +493,13 @@
  * co-processor instructions.  However, we have to watch out
  * for the ARM6/ARM7 SWI bug.
  *
+ * NEON is a special case that has to be handled here. Not all
+ * NEON instructions are co-processor instructions, so we have
+ * to make a special case of checking for them. Plus, there's
+ * five groups of them, so we have a table of mask/opcode pairs
+ * to check against, and if any match then we branch off into the
+ * NEON handler code.
+ *
  * Emulators may wish to make use of the following registers:
  *  r0  = instruction opcode.
  *  r2  = PC+4
@@ -488,6 +508,23 @@
  *  lr  = unrecognised instruction return address
  */
 call_fpe:
+#ifdef CONFIG_NEON
+	adr	r6, .LCneon_opcodes
+2:
+	ldr	r7, [r6], #4			@ mask value
+	cmp	r7, #0				@ end mask?
+	beq	1f
+	and	r8, r0, r7
+	ldr	r7, [r6], #4			@ opcode bits matching in mask
+	cmp	r8, r7				@ NEON instruction?
+	bne	2b
+	get_thread_info r10
+	mov	r7, #1
+	strb	r7, [r10, #TI_USED_CP + 10]	@ mark CP#10 as used
+	strb	r7, [r10, #TI_USED_CP + 11]	@ mark CP#11 as used
+	b	do_vfp				@ let VFP handler handle this
+1:
+#endif
 	tst	r0, #0x08000000			@ only CDP/CPRT/LDC/STC have bit 27
 #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
 	and	r8, r0, #0x0f000000		@ mask out op-code bits
@@ -537,6 +574,20 @@
 	mov	pc, lr				@ CP#14 (Debug)
 	mov	pc, lr				@ CP#15 (Control)
 
+#ifdef CONFIG_NEON
+	.align	6
+
+.LCneon_opcodes:
+	.word	0xfe000000			@ mask
+	.word	0xf2000000			@ opcode
+
+	.word	0xff100000			@ mask
+	.word	0xf4000000			@ opcode
+
+	.word	0x00000000			@ mask
+	.word	0x00000000			@ opcode
+#endif
+
 do_fpe:
 	enable_irq
 	ldr	r4, .LCfp
@@ -555,7 +606,7 @@
 	.data
 ENTRY(fp_enter)
 	.word	no_fp
-	.text
+	.previous
 
 no_fp:	mov	pc, lr
 
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 33e6cc2..6c90c50 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -72,7 +72,7 @@
 	ldr	r1, [sp, #S_PSR]		@ get calling cpsr
 	ldr	lr, [sp, #S_PC]!		@ get pc
 	msr	spsr_cxsf, r1			@ save in spsr_svc
-	ldmdb	sp, {r0 - lr}^			@ get calling r1 - lr
+	ldmdb	sp, {r0 - lr}^			@ get calling r0 - lr
 	mov	r0, r0
 	add	sp, sp, #S_FRAME_SIZE - S_PC
 	movs	pc, lr				@ return & move spsr_svc into cpsr
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
new file mode 100644
index 0000000..d51bc8b
--- /dev/null
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -0,0 +1,1529 @@
+/*
+ * arch/arm/kernel/kprobes-decode.c
+ *
+ * Copyright (C) 2006, 2007 Motorola Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+/*
+ * We do not have hardware single-stepping on ARM, This
+ * effort is further complicated by the ARM not having a
+ * "next PC" register.  Instructions that change the PC
+ * can't be safely single-stepped in a MP environment, so
+ * we have a lot of work to do:
+ *
+ * In the prepare phase:
+ *   *) If it is an instruction that does anything
+ *      with the CPU mode, we reject it for a kprobe.
+ *      (This is out of laziness rather than need.  The
+ *      instructions could be simulated.)
+ *
+ *   *) Otherwise, decode the instruction rewriting its
+ *      registers to take fixed, ordered registers and
+ *      setting a handler for it to run the instruction.
+ *
+ * In the execution phase by an instruction's handler:
+ *
+ *   *) If the PC is written to by the instruction, the
+ *      instruction must be fully simulated in software.
+ *      If it is a conditional instruction, the handler
+ *      will use insn[0] to copy its condition code to
+ *	set r0 to 1 and insn[1] to "mov pc, lr" to return.
+ *
+ *   *) Otherwise, a modified form of the instruction is
+ *      directly executed.  Its handler calls the
+ *      instruction in insn[0].  In insn[1] is a
+ *      "mov pc, lr" to return.
+ *
+ *      Before calling, load up the reordered registers
+ *      from the original instruction's registers.  If one
+ *      of the original input registers is the PC, compute
+ *      and adjust the appropriate input register.
+ *
+ *	After call completes, copy the output registers to
+ *      the original instruction's original registers.
+ *
+ * We don't use a real breakpoint instruction since that
+ * would have us in the kernel go from SVC mode to SVC
+ * mode losing the link register.  Instead we use an
+ * undefined instruction.  To simplify processing, the
+ * undefined instruction used for kprobes must be reserved
+ * exclusively for kprobes use.
+ *
+ * TODO: ifdef out some instruction decoding based on architecture.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kprobes.h>
+
+#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
+
+#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
+
+#define PSR_fs	(PSR_f|PSR_s)
+
+#define KPROBE_RETURN_INSTRUCTION	0xe1a0f00e	/* mov pc, lr */
+#define SET_R0_TRUE_INSTRUCTION		0xe3a00001	/* mov	r0, #1 */
+
+#define	truecc_insn(insn)	(((insn) & 0xf0000000) | \
+				 (SET_R0_TRUE_INSTRUCTION & 0x0fffffff))
+
+typedef long (insn_0arg_fn_t)(void);
+typedef long (insn_1arg_fn_t)(long);
+typedef long (insn_2arg_fn_t)(long, long);
+typedef long (insn_3arg_fn_t)(long, long, long);
+typedef long (insn_4arg_fn_t)(long, long, long, long);
+typedef long long (insn_llret_0arg_fn_t)(void);
+typedef long long (insn_llret_3arg_fn_t)(long, long, long);
+typedef long long (insn_llret_4arg_fn_t)(long, long, long, long);
+
+union reg_pair {
+	long long	dr;
+#ifdef __LITTLE_ENDIAN
+	struct { long	r0, r1; };
+#else
+	struct { long	r1, r0; };
+#endif
+};
+
+/*
+ * For STR and STM instructions, an ARM core may choose to use either
+ * a +8 or a +12 displacement from the current instruction's address.
+ * Whichever value is chosen for a given core, it must be the same for
+ * both instructions and may not change.  This function measures it.
+ */
+
+static int str_pc_offset;
+
+static void __init find_str_pc_offset(void)
+{
+	int addr, scratch, ret;
+
+	__asm__ (
+		"sub	%[ret], pc, #4		\n\t"
+		"str	pc, %[addr]		\n\t"
+		"ldr	%[scr], %[addr]		\n\t"
+		"sub	%[ret], %[scr], %[ret]	\n\t"
+		: [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
+
+	str_pc_offset = ret;
+}
+
+/*
+ * The insnslot_?arg_r[w]flags() functions below are to keep the
+ * msr -> *fn -> mrs instruction sequences indivisible so that
+ * the state of the CPSR flags aren't inadvertently modified
+ * just before or just after the call.
+ */
+
+static inline long __kprobes
+insnslot_0arg_rflags(long cpsr, insn_0arg_fn_t *fn)
+{
+	register long ret asm("r0");
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		: "=r" (ret)
+		: [cpsr] "r" (cpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	return ret;
+}
+
+static inline long long __kprobes
+insnslot_llret_0arg_rflags(long cpsr, insn_llret_0arg_fn_t *fn)
+{
+	register long ret0 asm("r0");
+	register long ret1 asm("r1");
+	union reg_pair fnr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		: "=r" (ret0), "=r" (ret1)
+		: [cpsr] "r" (cpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	fnr.r0 = ret0;
+	fnr.r1 = ret1;
+	return fnr.dr;
+}
+
+static inline long __kprobes
+insnslot_1arg_rflags(long r0, long cpsr, insn_1arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long ret asm("r0");
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		: "=r" (ret)
+		: "0" (rr0), [cpsr] "r" (cpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	return ret;
+}
+
+static inline long __kprobes
+insnslot_2arg_rflags(long r0, long r1, long cpsr, insn_2arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long rr1 asm("r1") = r1;
+	register long ret asm("r0");
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		: "=r" (ret)
+		: "0" (rr0), "r" (rr1),
+		  [cpsr] "r" (cpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	return ret;
+}
+
+static inline long __kprobes
+insnslot_3arg_rflags(long r0, long r1, long r2, long cpsr, insn_3arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long rr1 asm("r1") = r1;
+	register long rr2 asm("r2") = r2;
+	register long ret asm("r0");
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		: "=r" (ret)
+		: "0" (rr0), "r" (rr1), "r" (rr2),
+		  [cpsr] "r" (cpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	return ret;
+}
+
+static inline long long __kprobes
+insnslot_llret_3arg_rflags(long r0, long r1, long r2, long cpsr,
+			   insn_llret_3arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long rr1 asm("r1") = r1;
+	register long rr2 asm("r2") = r2;
+	register long ret0 asm("r0");
+	register long ret1 asm("r1");
+	union reg_pair fnr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		: "=r" (ret0), "=r" (ret1)
+		: "0" (rr0), "r" (rr1), "r" (rr2),
+		  [cpsr] "r" (cpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	fnr.r0 = ret0;
+	fnr.r1 = ret1;
+	return fnr.dr;
+}
+
+static inline long __kprobes
+insnslot_4arg_rflags(long r0, long r1, long r2, long r3, long cpsr,
+		     insn_4arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long rr1 asm("r1") = r1;
+	register long rr2 asm("r2") = r2;
+	register long rr3 asm("r3") = r3;
+	register long ret asm("r0");
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[cpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		: "=r" (ret)
+		: "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
+		  [cpsr] "r" (cpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	return ret;
+}
+
+static inline long __kprobes
+insnslot_1arg_rwflags(long r0, long *cpsr, insn_1arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long ret asm("r0");
+	long oldcpsr = *cpsr;
+	long newcpsr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[oldcpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		"mrs	%[newcpsr], cpsr	\n\t"
+		: "=r" (ret), [newcpsr] "=r" (newcpsr)
+		: "0" (rr0), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+	return ret;
+}
+
+static inline long __kprobes
+insnslot_2arg_rwflags(long r0, long r1, long *cpsr, insn_2arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long rr1 asm("r1") = r1;
+	register long ret asm("r0");
+	long oldcpsr = *cpsr;
+	long newcpsr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[oldcpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		"mrs	%[newcpsr], cpsr	\n\t"
+		: "=r" (ret), [newcpsr] "=r" (newcpsr)
+		: "0" (rr0), "r" (rr1), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+	return ret;
+}
+
+static inline long __kprobes
+insnslot_3arg_rwflags(long r0, long r1, long r2, long *cpsr,
+		      insn_3arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long rr1 asm("r1") = r1;
+	register long rr2 asm("r2") = r2;
+	register long ret asm("r0");
+	long oldcpsr = *cpsr;
+	long newcpsr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[oldcpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		"mrs	%[newcpsr], cpsr	\n\t"
+		: "=r" (ret), [newcpsr] "=r" (newcpsr)
+		: "0" (rr0), "r" (rr1), "r" (rr2),
+		  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+	return ret;
+}
+
+static inline long __kprobes
+insnslot_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
+		      insn_4arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long rr1 asm("r1") = r1;
+	register long rr2 asm("r2") = r2;
+	register long rr3 asm("r3") = r3;
+	register long ret asm("r0");
+	long oldcpsr = *cpsr;
+	long newcpsr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[oldcpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		"mrs	%[newcpsr], cpsr	\n\t"
+		: "=r" (ret), [newcpsr] "=r" (newcpsr)
+		: "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
+		  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+	return ret;
+}
+
+static inline long long __kprobes
+insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
+			    insn_llret_4arg_fn_t *fn)
+{
+	register long rr0 asm("r0") = r0;
+	register long rr1 asm("r1") = r1;
+	register long rr2 asm("r2") = r2;
+	register long rr3 asm("r3") = r3;
+	register long ret0 asm("r0");
+	register long ret1 asm("r1");
+	long oldcpsr = *cpsr;
+	long newcpsr;
+	union reg_pair fnr;
+
+	__asm__ __volatile__ (
+		"msr	cpsr_fs, %[oldcpsr]	\n\t"
+		"mov	lr, pc			\n\t"
+		"mov	pc, %[fn]		\n\t"
+		"mrs	%[newcpsr], cpsr	\n\t"
+		: "=r" (ret0), "=r" (ret1), [newcpsr] "=r" (newcpsr)
+		: "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
+		  [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+		: "lr", "cc"
+	);
+	*cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+	fnr.r0 = ret0;
+	fnr.r1 = ret1;
+	return fnr.dr;
+}
+
+/*
+ * To avoid the complications of mimicing single-stepping on a
+ * processor without a Next-PC or a single-step mode, and to
+ * avoid having to deal with the side-effects of boosting, we
+ * simulate or emulate (almost) all ARM instructions.
+ *
+ * "Simulation" is where the instruction's behavior is duplicated in
+ * C code.  "Emulation" is where the original instruction is rewritten
+ * and executed, often by altering its registers.
+ *
+ * By having all behavior of the kprobe'd instruction completed before
+ * returning from the kprobe_handler(), all locks (scheduler and
+ * interrupt) can safely be released.  There is no need for secondary
+ * breakpoints, no race with MP or preemptable kernels, nor having to
+ * clean up resources counts at a later time impacting overall system
+ * performance.  By rewriting the instruction, only the minimum registers
+ * need to be loaded and saved back optimizing performance.
+ *
+ * Calling the insnslot_*_rwflags version of a function doesn't hurt
+ * anything even when the CPSR flags aren't updated by the
+ * instruction.  It's just a little slower in return for saving
+ * a little space by not having a duplicate function that doesn't
+ * update the flags.  (The same optimization can be said for
+ * instructions that do or don't perform register writeback)
+ * Also, instructions can either read the flags, only write the
+ * flags, or read and write the flags.  To save combinations
+ * rather than for sheer performance, flag functions just assume
+ * read and write of flags.
+ */
+
+static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	long iaddr = (long)p->addr;
+	int disp  = branch_displacement(insn);
+
+	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
+		return;
+
+	if (insn & (1 << 24))
+		regs->ARM_lr = iaddr + 4;
+
+	regs->ARM_pc = iaddr + 8 + disp;
+}
+
+static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = p->opcode;
+	long iaddr = (long)p->addr;
+	int disp = branch_displacement(insn);
+
+	regs->ARM_lr = iaddr + 4;
+	regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
+	regs->ARM_cpsr |= PSR_T_BIT;
+}
+
+static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rm = insn & 0xf;
+	long rmv = regs->uregs[rm];
+
+	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
+		return;
+
+	if (insn & (1 << 5))
+		regs->ARM_lr = (long)p->addr + 4;
+
+	regs->ARM_pc = rmv & ~0x1;
+	regs->ARM_cpsr &= ~PSR_T_BIT;
+	if (rmv & 0x1)
+		regs->ARM_cpsr |= PSR_T_BIT;
+}
+
+static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rn = (insn >> 16) & 0xf;
+	int lbit = insn & (1 << 20);
+	int wbit = insn & (1 << 21);
+	int ubit = insn & (1 << 23);
+	int pbit = insn & (1 << 24);
+	long *addr = (long *)regs->uregs[rn];
+	int reg_bit_vector;
+	int reg_count;
+
+	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
+		return;
+
+	reg_count = 0;
+	reg_bit_vector = insn & 0xffff;
+	while (reg_bit_vector) {
+		reg_bit_vector &= (reg_bit_vector - 1);
+		++reg_count;
+	}
+
+	if (!ubit)
+		addr -= reg_count;
+	addr += (!pbit ^ !ubit);
+
+	reg_bit_vector = insn & 0xffff;
+	while (reg_bit_vector) {
+		int reg = __ffs(reg_bit_vector);
+		reg_bit_vector &= (reg_bit_vector - 1);
+		if (lbit)
+			regs->uregs[reg] = *addr++;
+		else
+			*addr++ = regs->uregs[reg];
+	}
+
+	if (wbit) {
+		if (!ubit)
+			addr -= reg_count;
+		addr -= (!pbit ^ !ubit);
+		regs->uregs[rn] = (long)addr;
+	}
+}
+
+static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+
+	if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
+		return;
+
+	regs->ARM_pc = (long)p->addr + str_pc_offset;
+	simulate_ldm1stm1(p, regs);
+	regs->ARM_pc = (long)p->addr + 4;
+}
+
+static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
+{
+	regs->uregs[12] = regs->uregs[13];
+}
+
+static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rn = (insn >> 16) & 0xf;
+	long rnv = regs->uregs[rn];
+
+	/* Save Rn in case of writeback. */
+	regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;  /* rm may be invalid, don't care. */
+
+	/* Not following the C calling convention here, so need asm(). */
+	__asm__ __volatile__ (
+		"ldr	r0, %[rn]	\n\t"
+		"ldr	r1, %[rm]	\n\t"
+		"msr	cpsr_fs, %[cpsr]\n\t"
+		"mov	lr, pc		\n\t"
+		"mov	pc, %[i_fn]	\n\t"
+		"str	r0, %[rn]	\n\t"	/* in case of writeback */
+		"str	r2, %[rd0]	\n\t"
+		"str	r3, %[rd1]	\n\t"
+		: [rn]  "+m" (regs->uregs[rn]),
+		  [rd0] "=m" (regs->uregs[rd]),
+		  [rd1] "=m" (regs->uregs[rd+1])
+		: [rm]   "m" (regs->uregs[rm]),
+		  [cpsr] "r" (regs->ARM_cpsr),
+		  [i_fn] "r" (i_fn)
+		: "r0", "r1", "r2", "r3", "lr", "cc"
+	);
+}
+
+static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm  = insn & 0xf;
+	long rnv = regs->uregs[rn];
+	long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
+
+	regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
+					       regs->uregs[rd+1],
+					       regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	union reg_pair fnr;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;
+	long rdv;
+	long rnv  = regs->uregs[rn];
+	long rmv  = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
+	long cpsr = regs->ARM_cpsr;
+
+	fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
+	regs->uregs[rn] = fnr.r0;  /* Save Rn in case of writeback. */
+	rdv = fnr.r1;
+
+	if (rd == 15) {
+#if __LINUX_ARM_ARCH__ >= 5
+		cpsr &= ~PSR_T_BIT;
+		if (rdv & 0x1)
+			cpsr |= PSR_T_BIT;
+		regs->ARM_cpsr = cpsr;
+		rdv &= ~0x1;
+#else
+		rdv &= ~0x2;
+#endif
+	}
+	regs->uregs[rd] = rdv;
+}
+
+static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	long iaddr = (long)p->addr;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;
+	long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
+	long rnv = (rn == 15) ? iaddr +  8 : regs->uregs[rn];
+	long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
+
+	/* Save Rn in case of writeback. */
+	regs->uregs[rn] =
+		insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	union reg_pair fnr;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+
+	fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn);
+	regs->uregs[rn] = fnr.r0;
+	regs->uregs[rd] = fnr.r1;
+}
+
+static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	long rnv = regs->uregs[rn];
+	long rdv = regs->uregs[rd];
+
+	insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rm = insn & 0xf;
+	long rmv = regs->uregs[rm];
+
+	/* Writes Q flag */
+	regs->uregs[rd] = insnslot_1arg_rwflags(rmv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_sel(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;
+	long rnv = regs->uregs[rn];
+	long rmv = regs->uregs[rm];
+
+	/* Reads GE bits */
+	regs->uregs[rd] = insnslot_2arg_rflags(rnv, rmv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
+
+	insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+
+	regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int ird = (insn >> 12) & 0xf;
+
+	insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rn = (insn >> 16) & 0xf;
+	long rnv = regs->uregs[rn];
+
+	insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rm = insn & 0xf;
+	long rmv = regs->uregs[rm];
+
+	regs->uregs[rd] = insnslot_1arg_rflags(rmv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_rd12rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	int rm = insn & 0xf;
+	long rnv = regs->uregs[rn];
+	long rmv = regs->uregs[rm];
+
+	regs->uregs[rd] =
+		insnslot_2arg_rwflags(rnv, rmv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_rd16rn12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 16) & 0xf;
+	int rn = (insn >> 12) & 0xf;
+	int rs = (insn >> 8) & 0xf;
+	int rm = insn & 0xf;
+	long rnv = regs->uregs[rn];
+	long rsv = regs->uregs[rs];
+	long rmv = regs->uregs[rm];
+
+	regs->uregs[rd] =
+		insnslot_3arg_rwflags(rnv, rsv, rmv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_rd16rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 16) & 0xf;
+	int rs = (insn >> 8) & 0xf;
+	int rm = insn & 0xf;
+	long rsv = regs->uregs[rs];
+	long rmv = regs->uregs[rm];
+
+	regs->uregs[rd] =
+		insnslot_2arg_rwflags(rsv, rmv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_rdhi16rdlo12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_llret_4arg_fn_t *i_fn = (insn_llret_4arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	union reg_pair fnr;
+	int rdhi = (insn >> 16) & 0xf;
+	int rdlo = (insn >> 12) & 0xf;
+	int rs   = (insn >> 8) & 0xf;
+	int rm   = insn & 0xf;
+	long rsv = regs->uregs[rs];
+	long rmv = regs->uregs[rm];
+
+	fnr.dr = insnslot_llret_4arg_rwflags(regs->uregs[rdhi],
+					     regs->uregs[rdlo], rsv, rmv,
+					     &regs->ARM_cpsr, i_fn);
+	regs->uregs[rdhi] = fnr.r0;
+	regs->uregs[rdlo] = fnr.r1;
+}
+
+static void __kprobes
+emulate_alu_imm_rflags(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
+
+	regs->uregs[rd] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;
+	long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
+
+	regs->uregs[rd] = insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	long ppc = (long)p->addr + 8;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;	/* rn/rnv/rs/rsv may be */
+	int rs = (insn >> 8) & 0xf;	/* invalid, don't care. */
+	int rm = insn & 0xf;
+	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+	long rsv = regs->uregs[rs];
+
+	regs->uregs[rd] =
+		insnslot_3arg_rflags(rnv, rmv, rsv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+	insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+	kprobe_opcode_t insn = p->opcode;
+	long ppc = (long)p->addr + 8;
+	int rd = (insn >> 12) & 0xf;
+	int rn = (insn >> 16) & 0xf;	/* rn/rnv/rs/rsv may be */
+	int rs = (insn >> 8) & 0xf;	/* invalid, don't care. */
+	int rm = insn & 0xf;
+	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+	long rsv = regs->uregs[rs];
+
+	regs->uregs[rd] =
+		insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	int ibit = (insn & (1 << 26)) ? 25 : 22;
+
+	insn &= 0xfff00fff;
+	insn |= 0x00001000;	/* Rn = r0, Rd = r1 */
+	if (insn & (1 << ibit)) {
+		insn &= ~0xf;
+		insn |= 2;	/* Rm = r2 */
+	}
+	asi->insn[0] = insn;
+	asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr : emulate_str;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	insn &= 0xffff0ff0;	/* Rd = r0, Rm = r0 */
+	asi->insn[0] = insn;
+	asi->insn_handler = emulate_rd12rm0;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	insn &= 0xffff0fff;	/* Rd = r0 */
+	asi->insn[0] = insn;
+	asi->insn_handler = emulate_rd12;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
+				struct arch_specific_insn *asi)
+{
+	insn &= 0xfff00ff0;	/* Rd = r0, Rn = r0 */
+	insn |= 0x00000001;	/* Rm = r1 */
+	asi->insn[0] = insn;
+	asi->insn_handler = emulate_rd12rn16rm0_rwflags;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
+			       struct arch_specific_insn *asi)
+{
+	insn &= 0xfff0f0f0;	/* Rd = r0, Rs = r0 */
+	insn |= 0x00000001;	/* Rm = r1          */
+	asi->insn[0] = insn;
+	asi->insn_handler = emulate_rd16rs8rm0_rwflags;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
+				   struct arch_specific_insn *asi)
+{
+	insn &= 0xfff000f0;	/* Rd = r0, Rn = r0 */
+	insn |= 0x00000102;	/* Rs = r1, Rm = r2 */
+	asi->insn[0] = insn;
+	asi->insn_handler = emulate_rd16rn12rs8rm0_rwflags;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
+				       struct arch_specific_insn *asi)
+{
+	insn &= 0xfff000f0;	/* RdHi = r0, RdLo = r1 */
+	insn |= 0x00001203;	/* Rs = r2, Rm = r3 */
+	asi->insn[0] = insn;
+	asi->insn_handler = emulate_rdhi16rdlo12rs8rm0_rwflags;
+	return INSN_GOOD;
+}
+
+/*
+ * For the instruction masking and comparisons in all the "space_*"
+ * functions below, Do _not_ rearrange the order of tests unless
+ * you're very, very sure of what you are doing.  For the sake of
+ * efficiency, the masks for some tests sometimes assume other test
+ * have been done prior to them so the number of patterns to test
+ * for an instruction set can be as broad as possible to reduce the
+ * number of tests needed.
+ */
+
+static enum kprobe_insn __kprobes
+space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */
+	/* RFE           : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */
+	/* SRS           : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */
+	if ((insn & 0xfff30020) == 0xf1020000 ||
+	    (insn & 0xfe500f00) == 0xf8100a00 ||
+	    (insn & 0xfe5f0f00) == 0xf84d0500)
+		return INSN_REJECTED;
+
+	/* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */
+	if ((insn & 0xfd700000) == 0xf4500000) {
+		insn &= 0xfff0ffff;	/* Rn = r0 */
+		asi->insn[0] = insn;
+		asi->insn_handler = emulate_rn16;
+		return INSN_GOOD;
+	}
+
+	/* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */
+	if ((insn & 0xfe000000) == 0xfa000000) {
+		asi->insn_handler = simulate_blx1;
+		return INSN_GOOD_NO_SLOT;
+	}
+
+	/* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
+	/* CDP2   : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+	if ((insn & 0xffff00f0) == 0xf1010000 ||
+	    (insn & 0xff000010) == 0xfe000000) {
+		asi->insn[0] = insn;
+		asi->insn_handler = emulate_none;
+		return INSN_GOOD;
+	}
+
+	/* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
+	/* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
+	if ((insn & 0xffe00000) == 0xfc400000) {
+		insn &= 0xfff00fff;	/* Rn = r0 */
+		insn |= 0x00001000;	/* Rd = r1 */
+		asi->insn[0] = insn;
+		asi->insn_handler =
+			(insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
+		return INSN_GOOD;
+	}
+
+	/* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+	/* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+	if ((insn & 0xfe000000) == 0xfc000000) {
+		insn &= 0xfff0ffff;      /* Rn = r0 */
+		asi->insn[0] = insn;
+		asi->insn_handler = emulate_ldcstc;
+		return INSN_GOOD;
+	}
+
+	/* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+	/* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
+	insn &= 0xffff0fff;	/* Rd = r0 */
+	asi->insn[0]      = insn;
+	asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */
+	if ((insn & 0x0f900010) == 0x01000000) {
+
+		/* BXJ  : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
+		/* MSR  : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
+		if ((insn & 0x0ff000f0) == 0x01200020 ||
+		    (insn & 0x0fb000f0) == 0x01200000)
+			return INSN_REJECTED;
+
+		/* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */
+		if ((insn & 0x0fb00010) == 0x01000000)
+			return prep_emulate_rd12(insn, asi);
+
+		/* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
+		if ((insn & 0x0ff00090) == 0x01400080)
+			return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
+
+		/* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
+		/* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
+		if ((insn & 0x0ff000b0) == 0x012000a0 ||
+		    (insn & 0x0ff00090) == 0x01600080)
+			return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+
+		/* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */
+		/* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */
+		return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+
+	}
+
+	/* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */
+	else if ((insn & 0x0f900090) == 0x01000010) {
+
+		/* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
+		if ((insn & 0xfff000f0) == 0xe1200070)
+			return INSN_REJECTED;
+
+		/* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
+		/* BX     : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
+		if ((insn & 0x0ff000d0) == 0x01200010) {
+			asi->insn[0] = truecc_insn(insn);
+			asi->insn_handler = simulate_blx2bx;
+			return INSN_GOOD;
+		}
+
+		/* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
+		if ((insn & 0x0ff000f0) == 0x01600010)
+			return prep_emulate_rd12rm0(insn, asi);
+
+		/* QADD    : cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx :Q */
+		/* QSUB    : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */
+		/* QDADD   : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */
+		/* QDSUB   : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */
+		return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+	}
+
+	/* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */
+	else if ((insn & 0x0f000090) == 0x00000090) {
+
+		/* MUL    : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx :   */
+		/* MULS   : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */
+		/* MLA    : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx :   */
+		/* MLAS   : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */
+		/* UMAAL  : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx :   */
+		/* UMULL  : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx :   */
+		/* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */
+		/* UMLAL  : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx :   */
+		/* UMLALS : cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx :cc */
+		/* SMULL  : cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx :   */
+		/* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
+		/* SMLAL  : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx :   */
+		/* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
+		if ((insn & 0x0fe000f0) == 0x00000090) {
+		       return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+		} else if  ((insn & 0x0fe000f0) == 0x00200090) {
+		       return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+		} else {
+		       return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
+		}
+	}
+
+	/* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
+	else if ((insn & 0x0e000090) == 0x00000090) {
+
+		/* SWP   : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
+		/* SWPB  : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
+		/* LDRD  : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
+		/* STRD  : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
+		/* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
+		/* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
+		/* LDRH  : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
+		/* STRH  : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
+		/* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
+		/* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
+		if ((insn & 0x0fb000f0) == 0x01000090) {
+			/* SWP/SWPB */
+			return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+		} else if ((insn & 0x0e1000d0) == 0x00000d0) {
+			/* STRD/LDRD */
+			insn &= 0xfff00fff;
+			insn |= 0x00002000;	/* Rn = r0, Rd = r2 */
+			if (insn & (1 << 22)) {
+				/* I bit */
+				insn &= ~0xf;
+				insn |= 1;	/* Rm = r1 */
+			}
+			asi->insn[0] = insn;
+			asi->insn_handler =
+				(insn & (1 << 5)) ? emulate_strd : emulate_ldrd;
+			return INSN_GOOD;
+		}
+
+		return prep_emulate_ldr_str(insn, asi);
+	}
+
+	/* cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx xxxx */
+
+	/*
+	 * ALU op with S bit and Rd == 15 :
+	 * 	cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
+	 */
+	if ((insn & 0x0e10f000) == 0x0010f000)
+		return INSN_REJECTED;
+
+	/*
+	 * "mov ip, sp" is the most common kprobe'd instruction by far.
+	 * Check and optimize for it explicitly.
+	 */
+	if (insn == 0xe1a0c00d) {
+		asi->insn_handler = simulate_mov_ipsp;
+		return INSN_GOOD_NO_SLOT;
+	}
+
+	/*
+	 * Data processing: Immediate-shift / Register-shift
+	 * ALU op : cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx
+	 * CPY    : cccc 0001 1010 xxxx xxxx 0000 0000 xxxx
+	 * MOV    : cccc 0001 101x xxxx xxxx xxxx xxxx xxxx
+	 * *S (bit 20) updates condition codes
+	 * ADC/SBC/RSC reads the C flag
+	 */
+	insn &= 0xfff00ff0;	/* Rn = r0, Rd = r0 */
+	insn |= 0x00000001;	/* Rm = r1 */
+	if (insn & 0x010) {
+		insn &= 0xfffff0ff;     /* register shift */
+		insn |= 0x00000200;     /* Rs = r2 */
+	}
+	asi->insn[0] = insn;
+	asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
+				emulate_alu_rwflags : emulate_alu_rflags;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/*
+	 * MSR   : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
+	 * Undef : cccc 0011 0x00 xxxx xxxx xxxx xxxx xxxx
+	 * ALU op with S bit and Rd == 15 :
+	 *	   cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
+	 */
+	if ((insn & 0x0f900000) == 0x03200000 ||	/* MSR & Undef */
+	    (insn & 0x0e10f000) == 0x0210f000)		/* ALU s-bit, R15  */
+		return INSN_REJECTED;
+
+	/*
+	 * Data processing: 32-bit Immediate
+	 * ALU op : cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
+	 * MOV    : cccc 0011 101x xxxx xxxx xxxx xxxx xxxx
+	 * *S (bit 20) updates condition codes
+	 * ADC/SBC/RSC reads the C flag
+	 */
+	insn &= 0xfff00ff0;	/* Rn = r0, Rd = r0 */
+	asi->insn[0] = insn;
+	asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
+			emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */
+	if ((insn & 0x0ff000f0) == 0x068000b0) {
+		insn &= 0xfff00ff0;	/* Rd = r0, Rn = r0 */
+		insn |= 0x00000001;	/* Rm = r1 */
+		asi->insn[0] = insn;
+		asi->insn_handler = emulate_sel;
+		return INSN_GOOD;
+	}
+
+	/* SSAT   : cccc 0110 101x xxxx xxxx xxxx xx01 xxxx :Q */
+	/* USAT   : cccc 0110 111x xxxx xxxx xxxx xx01 xxxx :Q */
+	/* SSAT16 : cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx :Q */
+	/* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */
+	if ((insn & 0x0fa00030) == 0x06a00010 ||
+	    (insn & 0x0fb000f0) == 0x06a00030) {
+		insn &= 0xffff0ff0;	/* Rd = r0, Rm = r0 */
+		asi->insn[0] = insn;
+		asi->insn_handler = emulate_sat;
+		return INSN_GOOD;
+	}
+
+	/* REV    : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
+	/* REV16  : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
+	/* REVSH  : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
+	if ((insn & 0x0ff00070) == 0x06b00030 ||
+	    (insn & 0x0ff000f0) == 0x06f000b0)
+		return prep_emulate_rd12rm0(insn, asi);
+
+	/* SADD16    : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
+	/* SADDSUBX  : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */
+	/* SSUBADDX  : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */
+	/* SSUB16    : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */
+	/* SADD8     : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */
+	/* SSUB8     : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */
+	/* QADD16    : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx :   */
+	/* QADDSUBX  : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx :   */
+	/* QSUBADDX  : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx :   */
+	/* QSUB16    : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx :   */
+	/* QADD8     : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx :   */
+	/* QSUB8     : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx :   */
+	/* SHADD16   : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx :   */
+	/* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx :   */
+	/* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx :   */
+	/* SHSUB16   : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx :   */
+	/* SHADD8    : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx :   */
+	/* SHSUB8    : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx :   */
+	/* UADD16    : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */
+	/* UADDSUBX  : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */
+	/* USUBADDX  : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */
+	/* USUB16    : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */
+	/* UADD8     : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */
+	/* USUB8     : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */
+	/* UQADD16   : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx :   */
+	/* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx :   */
+	/* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx :   */
+	/* UQSUB16   : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx :   */
+	/* UQADD8    : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx :   */
+	/* UQSUB8    : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx :   */
+	/* UHADD16   : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx :   */
+	/* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx :   */
+	/* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx :   */
+	/* UHSUB16   : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx :   */
+	/* UHADD8    : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx :   */
+	/* UHSUB8    : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx :   */
+	/* PKHBT     : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx :   */
+	/* PKHTB     : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx :   */
+	/* SXTAB16   : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx :   */
+	/* SXTB      : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx :   */
+	/* SXTAB     : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx :   */
+	/* SXTAH     : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx :   */
+	/* UXTAB16   : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx :   */
+	/* UXTAB     : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx :   */
+	/* UXTAH     : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx :   */
+	return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* Undef : cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
+	if ((insn & 0x0ff000f0) == 0x03f000f0)
+		return INSN_REJECTED;
+
+	/* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
+	/* USAD8  : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
+	if ((insn & 0x0ff000f0) == 0x07800010)
+		 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+
+	/* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
+	/* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
+	if ((insn & 0x0ff00090) == 0x07400010)
+		return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
+
+	/* SMLAD  : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */
+	/* SMLSD  : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */
+	/* SMMLA  : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx :  */
+	/* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
+	if ((insn & 0x0ff00090) == 0x07000010 ||
+	    (insn & 0x0ff000d0) == 0x07500010 ||
+	    (insn & 0x0ff000d0) == 0x075000d0)
+		return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+
+	/* SMUSD  : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :  */
+	/* SMUAD  : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
+	/* SMMUL  : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx :  */
+	return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* LDR   : cccc 01xx x0x1 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRB  : cccc 01xx x1x1 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRBT : cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
+	/* LDRT  : cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
+	/* STR   : cccc 01xx x0x0 xxxx xxxx xxxx xxxx xxxx */
+	/* STRB  : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
+	/* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
+	/* STRT  : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
+	return prep_emulate_ldr_str(insn, asi);
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* LDM(2) : cccc 100x x101 xxxx 0xxx xxxx xxxx xxxx */
+	/* LDM(3) : cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
+	if ((insn & 0x0e708000) == 0x85000000 ||
+	    (insn & 0x0e508000) == 0x85010000)
+		return INSN_REJECTED;
+
+	/* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
+	/* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
+	asi->insn[0] = truecc_insn(insn);
+	asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
+				simulate_stm1_pc : simulate_ldm1stm1;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* B  : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
+	/* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
+	asi->insn[0] = truecc_insn(insn);
+	asi->insn_handler = simulate_bbl;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
+	/* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
+	insn &= 0xfff00fff;
+	insn |= 0x00001000;	/* Rn = r0, Rd = r1 */
+	asi->insn[0] = insn;
+	asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+	/* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+	insn &= 0xfff0ffff;	/* Rn = r0 */
+	asi->insn[0] = insn;
+	asi->insn_handler = emulate_ldcstc;
+	return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
+	/* SWI  : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
+	if ((insn & 0xfff000f0) == 0xe1200070 ||
+	    (insn & 0x0f000000) == 0x0f000000)
+		return INSN_REJECTED;
+
+	/* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+	if ((insn & 0x0f000010) == 0x0e000000) {
+		asi->insn[0] = insn;
+		asi->insn_handler = emulate_none;
+		return INSN_GOOD;
+	}
+
+	/* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+	/* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
+	insn &= 0xffff0fff;	/* Rd = r0 */
+	asi->insn[0] = insn;
+	asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
+	return INSN_GOOD;
+}
+
+/* Return:
+ *   INSN_REJECTED     If instruction is one not allowed to kprobe,
+ *   INSN_GOOD         If instruction is supported and uses instruction slot,
+ *   INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
+ *
+ * For instructions we don't want to kprobe (INSN_REJECTED return result):
+ *   These are generally ones that modify the processor state making
+ *   them "hard" to simulate such as switches processor modes or
+ *   make accesses in alternate modes.  Any of these could be simulated
+ *   if the work was put into it, but low return considering they
+ *   should also be very rare.
+ */
+enum kprobe_insn __kprobes
+arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
+
+	if ((insn & 0xf0000000) == 0xf0000000) {
+
+		return space_1111(insn, asi);
+
+	} else if ((insn & 0x0e000000) == 0x00000000) {
+
+		return space_cccc_000x(insn, asi);
+
+	} else if ((insn & 0x0e000000) == 0x02000000) {
+
+		return space_cccc_001x(insn, asi);
+
+	} else if ((insn & 0x0f000010) == 0x06000010) {
+
+		return space_cccc_0110__1(insn, asi);
+
+	} else if ((insn & 0x0f000010) == 0x07000010) {
+
+		return space_cccc_0111__1(insn, asi);
+
+	} else if ((insn & 0x0c000000) == 0x04000000) {
+
+		return space_cccc_01xx(insn, asi);
+
+	} else if ((insn & 0x0e000000) == 0x08000000) {
+
+		return space_cccc_100x(insn, asi);
+
+	} else if ((insn & 0x0e000000) == 0x0a000000) {
+
+		return space_cccc_101x(insn, asi);
+
+	} else if ((insn & 0x0fe00000) == 0x0c400000) {
+
+		return space_cccc_1100_010x(insn, asi);
+
+	} else if ((insn & 0x0e000000) == 0x0c400000) {
+
+		return space_cccc_110x(insn, asi);
+
+	}
+
+	return space_cccc_111x(insn, asi);
+}
+
+void __init arm_kprobe_decode_init(void)
+{
+	find_str_pc_offset();
+}
+
+
+/*
+ * All ARM instructions listed below.
+ *
+ * Instructions and their general purpose registers are given.
+ * If a particular register may not use R15, it is prefixed with a "!".
+ * If marked with a "*" means the value returned by reading R15
+ * is implementation defined.
+ *
+ * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ
+ *     TST: Rd, Rn, Rm, !Rs
+ * BX: Rm
+ * BLX(2): !Rm
+ * BX: Rm (R15 legal, but discouraged)
+ * BXJ: !Rm,
+ * CLZ: !Rd, !Rm
+ * CPY: Rd, Rm
+ * LDC/2,STC/2 immediate offset & unindex: Rn
+ * LDC/2,STC/2 immediate pre/post-indexed: !Rn
+ * LDM(1/3): !Rn, register_list
+ * LDM(2): !Rn, !register_list
+ * LDR,STR,PLD immediate offset: Rd, Rn
+ * LDR,STR,PLD register offset: Rd, Rn, !Rm
+ * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm
+ * LDR,STR immediate pre/post-indexed: Rd, !Rn
+ * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm
+ * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm
+ * LDRB,STRB immediate offset: !Rd, Rn
+ * LDRB,STRB register offset: !Rd, Rn, !Rm
+ * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm
+ * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn
+ * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm
+ * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm
+ * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn
+ * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm
+ * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm
+ * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn
+ * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm
+ * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn
+ * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm
+ * LDREX: !Rd, !Rn
+ * MCR/2: !Rd
+ * MCRR/2,MRRC/2: !Rd, !Rn
+ * MLA: !Rd, !Rn, !Rm, !Rs
+ * MOV: Rd
+ * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register)
+ * MRS,MSR: !Rd
+ * MUL: !Rd, !Rm, !Rs
+ * PKH{BT,TB}: !Rd, !Rn, !Rm
+ * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn
+ * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn
+ * REV/16/SH: !Rd, !Rm
+ * RFE: !Rn
+ * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm
+ * SEL: !Rd, !Rn, !Rm
+ * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs
+ * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs
+ * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs
+ * SSAT/16: !Rd, !Rm
+ * STM(1/2): !Rn, register_list* (R15 in reg list not recommended)
+ * STRT immediate pre/post-indexed: Rd*, !Rn
+ * STRT register pre/post-indexed: Rd*, !Rn, !Rm
+ * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm
+ * STREX: !Rd, !Rn, !Rm
+ * SWP/B: !Rd, !Rn, !Rm
+ * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm
+ * {S,U}XT{B,B16,H}: !Rd, !Rm
+ * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs
+ * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs
+ *
+ * May transfer control by writing R15 (possible mode changes or alternate
+ * mode accesses marked by "*"):
+ * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY,
+ * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI*
+ *
+ * Instructions that do not take general registers, nor transfer control:
+ * CDP/2, SETEND, SRS*
+ */
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
new file mode 100644
index 0000000..a22a98c
--- /dev/null
+++ b/arch/arm/kernel/kprobes.c
@@ -0,0 +1,447 @@
+/*
+ * arch/arm/kernel/kprobes.c
+ *
+ * Kprobes on ARM
+ *
+ * Abhishek Sagar <sagar.abhishek@gmail.com>
+ * Copyright (C) 2006, 2007 Motorola Inc.
+ *
+ * Nicolas Pitre <nico@marvell.com>
+ * Copyright (C) 2007 Marvell Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/stringify.h>
+#include <asm/traps.h>
+#include <asm/cacheflush.h>
+
+#define MIN_STACK_SIZE(addr) 				\
+	min((unsigned long)MAX_STACK_SIZE,		\
+	    (unsigned long)current_thread_info() + THREAD_START_SP - (addr))
+
+#define flush_insns(addr, cnt) 				\
+	flush_icache_range((unsigned long)(addr),	\
+			   (unsigned long)(addr) +	\
+			   sizeof(kprobe_opcode_t) * (cnt))
+
+/* Used as a marker in ARM_pc to note when we're in a jprobe. */
+#define JPROBE_MAGIC_ADDR		0xffffffff
+
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
+
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
+{
+	kprobe_opcode_t insn;
+	kprobe_opcode_t tmp_insn[MAX_INSN_SIZE];
+	unsigned long addr = (unsigned long)p->addr;
+	int is;
+
+	if (addr & 0x3 || in_exception_text(addr))
+		return -EINVAL;
+
+	insn = *p->addr;
+	p->opcode = insn;
+	p->ainsn.insn = tmp_insn;
+
+	switch (arm_kprobe_decode_insn(insn, &p->ainsn)) {
+	case INSN_REJECTED:	/* not supported */
+		return -EINVAL;
+
+	case INSN_GOOD:		/* instruction uses slot */
+		p->ainsn.insn = get_insn_slot();
+		if (!p->ainsn.insn)
+			return -ENOMEM;
+		for (is = 0; is < MAX_INSN_SIZE; ++is)
+			p->ainsn.insn[is] = tmp_insn[is];
+		flush_insns(&p->ainsn.insn, MAX_INSN_SIZE);
+		break;
+
+	case INSN_GOOD_NO_SLOT:	/* instruction doesn't need insn slot */
+		p->ainsn.insn = NULL;
+		break;
+	}
+
+	return 0;
+}
+
+void __kprobes arch_arm_kprobe(struct kprobe *p)
+{
+	*p->addr = KPROBE_BREAKPOINT_INSTRUCTION;
+	flush_insns(p->addr, 1);
+}
+
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
+{
+	*p->addr = p->opcode;
+	flush_insns(p->addr, 1);
+}
+
+void __kprobes arch_remove_kprobe(struct kprobe *p)
+{
+	if (p->ainsn.insn) {
+		mutex_lock(&kprobe_mutex);
+		free_insn_slot(p->ainsn.insn, 0);
+		mutex_unlock(&kprobe_mutex);
+		p->ainsn.insn = NULL;
+	}
+}
+
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+	kcb->prev_kprobe.kp = kprobe_running();
+	kcb->prev_kprobe.status = kcb->kprobe_status;
+}
+
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+	kcb->kprobe_status = kcb->prev_kprobe.status;
+}
+
+static void __kprobes set_current_kprobe(struct kprobe *p)
+{
+	__get_cpu_var(current_kprobe) = p;
+}
+
+static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs,
+				 struct kprobe_ctlblk *kcb)
+{
+	regs->ARM_pc += 4;
+	p->ainsn.insn_handler(p, regs);
+}
+
+/*
+ * Called with IRQs disabled. IRQs must remain disabled from that point
+ * all the way until processing this kprobe is complete.  The current
+ * kprobes implementation cannot process more than one nested level of
+ * kprobe, and that level is reserved for user kprobe handlers, so we can't
+ * risk encountering a new kprobe in an interrupt handler.
+ */
+void __kprobes kprobe_handler(struct pt_regs *regs)
+{
+	struct kprobe *p, *cur;
+	struct kprobe_ctlblk *kcb;
+	kprobe_opcode_t	*addr = (kprobe_opcode_t *)regs->ARM_pc;
+
+	kcb = get_kprobe_ctlblk();
+	cur = kprobe_running();
+	p = get_kprobe(addr);
+
+	if (p) {
+		if (cur) {
+			/* Kprobe is pending, so we're recursing. */
+			switch (kcb->kprobe_status) {
+			case KPROBE_HIT_ACTIVE:
+			case KPROBE_HIT_SSDONE:
+				/* A pre- or post-handler probe got us here. */
+				kprobes_inc_nmissed_count(p);
+				save_previous_kprobe(kcb);
+				set_current_kprobe(p);
+				kcb->kprobe_status = KPROBE_REENTER;
+				singlestep(p, regs, kcb);
+				restore_previous_kprobe(kcb);
+				break;
+			default:
+				/* impossible cases */
+				BUG();
+			}
+		} else {
+			set_current_kprobe(p);
+			kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+
+			/*
+			 * If we have no pre-handler or it returned 0, we
+			 * continue with normal processing.  If we have a
+			 * pre-handler and it returned non-zero, it prepped
+			 * for calling the break_handler below on re-entry,
+			 * so get out doing nothing more here.
+			 */
+			if (!p->pre_handler || !p->pre_handler(p, regs)) {
+				kcb->kprobe_status = KPROBE_HIT_SS;
+				singlestep(p, regs, kcb);
+				if (p->post_handler) {
+					kcb->kprobe_status = KPROBE_HIT_SSDONE;
+					p->post_handler(p, regs, 0);
+				}
+				reset_current_kprobe();
+			}
+		}
+	} else if (cur) {
+		/* We probably hit a jprobe.  Call its break handler. */
+		if (cur->break_handler && cur->break_handler(cur, regs)) {
+			kcb->kprobe_status = KPROBE_HIT_SS;
+			singlestep(cur, regs, kcb);
+			if (cur->post_handler) {
+				kcb->kprobe_status = KPROBE_HIT_SSDONE;
+				cur->post_handler(cur, regs, 0);
+			}
+		}
+		reset_current_kprobe();
+	} else {
+		/*
+		 * The probe was removed and a race is in progress.
+		 * There is nothing we can do about it.  Let's restart
+		 * the instruction.  By the time we can restart, the
+		 * real instruction will be there.
+		 */
+	}
+}
+
+int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
+{
+	kprobe_handler(regs);
+	return 0;
+}
+
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
+{
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	switch (kcb->kprobe_status) {
+	case KPROBE_HIT_SS:
+	case KPROBE_REENTER:
+		/*
+		 * We are here because the instruction being single
+		 * stepped caused a page fault. We reset the current
+		 * kprobe and the PC to point back to the probe address
+		 * and allow the page fault handler to continue as a
+		 * normal page fault.
+		 */
+		regs->ARM_pc = (long)cur->addr;
+		if (kcb->kprobe_status == KPROBE_REENTER) {
+			restore_previous_kprobe(kcb);
+		} else {
+			reset_current_kprobe();
+		}
+		break;
+
+	case KPROBE_HIT_ACTIVE:
+	case KPROBE_HIT_SSDONE:
+		/*
+		 * We increment the nmissed count for accounting,
+		 * we can also use npre/npostfault count for accounting
+		 * these specific fault cases.
+		 */
+		kprobes_inc_nmissed_count(cur);
+
+		/*
+		 * We come here because instructions in the pre/post
+		 * handler caused the page_fault, this could happen
+		 * if handler tries to access user space by
+		 * copy_from_user(), get_user() etc. Let the
+		 * user-specified handler try to fix it.
+		 */
+		if (cur->fault_handler && cur->fault_handler(cur, regs, fsr))
+			return 1;
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
+{
+	/*
+	 * notify_die() is currently never called on ARM,
+	 * so this callback is currently empty.
+	 */
+	return NOTIFY_DONE;
+}
+
+/*
+ * When a retprobed function returns, trampoline_handler() is called,
+ * calling the kretprobe's handler. We construct a struct pt_regs to
+ * give a view of registers r0-r11 to the user return-handler.  This is
+ * not a complete pt_regs structure, but that should be plenty sufficient
+ * for kretprobe handlers which should normally be interested in r0 only
+ * anyway.
+ */
+static void __attribute__((naked)) __kprobes kretprobe_trampoline(void)
+{
+	__asm__ __volatile__ (
+		"stmdb	sp!, {r0 - r11}		\n\t"
+		"mov	r0, sp			\n\t"
+		"bl	trampoline_handler	\n\t"
+		"mov	lr, r0			\n\t"
+		"ldmia	sp!, {r0 - r11}		\n\t"
+		"mov	pc, lr			\n\t"
+		: : : "memory");
+}
+
+/* Called from kretprobe_trampoline */
+static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
+{
+	struct kretprobe_instance *ri = NULL;
+	struct hlist_head *head, empty_rp;
+	struct hlist_node *node, *tmp;
+	unsigned long flags, orig_ret_address = 0;
+	unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
+
+	INIT_HLIST_HEAD(&empty_rp);
+	spin_lock_irqsave(&kretprobe_lock, flags);
+	head = kretprobe_inst_table_head(current);
+
+	/*
+	 * It is possible to have multiple instances associated with a given
+	 * task either because multiple functions in the call path have
+	 * a return probe installed on them, and/or more than one return
+	 * probe was registered for a target function.
+	 *
+	 * We can handle this because:
+	 *     - instances are always inserted at the head of the list
+	 *     - when multiple return probes are registered for the same
+	 *       function, the first instance's ret_addr will point to the
+	 *       real return address, and all the rest will point to
+	 *       kretprobe_trampoline
+	 */
+	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+		if (ri->task != current)
+			/* another task is sharing our hash bucket */
+			continue;
+
+		if (ri->rp && ri->rp->handler) {
+			__get_cpu_var(current_kprobe) = &ri->rp->kp;
+			get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+			ri->rp->handler(ri, regs);
+			__get_cpu_var(current_kprobe) = NULL;
+		}
+
+		orig_ret_address = (unsigned long)ri->ret_addr;
+		recycle_rp_inst(ri, &empty_rp);
+
+		if (orig_ret_address != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	kretprobe_assert(ri, orig_ret_address, trampoline_address);
+	spin_unlock_irqrestore(&kretprobe_lock, flags);
+
+	hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
+
+	return (void *)orig_ret_address;
+}
+
+/* Called with kretprobe_lock held. */
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+				      struct pt_regs *regs)
+{
+	ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr;
+
+	/* Replace the return addr with trampoline addr. */
+	regs->ARM_lr = (unsigned long)&kretprobe_trampoline;
+}
+
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct jprobe *jp = container_of(p, struct jprobe, kp);
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+	long sp_addr = regs->ARM_sp;
+
+	kcb->jprobe_saved_regs = *regs;
+	memcpy(kcb->jprobes_stack, (void *)sp_addr, MIN_STACK_SIZE(sp_addr));
+	regs->ARM_pc = (long)jp->entry;
+	regs->ARM_cpsr |= PSR_I_BIT;
+	preempt_disable();
+	return 1;
+}
+
+void __kprobes jprobe_return(void)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	__asm__ __volatile__ (
+		/*
+		 * Setup an empty pt_regs. Fill SP and PC fields as
+		 * they're needed by longjmp_break_handler.
+		 */
+		"sub    sp, %0, %1		\n\t"
+		"ldr    r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t"
+		"str    %0, [sp, %2]		\n\t"
+		"str    r0, [sp, %3]		\n\t"
+		"mov    r0, sp			\n\t"
+		"bl     kprobe_handler		\n\t"
+
+		/*
+		 * Return to the context saved by setjmp_pre_handler
+		 * and restored by longjmp_break_handler.
+		 */
+		"ldr	r0, [sp, %4]		\n\t"
+		"msr	cpsr_cxsf, r0		\n\t"
+		"ldmia	sp, {r0 - pc}		\n\t"
+		:
+		: "r" (kcb->jprobe_saved_regs.ARM_sp),
+		  "I" (sizeof(struct pt_regs)),
+		  "J" (offsetof(struct pt_regs, ARM_sp)),
+		  "J" (offsetof(struct pt_regs, ARM_pc)),
+		  "J" (offsetof(struct pt_regs, ARM_cpsr))
+		: "memory", "cc");
+}
+
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+	long stack_addr = kcb->jprobe_saved_regs.ARM_sp;
+	long orig_sp = regs->ARM_sp;
+	struct jprobe *jp = container_of(p, struct jprobe, kp);
+
+	if (regs->ARM_pc == JPROBE_MAGIC_ADDR) {
+		if (orig_sp != stack_addr) {
+			struct pt_regs *saved_regs =
+				(struct pt_regs *)kcb->jprobe_saved_regs.ARM_sp;
+			printk("current sp %lx does not match saved sp %lx\n",
+			       orig_sp, stack_addr);
+			printk("Saved registers for jprobe %p\n", jp);
+			show_regs(saved_regs);
+			printk("Current registers\n");
+			show_regs(regs);
+			BUG();
+		}
+		*regs = kcb->jprobe_saved_regs;
+		memcpy((void *)stack_addr, kcb->jprobes_stack,
+		       MIN_STACK_SIZE(stack_addr));
+		preempt_enable_no_resched();
+		return 1;
+	}
+	return 0;
+}
+
+static struct undef_hook kprobes_break_hook = {
+	.instr_mask	= 0xffffffff,
+	.instr_val	= KPROBE_BREAKPOINT_INSTRUCTION,
+	.cpsr_mask	= MODE_MASK,
+	.cpsr_val	= SVC_MODE,
+	.fn		= kprobe_trap_handler,
+};
+
+int __init arch_init_kprobes()
+{
+	arm_kprobe_decode_init();
+	register_undef_hook(&kprobes_break_hook);
+	return 0;
+}
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index e59b5b8..b5867ec 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -325,7 +325,9 @@
 	profile_tick(CPU_PROFILING);
 	do_leds();
 	do_set_rtc();
+	write_seqlock(&xtime_lock);
 	do_timer(1);
+	write_sequnlock(&xtime_lock);
 #ifndef CONFIG_SMP
 	update_process_times(user_mode(get_irq_regs()));
 #endif
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index c34db4e..5595fdd 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -19,6 +19,7 @@
 #include <linux/kallsyms.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/kprobes.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
@@ -46,15 +47,6 @@
 
 static void dump_mem(const char *str, unsigned long bottom, unsigned long top);
 
-static inline int in_exception_text(unsigned long ptr)
-{
-	extern char __exception_text_start[];
-	extern char __exception_text_end[];
-
-	return ptr >= (unsigned long)&__exception_text_start &&
-	       ptr < (unsigned long)&__exception_text_end;
-}
-
 void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
 {
 #ifdef CONFIG_KALLSYMS
@@ -322,6 +314,17 @@
 		get_user(instr, (u32 __user *)pc);
 	}
 
+#ifdef CONFIG_KPROBES
+	/*
+	 * It is possible to have recursive kprobes, so we can't call
+	 * the kprobe trap handler with the undef_lock held.
+	 */
+	if (instr == KPROBE_BREAKPOINT_INSTRUCTION && !user_mode(regs)) {
+		kprobe_trap_handler(regs, instr);
+		return;
+	}
+#endif
+
 	spin_lock_irqsave(&undef_lock, flags);
 	list_for_each_entry(hook, &undef_hook, node) {
 		if ((instr & hook->instr_mask) == hook->instr_val &&
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 5ff5406..30f732c 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -94,6 +94,7 @@
 			TEXT_TEXT
 			SCHED_TEXT
 			LOCK_TEXT
+			KPROBES_TEXT
 #ifdef CONFIG_MMU
 			*(.fixup)
 #endif
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index 0446ef2..b016be2 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -130,13 +130,9 @@
 aaec2000_timer_interrupt(int irq, void *dev_id)
 {
 	/* TODO: Check timer accuracy */
-	write_seqlock(&xtime_lock);
-
 	timer_tick();
 	TIMER1_CLEAR = 1;
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 05a9f8a..5b0422c 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -22,6 +22,9 @@
 config ARCH_AT91SAM9RL
 	bool "AT91SAM9RL"
 
+config ARCH_AT91CAP9
+	bool "AT91CAP9"
+
 config ARCH_AT91X40
 	bool "AT91x40"
 
@@ -178,6 +181,21 @@
 
 # ----------------------------------------------------------
 
+if ARCH_AT91CAP9
+
+comment "AT91CAP9 Board Type"
+
+config MACH_AT91CAP9ADK
+	bool "Atmel AT91CAP9A-DK Evaluation Kit"
+	depends on ARCH_AT91CAP9
+	help
+	  Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit.
+	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138>
+
+endif
+
+# ----------------------------------------------------------
+
 if ARCH_AT91X40
 
 comment "AT91X40 Board Type"
@@ -198,13 +216,13 @@
 
 config MTD_AT91_DATAFLASH_CARD
 	bool "Enable DataFlash Card support"
-	depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK)
+	depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK)
 	help
 	  Enable support for the DataFlash card.
 
 config MTD_NAND_AT91_BUSWIDTH_16
 	bool "Enable 16-bit data bus interface to NAND flash"
-	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK)
+	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK)
 	help
 	  On AT91SAM926x boards both types of NAND flash can be present
 	  (8 and 16 bit data bus width).
@@ -219,6 +237,22 @@
 	  Select this if you need to program one or more of the PCK0..PCK3
 	  programmable clock outputs.
 
+config AT91_TIMER_HZ
+       int "Kernel HZ (jiffies per second)"
+       range 32 1024
+       depends on ARCH_AT91
+       default "128" if ARCH_AT91RM9200
+       default "100"
+       help
+	  On AT91rm9200 chips where you're using a system clock derived
+	  from the 32768 Hz hardware clock, this tick rate should divide
+	  it exactly: use a power-of-two value, such as 128 or 256, to
+	  reduce timing errors caused by rounding.
+
+	  On AT91sam926x chips, or otherwise when using a higher precision
+	  system clock (of at least several MHz), rounding is less of a
+	  problem so it can be safer to use a decimal values like 100.
+
 endmenu
 
 endif
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index a21f08c..bf5f293 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -8,7 +8,6 @@
 obj-		:=
 
 obj-$(CONFIG_AT91_PMC_UNIT)	+= clock.o
-obj-$(CONFIG_PM)		+= pm.o
 
 # CPU-specific support
 obj-$(CONFIG_ARCH_AT91RM9200)	+= at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
@@ -16,6 +15,7 @@
 obj-$(CONFIG_ARCH_AT91SAM9261)	+= at91sam9261.o at91sam926x_time.o at91sam9261_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263.o at91sam926x_time.o at91sam9263_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9RL)	+= at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o
+obj-$(CONFIG_ARCH_AT91CAP9)	+= at91cap9.o at91sam926x_time.o at91cap9_devices.o
 obj-$(CONFIG_ARCH_AT91X40)	+= at91x40.o at91x40_time.o
 
 # AT91RM9200 board-specific support
@@ -29,7 +29,6 @@
 obj-$(CONFIG_MACH_ATEB9200)	+= board-eb9200.o
 obj-$(CONFIG_MACH_KAFA)		+= board-kafa.o
 obj-$(CONFIG_MACH_PICOTUX2XX)	+= board-picotux200.o
-obj-$(CONFIG_MACH_AT91EB01)	+= board-eb01.o
 
 # AT91SAM9260 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
@@ -43,19 +42,17 @@
 # AT91SAM9RL board-specific support
 obj-$(CONFIG_MACH_AT91SAM9RLEK)	+= board-sam9rlek.o
 
-# LEDs support
-led-$(CONFIG_ARCH_AT91RM9200DK)	+= leds.o
-led-$(CONFIG_MACH_AT91RM9200EK)	+= leds.o
-led-$(CONFIG_MACH_AT91SAM9261EK)+= leds.o
-led-$(CONFIG_MACH_CSB337)	+= leds.o
-led-$(CONFIG_MACH_CSB637)	+= leds.o
-led-$(CONFIG_MACH_KB9200)	+= leds.o
-led-$(CONFIG_MACH_KAFA)		+= leds.o
-obj-$(CONFIG_LEDS) += $(led-y)
+# AT91CAP9 board-specific support
+obj-$(CONFIG_MACH_AT91CAP9ADK)	+= board-cap9adk.o
 
-# VGA support
-#obj-$(CONFIG_FB_S1D13XXX)	+= ics1523.o
+# AT91X40 board-specific support
+obj-$(CONFIG_MACH_AT91EB01)	+= board-eb01.o
 
+# Drivers
+obj-y				+= leds.o
+
+# Power Management
+obj-$(CONFIG_PM)		+= pm.o
 
 ifeq ($(CONFIG_PM_DEBUG),y)
 CFLAGS_pm.o += -DDEBUG
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
index e667dcc..071a250 100644
--- a/arch/arm/mach-at91/Makefile.boot
+++ b/arch/arm/mach-at91/Makefile.boot
@@ -3,7 +3,12 @@
 #   PARAMS_PHYS must be within 4MB of ZRELADDR
 #   INITRD_PHYS must be in RAM
 
+ifeq ($(CONFIG_ARCH_AT91CAP9),y)
+   zreladdr-y	:= 0x70008000
+params_phys-y	:= 0x70000100
+initrd_phys-y	:= 0x70410000
+else
    zreladdr-y	:= 0x20008000
 params_phys-y	:= 0x20000100
 initrd_phys-y	:= 0x20410000
-
+endif
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
new file mode 100644
index 0000000..48d27d8
--- /dev/null
+++ b/arch/arm/mach-at91/at91cap9.c
@@ -0,0 +1,365 @@
+/*
+ * arch/arm/mach-at91/at91cap9.c
+ *
+ *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ *  Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/arch/at91cap9.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_rstc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91cap9_io_desc[] __initdata = {
+	{
+		.virtual	= AT91_VA_BASE_SYS,
+		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_IO_VIRT_BASE - AT91CAP9_SRAM_SIZE,
+		.pfn		= __phys_to_pfn(AT91CAP9_SRAM_BASE),
+		.length		= AT91CAP9_SRAM_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+/* --------------------------------------------------------------------
+ *  Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioABCD_clk = {
+	.name		= "pioABCD_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_PIOABCD,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb0_clk = {
+	.name		= "mpb0_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_MPB0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb1_clk = {
+	.name		= "mpb1_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_MPB1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb2_clk = {
+	.name		= "mpb2_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_MPB2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb3_clk = {
+	.name		= "mpb3_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_MPB3,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb4_clk = {
+	.name		= "mpb4_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_MPB4,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+	.name		= "usart0_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_US0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+	.name		= "usart1_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_US1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+	.name		= "usart2_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_US2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc0_clk = {
+	.name		= "mci0_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_MCI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc1_clk = {
+	.name		= "mci1_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_MCI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk can_clk = {
+	.name		= "can_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_CAN,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi_clk = {
+	.name		= "twi_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_TWI,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+	.name		= "spi0_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_SPI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+	.name		= "spi1_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_SPI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+	.name		= "ssc0_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_SSC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+	.name		= "ssc1_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_SSC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ac97_clk = {
+	.name		= "ac97_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_AC97C,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tcb_clk = {
+	.name		= "tcb_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_TCB,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pwmc_clk = {
+	.name		= "pwmc_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_PWMC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk macb_clk = {
+	.name		= "macb_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_EMAC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk aestdes_clk = {
+	.name		= "aestdes_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_AESTDES,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk adc_clk = {
+	.name		= "adc_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_ADC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk isi_clk = {
+	.name		= "isi_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_ISI,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk lcdc_clk = {
+	.name		= "lcdc_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_LCDC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma_clk = {
+	.name		= "dma_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_DMA,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk udphs_clk = {
+	.name		= "udphs_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_UDPHS,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+	.name		= "ohci_clk",
+	.pmc_mask	= 1 << AT91CAP9_ID_UHP,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+	&pioABCD_clk,
+	&mpb0_clk,
+	&mpb1_clk,
+	&mpb2_clk,
+	&mpb3_clk,
+	&mpb4_clk,
+	&usart0_clk,
+	&usart1_clk,
+	&usart2_clk,
+	&mmc0_clk,
+	&mmc1_clk,
+	&can_clk,
+	&twi_clk,
+	&spi0_clk,
+	&spi1_clk,
+	&ssc0_clk,
+	&ssc1_clk,
+	&ac97_clk,
+	&tcb_clk,
+	&pwmc_clk,
+	&macb_clk,
+	&aestdes_clk,
+	&adc_clk,
+	&isi_clk,
+	&lcdc_clk,
+	&dma_clk,
+	&udphs_clk,
+	&ohci_clk,
+	// irq0 .. irq1
+};
+
+/*
+ * The four programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+	.name		= "pck0",
+	.pmc_mask	= AT91_PMC_PCK0,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 0,
+};
+static struct clk pck1 = {
+	.name		= "pck1",
+	.pmc_mask	= AT91_PMC_PCK1,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 1,
+};
+static struct clk pck2 = {
+	.name		= "pck2",
+	.pmc_mask	= AT91_PMC_PCK2,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 2,
+};
+static struct clk pck3 = {
+	.name		= "pck3",
+	.pmc_mask	= AT91_PMC_PCK3,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 3,
+};
+
+static void __init at91cap9_register_clocks(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+		clk_register(periph_clocks[i]);
+
+	clk_register(&pck0);
+	clk_register(&pck1);
+	clk_register(&pck2);
+	clk_register(&pck3);
+}
+
+/* --------------------------------------------------------------------
+ *  GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91cap9_gpio[] = {
+	{
+		.id		= AT91CAP9_ID_PIOABCD,
+		.offset		= AT91_PIOA,
+		.clock		= &pioABCD_clk,
+	}, {
+		.id		= AT91CAP9_ID_PIOABCD,
+		.offset		= AT91_PIOB,
+		.clock		= &pioABCD_clk,
+	}, {
+		.id		= AT91CAP9_ID_PIOABCD,
+		.offset		= AT91_PIOC,
+		.clock		= &pioABCD_clk,
+	}, {
+		.id		= AT91CAP9_ID_PIOABCD,
+		.offset		= AT91_PIOD,
+		.clock		= &pioABCD_clk,
+	}
+};
+
+static void at91cap9_reset(void)
+{
+	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+}
+
+/* --------------------------------------------------------------------
+ *  AT91CAP9 processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at91cap9_initialize(unsigned long main_clock)
+{
+	/* Map peripherals */
+	iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc));
+
+	at91_arch_reset = at91cap9_reset;
+	at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
+
+	/* Init clock subsystem */
+	at91_clock_init(main_clock);
+
+	/* Register the processor-specific clocks */
+	at91cap9_register_clocks();
+
+	/* Register GPIO subsystem */
+	at91_gpio_init(at91cap9_gpio, 4);
+}
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = {
+	7,	/* Advanced Interrupt Controller (FIQ) */
+	7,	/* System Peripherals */
+	1,	/* Parallel IO Controller A, B, C and D */
+	0,	/* MP Block Peripheral 0 */
+	0,	/* MP Block Peripheral 1 */
+	0,	/* MP Block Peripheral 2 */
+	0,	/* MP Block Peripheral 3 */
+	0,	/* MP Block Peripheral 4 */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	0,	/* Multimedia Card Interface 0 */
+	0,	/* Multimedia Card Interface 1 */
+	3,	/* CAN */
+	6,	/* Two-Wire Interface */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	4,	/* Serial Synchronous Controller 0 */
+	4,	/* Serial Synchronous Controller 1 */
+	5,	/* AC97 Controller */
+	0,	/* Timer Counter 0, 1 and 2 */
+	0,	/* Pulse Width Modulation Controller */
+	3,	/* Ethernet */
+	0,	/* Advanced Encryption Standard, Triple DES*/
+	0,	/* Analog-to-Digital Converter */
+	0,	/* Image Sensor Interface */
+	3,	/* LCD Controller */
+	0,	/* DMA Controller */
+	2,	/* USB Device Port */
+	2,	/* USB Host port */
+	0,	/* Advanced Interrupt Controller (IRQ0) */
+	0,	/* Advanced Interrupt Controller (IRQ1) */
+};
+
+void __init at91cap9_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+	if (!priority)
+		priority = at91cap9_default_irq_priority;
+
+	/* Initialize the AIC interrupt controller */
+	at91_aic_init(priority);
+
+	/* Enable GPIO interrupts */
+	at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
new file mode 100644
index 0000000..c50fad9
--- /dev/null
+++ b/arch/arm/mach-at91/at91cap9_devices.c
@@ -0,0 +1,1066 @@
+/*
+ * arch/arm/mach-at91/at91cap9_devices.c
+ *
+ *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ *  Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91cap9.h>
+#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91cap9_matrix.h>
+
+#include "generic.h"
+
+
+/* --------------------------------------------------------------------
+ *  USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_data;
+
+static struct resource usbh_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_UHP_BASE,
+		.end	= AT91CAP9_UHP_BASE + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_UHP,
+		.end	= AT91CAP9_ID_UHP,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_usbh_device = {
+	.name		= "at91_ohci",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &ohci_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &usbh_data,
+	},
+	.resource	= usbh_resources,
+	.num_resources	= ARRAY_SIZE(usbh_resources),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+	int i;
+
+	if (!data)
+		return;
+
+	/* Enable VBus control for UHP ports */
+	for (i = 0; i < data->ports; i++) {
+		if (data->vbus_pin[i])
+			at91_set_gpio_output(data->vbus_pin[i], 0);
+	}
+
+	usbh_data = *data;
+	platform_device_register(&at91_usbh_device);
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
+static u64 eth_dmamask = DMA_BIT_MASK(32);
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_EMAC,
+		.end	= AT91CAP9_BASE_EMAC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_EMAC,
+		.end	= AT91CAP9_ID_EMAC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_eth_device = {
+	.name		= "macb",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &eth_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &eth_data,
+	},
+	.resource	= eth_resources,
+	.num_resources	= ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+	if (!data)
+		return;
+
+	if (data->phy_irq_pin) {
+		at91_set_gpio_input(data->phy_irq_pin, 0);
+		at91_set_deglitch(data->phy_irq_pin, 1);
+	}
+
+	/* Pins used for MII and RMII */
+	at91_set_A_periph(AT91_PIN_PB21, 0);	/* ETXCK_EREFCK */
+	at91_set_A_periph(AT91_PIN_PB22, 0);	/* ERXDV */
+	at91_set_A_periph(AT91_PIN_PB25, 0);	/* ERX0 */
+	at91_set_A_periph(AT91_PIN_PB26, 0);	/* ERX1 */
+	at91_set_A_periph(AT91_PIN_PB27, 0);	/* ERXER */
+	at91_set_A_periph(AT91_PIN_PB28, 0);	/* ETXEN */
+	at91_set_A_periph(AT91_PIN_PB23, 0);	/* ETX0 */
+	at91_set_A_periph(AT91_PIN_PB24, 0);	/* ETX1 */
+	at91_set_A_periph(AT91_PIN_PB30, 0);	/* EMDIO */
+	at91_set_A_periph(AT91_PIN_PB29, 0);	/* EMDC */
+
+	if (!data->is_rmii) {
+		at91_set_B_periph(AT91_PIN_PC25, 0);	/* ECRS */
+		at91_set_B_periph(AT91_PIN_PC26, 0);	/* ECOL */
+		at91_set_B_periph(AT91_PIN_PC22, 0);	/* ERX2 */
+		at91_set_B_periph(AT91_PIN_PC23, 0);	/* ERX3 */
+		at91_set_B_periph(AT91_PIN_PC27, 0);	/* ERXCK */
+		at91_set_B_periph(AT91_PIN_PC20, 0);	/* ETX2 */
+		at91_set_B_periph(AT91_PIN_PC21, 0);	/* ETX3 */
+		at91_set_B_periph(AT91_PIN_PC24, 0);	/* ETXER */
+	}
+
+	eth_data = *data;
+	platform_device_register(&at91cap9_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct at91_mmc_data mmc0_data, mmc1_data;
+
+static struct resource mmc0_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_MCI0,
+		.end	= AT91CAP9_BASE_MCI0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_MCI0,
+		.end	= AT91CAP9_ID_MCI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_mmc0_device = {
+	.name		= "at91_mci",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &mmc_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &mmc0_data,
+	},
+	.resource	= mmc0_resources,
+	.num_resources	= ARRAY_SIZE(mmc0_resources),
+};
+
+static struct resource mmc1_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_MCI1,
+		.end	= AT91CAP9_BASE_MCI1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_MCI1,
+		.end	= AT91CAP9_ID_MCI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_mmc1_device = {
+	.name		= "at91_mci",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &mmc_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &mmc1_data,
+	},
+	.resource	= mmc1_resources,
+	.num_resources	= ARRAY_SIZE(mmc1_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+	if (!data)
+		return;
+
+	/* input/irq */
+	if (data->det_pin) {
+		at91_set_gpio_input(data->det_pin, 1);
+		at91_set_deglitch(data->det_pin, 1);
+	}
+	if (data->wp_pin)
+		at91_set_gpio_input(data->wp_pin, 1);
+	if (data->vcc_pin)
+		at91_set_gpio_output(data->vcc_pin, 0);
+
+	if (mmc_id == 0) {		/* MCI0 */
+		/* CLK */
+		at91_set_A_periph(AT91_PIN_PA2, 0);
+
+		/* CMD */
+		at91_set_A_periph(AT91_PIN_PA1, 1);
+
+		/* DAT0, maybe DAT1..DAT3 */
+		at91_set_A_periph(AT91_PIN_PA0, 1);
+		if (data->wire4) {
+			at91_set_A_periph(AT91_PIN_PA3, 1);
+			at91_set_A_periph(AT91_PIN_PA4, 1);
+			at91_set_A_periph(AT91_PIN_PA5, 1);
+		}
+
+		mmc0_data = *data;
+		at91_clock_associate("mci0_clk", &at91cap9_mmc1_device.dev, "mci_clk");
+		platform_device_register(&at91cap9_mmc0_device);
+	} else {			/* MCI1 */
+		/* CLK */
+		at91_set_A_periph(AT91_PIN_PA16, 0);
+
+		/* CMD */
+		at91_set_A_periph(AT91_PIN_PA17, 1);
+
+		/* DAT0, maybe DAT1..DAT3 */
+		at91_set_A_periph(AT91_PIN_PA18, 1);
+		if (data->wire4) {
+			at91_set_A_periph(AT91_PIN_PA19, 1);
+			at91_set_A_periph(AT91_PIN_PA20, 1);
+			at91_set_A_periph(AT91_PIN_PA21, 1);
+		}
+
+		mmc1_data = *data;
+		at91_clock_associate("mci1_clk", &at91cap9_mmc1_device.dev, "mci_clk");
+		platform_device_register(&at91cap9_mmc1_device);
+	}
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE)
+static struct at91_nand_data nand_data;
+
+#define NAND_BASE	AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+	{
+		.start	= NAND_BASE,
+		.end	= NAND_BASE + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91cap9_nand_device = {
+	.name		= "at91_nand",
+	.id		= -1,
+	.dev		= {
+				.platform_data	= &nand_data,
+	},
+	.resource	= nand_resources,
+	.num_resources	= ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct at91_nand_data *data)
+{
+	unsigned long csa, mode;
+
+	if (!data)
+		return;
+
+	csa = at91_sys_read(AT91_MATRIX_EBICSA);
+	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
+
+	/* set the bus interface characteristics */
+	at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(1)
+			| AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(1));
+
+	at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(6)
+			| AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(6));
+
+	at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(8) | AT91_SMC_NRDCYCLE_(8));
+
+	if (data->bus_width_16)
+		mode = AT91_SMC_DBW_16;
+	else
+		mode = AT91_SMC_DBW_8;
+	at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1));
+
+	/* enable pin */
+	if (data->enable_pin)
+		at91_set_gpio_output(data->enable_pin, 1);
+
+	/* ready/busy pin */
+	if (data->rdy_pin)
+		at91_set_gpio_input(data->rdy_pin, 1);
+
+	/* card detect pin */
+	if (data->det_pin)
+		at91_set_gpio_input(data->det_pin, 1);
+
+	nand_data = *data;
+	platform_device_register(&at91cap9_nand_device);
+}
+#else
+void __init at91_add_device_nand(struct at91_nand_data *data) {}
+#endif
+
+/* --------------------------------------------------------------------
+ *  TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PB4,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PB5,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91cap9_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+	at91_set_GPIO_periph(AT91_PIN_PB4, 1);		/* TWD (SDA) */
+	at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+	at91_set_GPIO_periph(AT91_PIN_PB5, 1);		/* TWCK (SCL) */
+	at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+	i2c_register_board_info(0, devices, nr_devices);
+	platform_device_register(&at91cap9_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_TWI,
+		.end	= AT91CAP9_BASE_TWI + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_TWI,
+		.end	= AT91CAP9_ID_TWI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_twi_device = {
+	.name		= "at91_i2c",
+	.id		= -1,
+	.resource	= twi_resources,
+	.num_resources	= ARRAY_SIZE(twi_resources),
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+	/* pins used for TWI interface */
+	at91_set_B_periph(AT91_PIN_PB4, 0);		/* TWD */
+	at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+	at91_set_B_periph(AT91_PIN_PB5, 0);		/* TWCK */
+	at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+	i2c_register_board_info(0, devices, nr_devices);
+	platform_device_register(&at91cap9_twi_device);
+}
+#else
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+/* --------------------------------------------------------------------
+ *  SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_SPI0,
+		.end	= AT91CAP9_BASE_SPI0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_SPI0,
+		.end	= AT91CAP9_ID_SPI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_spi0_device = {
+	.name		= "atmel_spi",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= spi0_resources,
+	.num_resources	= ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 };
+
+static struct resource spi1_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_SPI1,
+		.end	= AT91CAP9_BASE_SPI1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_SPI1,
+		.end	= AT91CAP9_ID_SPI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_spi1_device = {
+	.name		= "atmel_spi",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= spi1_resources,
+	.num_resources	= ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+	int i;
+	unsigned long cs_pin;
+	short enable_spi0 = 0;
+	short enable_spi1 = 0;
+
+	/* Choose SPI chip-selects */
+	for (i = 0; i < nr_devices; i++) {
+		if (devices[i].controller_data)
+			cs_pin = (unsigned long) devices[i].controller_data;
+		else if (devices[i].bus_num == 0)
+			cs_pin = spi0_standard_cs[devices[i].chip_select];
+		else
+			cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+		if (devices[i].bus_num == 0)
+			enable_spi0 = 1;
+		else
+			enable_spi1 = 1;
+
+		/* enable chip-select pin */
+		at91_set_gpio_output(cs_pin, 1);
+
+		/* pass chip-select pin to driver */
+		devices[i].controller_data = (void *) cs_pin;
+	}
+
+	spi_register_board_info(devices, nr_devices);
+
+	/* Configure SPI bus(es) */
+	if (enable_spi0) {
+		at91_set_B_periph(AT91_PIN_PA0, 0);	/* SPI0_MISO */
+		at91_set_B_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
+		at91_set_B_periph(AT91_PIN_PA2, 0);	/* SPI0_SPCK */
+
+		at91_clock_associate("spi0_clk", &at91cap9_spi0_device.dev, "spi_clk");
+		platform_device_register(&at91cap9_spi0_device);
+	}
+	if (enable_spi1) {
+		at91_set_A_periph(AT91_PIN_PB12, 0);	/* SPI1_MISO */
+		at91_set_A_periph(AT91_PIN_PB13, 0);	/* SPI1_MOSI */
+		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_SPCK */
+
+		at91_clock_associate("spi1_clk", &at91cap9_spi1_device.dev, "spi_clk");
+		platform_device_register(&at91cap9_spi1_device);
+	}
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  RTT
+ * -------------------------------------------------------------------- */
+
+static struct platform_device at91cap9_rtt_device = {
+	.name		= "at91_rtt",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+static void __init at91_add_device_rtt(void)
+{
+	platform_device_register(&at91cap9_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+static struct platform_device at91cap9_wdt_device = {
+	.name		= "at91_wdt",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+	platform_device_register(&at91cap9_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  AC97
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
+static u64 ac97_dmamask = DMA_BIT_MASK(32);
+static struct atmel_ac97_data ac97_data;
+
+static struct resource ac97_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_AC97C,
+		.end	= AT91CAP9_BASE_AC97C + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_AC97C,
+		.end	= AT91CAP9_ID_AC97C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_ac97_device = {
+	.name		= "ac97c",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &ac97_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &ac97_data,
+	},
+	.resource	= ac97_resources,
+	.num_resources	= ARRAY_SIZE(ac97_resources),
+};
+
+void __init at91_add_device_ac97(struct atmel_ac97_data *data)
+{
+	if (!data)
+		return;
+
+	at91_set_A_periph(AT91_PIN_PA6, 0);	/* AC97FS */
+	at91_set_A_periph(AT91_PIN_PA7, 0);	/* AC97CK */
+	at91_set_A_periph(AT91_PIN_PA8, 0);	/* AC97TX */
+	at91_set_A_periph(AT91_PIN_PA9, 0);	/* AC97RX */
+
+	/* reset */
+	if (data->reset_pin)
+		at91_set_gpio_output(data->reset_pin, 0);
+
+	ac97_data = *data;
+	platform_device_register(&at91cap9_ac97_device);
+}
+#else
+void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  LCD Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
+static struct atmel_lcdfb_info lcdc_data;
+
+static struct resource lcdc_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_LCDC_BASE,
+		.end	= AT91CAP9_LCDC_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_LCDC,
+		.end	= AT91CAP9_ID_LCDC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_lcdc_device = {
+	.name		= "atmel_lcdfb",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &lcdc_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &lcdc_data,
+	},
+	.resource	= lcdc_resources,
+	.num_resources	= ARRAY_SIZE(lcdc_resources),
+};
+
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+{
+	if (!data)
+		return;
+
+	at91_set_A_periph(AT91_PIN_PC1, 0);	/* LCDHSYNC */
+	at91_set_A_periph(AT91_PIN_PC2, 0);	/* LCDDOTCK */
+	at91_set_A_periph(AT91_PIN_PC3, 0);	/* LCDDEN */
+	at91_set_B_periph(AT91_PIN_PB9, 0);	/* LCDCC */
+	at91_set_A_periph(AT91_PIN_PC6, 0);	/* LCDD2 */
+	at91_set_A_periph(AT91_PIN_PC7, 0);	/* LCDD3 */
+	at91_set_A_periph(AT91_PIN_PC8, 0);	/* LCDD4 */
+	at91_set_A_periph(AT91_PIN_PC9, 0);	/* LCDD5 */
+	at91_set_A_periph(AT91_PIN_PC10, 0);	/* LCDD6 */
+	at91_set_A_periph(AT91_PIN_PC11, 0);	/* LCDD7 */
+	at91_set_A_periph(AT91_PIN_PC14, 0);	/* LCDD10 */
+	at91_set_A_periph(AT91_PIN_PC15, 0);	/* LCDD11 */
+	at91_set_A_periph(AT91_PIN_PC16, 0);	/* LCDD12 */
+	at91_set_A_periph(AT91_PIN_PC17, 0);	/* LCDD13 */
+	at91_set_A_periph(AT91_PIN_PC18, 0);	/* LCDD14 */
+	at91_set_A_periph(AT91_PIN_PC19, 0);	/* LCDD15 */
+	at91_set_A_periph(AT91_PIN_PC22, 0);	/* LCDD18 */
+	at91_set_A_periph(AT91_PIN_PC23, 0);	/* LCDD19 */
+	at91_set_A_periph(AT91_PIN_PC24, 0);	/* LCDD20 */
+	at91_set_A_periph(AT91_PIN_PC25, 0);	/* LCDD21 */
+	at91_set_A_periph(AT91_PIN_PC26, 0);	/* LCDD22 */
+	at91_set_A_periph(AT91_PIN_PC27, 0);	/* LCDD23 */
+
+	lcdc_data = *data;
+	platform_device_register(&at91_lcdc_device);
+}
+#else
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_SSC0,
+		.end	= AT91CAP9_BASE_SSC0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_SSC0,
+		.end	= AT91CAP9_ID_SSC0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_ssc0_device = {
+	.name	= "ssc",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ssc0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc0_resources,
+	.num_resources	= ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PB0, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PB1, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PB2, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PB3, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PB4, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PB5, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_SSC1,
+		.end	= AT91CAP9_BASE_SSC1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_SSC1,
+		.end	= AT91CAP9_ID_SSC1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91cap9_ssc1_device = {
+	.name	= "ssc",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ssc1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc1_resources,
+	.num_resources	= ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PB6, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PB7, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PB8, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PB9, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PB10, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PB11, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver.  For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	/*
+	 * NOTE: caller is responsible for passing information matching
+	 * "pins" to whatever will be using each particular controller.
+	 */
+	switch (id) {
+	case AT91CAP9_ID_SSC0:
+		pdev = &at91cap9_ssc0_device;
+		configure_ssc0_pins(pins);
+		at91_clock_associate("ssc0_clk", &pdev->dev, "ssc");
+		break;
+	case AT91CAP9_ID_SSC1:
+		pdev = &at91cap9_ssc1_device;
+		configure_ssc1_pins(pins);
+		at91_clock_associate("ssc1_clk", &pdev->dev, "ssc");
+		break;
+	default:
+		return;
+	}
+
+	platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+	[0] = {
+		.start	= AT91_VA_BASE_SYS + AT91_DBGU,
+		.end	= AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91_ID_SYS,
+		.end	= AT91_ID_SYS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data dbgu_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,		/* DBGU not capable of receive DMA */
+	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91cap9_dbgu_device = {
+	.name		= "atmel_usart",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &dbgu_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &dbgu_data,
+	},
+	.resource	= dbgu_resources,
+	.num_resources	= ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+	at91_set_A_periph(AT91_PIN_PC30, 0);		/* DRXD */
+	at91_set_A_periph(AT91_PIN_PC31, 1);		/* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_US0,
+		.end	= AT91CAP9_BASE_US0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_US0,
+		.end	= AT91CAP9_ID_US0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart0_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91cap9_uart0_device = {
+	.name		= "atmel_usart",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &uart0_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart0_data,
+	},
+	.resource	= uart0_resources,
+	.num_resources	= ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PA22, 1);		/* TXD0 */
+	at91_set_A_periph(AT91_PIN_PA23, 0);		/* RXD0 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PA24, 0);	/* RTS0 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PA25, 0);	/* CTS0 */
+}
+
+static struct resource uart1_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_US1,
+		.end	= AT91CAP9_BASE_US1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_US1,
+		.end	= AT91CAP9_ID_US1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart1_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91cap9_uart1_device = {
+	.name		= "atmel_usart",
+	.id		= 2,
+	.dev		= {
+				.dma_mask		= &uart1_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart1_data,
+	},
+	.resource	= uart1_resources,
+	.num_resources	= ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PD0, 1);		/* TXD1 */
+	at91_set_A_periph(AT91_PIN_PD1, 0);		/* RXD1 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PD7, 0);	/* RTS1 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PD8, 0);	/* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+	[0] = {
+		.start	= AT91CAP9_BASE_US2,
+		.end	= AT91CAP9_BASE_US2 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91CAP9_ID_US2,
+		.end	= AT91CAP9_ID_US2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart2_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91cap9_uart2_device = {
+	.name		= "atmel_usart",
+	.id		= 3,
+	.dev		= {
+				.dma_mask		= &uart2_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart2_data,
+	},
+	.resource	= uart2_resources,
+	.num_resources	= ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PD2, 1);		/* TXD2 */
+	at91_set_A_periph(AT91_PIN_PD3, 0);		/* RXD2 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PD5, 0);	/* RTS2 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PD6, 0);	/* CTS2 */
+}
+
+static struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
+struct platform_device *atmel_default_console_device;	/* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	switch (id) {
+		case 0:		/* DBGU */
+			pdev = &at91cap9_dbgu_device;
+			configure_dbgu_pins();
+			at91_clock_associate("mck", &pdev->dev, "usart");
+			break;
+		case AT91CAP9_ID_US0:
+			pdev = &at91cap9_uart0_device;
+			configure_usart0_pins(pins);
+			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+			break;
+		case AT91CAP9_ID_US1:
+			pdev = &at91cap9_uart1_device;
+			configure_usart1_pins(pins);
+			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+			break;
+		case AT91CAP9_ID_US2:
+			pdev = &at91cap9_uart2_device;
+			configure_usart2_pins(pins);
+			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+			break;
+		default:
+			return;
+	}
+	pdev->id = portnr;		/* update to mapped ID */
+
+	if (portnr < ATMEL_MAX_UART)
+		at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+	if (portnr < ATMEL_MAX_UART)
+		atmel_default_console_device = at91_uarts[portnr];
+	if (!atmel_default_console_device)
+		printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
+void __init at91_add_device_serial(void)
+{
+	int i;
+
+	for (i = 0; i < ATMEL_MAX_UART; i++) {
+		if (at91_uarts[i])
+			platform_device_register(at91_uarts[i]);
+	}
+}
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+	at91_add_device_rtt();
+	at91_add_device_watchdog();
+	return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 2cad2bf..d688c1d 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -301,28 +301,28 @@
 static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
 	7,	/* Advanced Interrupt Controller (FIQ) */
 	7,	/* System Peripherals */
-	0,	/* Parallel IO Controller A */
-	0,	/* Parallel IO Controller B */
-	0,	/* Parallel IO Controller C */
-	0,	/* Parallel IO Controller D */
-	6,	/* USART 0 */
-	6,	/* USART 1 */
-	6,	/* USART 2 */
-	6,	/* USART 3 */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C */
+	1,	/* Parallel IO Controller D */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	5,	/* USART 3 */
 	0,	/* Multimedia Card Interface */
-	4,	/* USB Device Port */
-	0,	/* Two-Wire Interface */
-	6,	/* Serial Peripheral Interface */
-	5,	/* Serial Synchronous Controller 0 */
-	5,	/* Serial Synchronous Controller 1 */
-	5,	/* Serial Synchronous Controller 2 */
+	2,	/* USB Device Port */
+	6,	/* Two-Wire Interface */
+	5,	/* Serial Peripheral Interface */
+	4,	/* Serial Synchronous Controller 0 */
+	4,	/* Serial Synchronous Controller 1 */
+	4,	/* Serial Synchronous Controller 2 */
 	0,	/* Timer Counter 0 */
 	0,	/* Timer Counter 1 */
 	0,	/* Timer Counter 2 */
 	0,	/* Timer Counter 3 */
 	0,	/* Timer Counter 4 */
 	0,	/* Timer Counter 5 */
-	3,	/* USB Host port */
+	2,	/* USB Host port */
 	3,	/* Ethernet MAC */
 	0,	/* Advanced Interrupt Controller (IRQ0) */
 	0,	/* Advanced Interrupt Controller (IRQ1) */
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 9296833..ef6aeb8 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -13,6 +13,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
@@ -29,7 +30,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static u64 ohci_dmamask = 0xffffffffUL;
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
 static struct at91_usbh_data usbh_data;
 
 static struct resource usbh_resources[] = {
@@ -50,7 +51,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &ohci_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &usbh_data,
 	},
 	.resource	= usbh_resources,
@@ -125,7 +126,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE)
-static u64 eth_dmamask = 0xffffffffUL;
+static u64 eth_dmamask = DMA_BIT_MASK(32);
 static struct at91_eth_data eth_data;
 
 static struct resource eth_resources[] = {
@@ -146,7 +147,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &eth_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &eth_data,
 	},
 	.resource	= eth_resources,
@@ -285,7 +286,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
-static u64 mmc_dmamask = 0xffffffffUL;
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
 static struct at91_mmc_data mmc_data;
 
 static struct resource mmc_resources[] = {
@@ -306,7 +307,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &mmc_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &mmc_data,
 	},
 	.resource	= mmc_resources,
@@ -375,7 +376,7 @@
 static struct resource nand_resources[] = {
 	{
 		.start	= NAND_BASE,
-		.end	= NAND_BASE + SZ_8M - 1,
+		.end	= NAND_BASE + SZ_256M - 1,
 		.flags	= IORESOURCE_MEM,
 	}
 };
@@ -513,7 +514,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = 0xffffffffUL;
+static u64 spi_dmamask = DMA_BIT_MASK(32);
 
 static struct resource spi_resources[] = {
 	[0] = {
@@ -533,7 +534,7 @@
 	.id		= 0,
 	.dev		= {
 				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.resource	= spi_resources,
 	.num_resources	= ARRAY_SIZE(spi_resources),
@@ -557,8 +558,11 @@
 		else
 			cs_pin = spi_standard_cs[devices[i].chip_select];
 
-		/* enable chip-select pin */
-		at91_set_gpio_output(cs_pin, 1);
+		if (devices[i].chip_select == 0)	/* for CS0 errata */
+			at91_set_A_periph(cs_pin, 0);
+		else
+			at91_set_gpio_output(cs_pin, 1);
+
 
 		/* pass chip-select pin to driver */
 		devices[i].controller_data = (void *) cs_pin;
@@ -613,24 +617,175 @@
 
 
 /* --------------------------------------------------------------------
- *  LEDs
+ *  SSC -- Synchronous Serial Controller
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_LEDS)
-u8 at91_leds_cpu;
-u8 at91_leds_timer;
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
 
-void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+static struct resource ssc0_resources[] = {
+	[0] = {
+		.start	= AT91RM9200_BASE_SSC0,
+		.end	= AT91RM9200_BASE_SSC0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91RM9200_ID_SSC0,
+		.end	= AT91RM9200_ID_SSC0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91rm9200_ssc0_device = {
+	.name	= "ssc",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ssc0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc0_resources,
+	.num_resources	= ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
 {
-	/* Enable GPIO to access the LEDs */
-	at91_set_gpio_output(cpu_led, 1);
-	at91_set_gpio_output(timer_led, 1);
-
-	at91_leds_cpu	= cpu_led;
-	at91_leds_timer	= timer_led;
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PB0, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PB1, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PB2, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PB3, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PB4, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PB5, 1);
 }
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+	[0] = {
+		.start	= AT91RM9200_BASE_SSC1,
+		.end	= AT91RM9200_BASE_SSC1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91RM9200_ID_SSC1,
+		.end	= AT91RM9200_ID_SSC1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91rm9200_ssc1_device = {
+	.name	= "ssc",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ssc1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc1_resources,
+	.num_resources	= ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PB6, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PB7, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PB8, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PB9, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PB10, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PB11, 1);
+}
+
+static u64 ssc2_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc2_resources[] = {
+	[0] = {
+		.start	= AT91RM9200_BASE_SSC2,
+		.end	= AT91RM9200_BASE_SSC2 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91RM9200_ID_SSC2,
+		.end	= AT91RM9200_ID_SSC2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91rm9200_ssc2_device = {
+	.name	= "ssc",
+	.id	= 2,
+	.dev	= {
+		.dma_mask		= &ssc2_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc2_resources,
+	.num_resources	= ARRAY_SIZE(ssc2_resources),
+};
+
+static inline void configure_ssc2_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PB12, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PB13, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PB14, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PB15, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PB16, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PB17, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver.  For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	/*
+	 * NOTE: caller is responsible for passing information matching
+	 * "pins" to whatever will be using each particular controller.
+	 */
+	switch (id) {
+	case AT91RM9200_ID_SSC0:
+		pdev = &at91rm9200_ssc0_device;
+		configure_ssc0_pins(pins);
+		at91_clock_associate("ssc0_clk", &pdev->dev, "ssc");
+		break;
+	case AT91RM9200_ID_SSC1:
+		pdev = &at91rm9200_ssc1_device;
+		configure_ssc1_pins(pins);
+		at91_clock_associate("ssc1_clk", &pdev->dev, "ssc");
+		break;
+	case AT91RM9200_ID_SSC2:
+		pdev = &at91rm9200_ssc2_device;
+		configure_ssc2_pins(pins);
+		at91_clock_associate("ssc2_clk", &pdev->dev, "ssc");
+		break;
+	default:
+		return;
+	}
+
+	platform_device_register(pdev);
+}
+
 #else
-void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #endif
 
 
@@ -658,12 +813,15 @@
 	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91rm9200_dbgu_device = {
 	.name		= "atmel_usart",
 	.id		= 0,
 	.dev		= {
-				.platform_data	= &dbgu_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &dbgu_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &dbgu_data,
 	},
 	.resource	= dbgu_resources,
 	.num_resources	= ARRAY_SIZE(dbgu_resources),
@@ -693,28 +851,35 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91rm9200_uart0_device = {
 	.name		= "atmel_usart",
 	.id		= 1,
 	.dev		= {
-				.platform_data	= &uart0_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart0_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart0_data,
 	},
 	.resource	= uart0_resources,
 	.num_resources	= ARRAY_SIZE(uart0_resources),
 };
 
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PA17, 1);		/* TXD0 */
 	at91_set_A_periph(AT91_PIN_PA18, 0);		/* RXD0 */
-	at91_set_A_periph(AT91_PIN_PA20, 0);		/* CTS0 */
 
-	/*
-	 * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21.
-	 *  We need to drive the pin manually.  Default is off (RTS is active low).
-	 */
-	at91_set_gpio_output(AT91_PIN_PA21, 1);
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PA20, 0);	/* CTS0 */
+
+	if (pins & ATMEL_UART_RTS) {
+		/*
+		 * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21.
+		 *  We need to drive the pin manually.  Default is off (RTS is active low).
+		 */
+		at91_set_gpio_output(AT91_PIN_PA21, 1);
+	}
 }
 
 static struct resource uart1_resources[] = {
@@ -735,27 +900,37 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91rm9200_uart1_device = {
 	.name		= "atmel_usart",
 	.id		= 2,
 	.dev		= {
-				.platform_data	= &uart1_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart1_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart1_data,
 	},
 	.resource	= uart1_resources,
 	.num_resources	= ARRAY_SIZE(uart1_resources),
 };
 
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(unsigned pins)
 {
-	at91_set_A_periph(AT91_PIN_PB18, 0);		/* RI1 */
-	at91_set_A_periph(AT91_PIN_PB19, 0);		/* DTR1 */
 	at91_set_A_periph(AT91_PIN_PB20, 1);		/* TXD1 */
 	at91_set_A_periph(AT91_PIN_PB21, 0);		/* RXD1 */
-	at91_set_A_periph(AT91_PIN_PB23, 0);		/* DCD1 */
-	at91_set_A_periph(AT91_PIN_PB24, 0);		/* CTS1 */
-	at91_set_A_periph(AT91_PIN_PB25, 0);		/* DSR1 */
-	at91_set_A_periph(AT91_PIN_PB26, 0);		/* RTS1 */
+
+	if (pins & ATMEL_UART_RI)
+		at91_set_A_periph(AT91_PIN_PB18, 0);	/* RI1 */
+	if (pins & ATMEL_UART_DTR)
+		at91_set_A_periph(AT91_PIN_PB19, 0);	/* DTR1 */
+	if (pins & ATMEL_UART_DCD)
+		at91_set_A_periph(AT91_PIN_PB23, 0);	/* DCD1 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PB24, 0);	/* CTS1 */
+	if (pins & ATMEL_UART_DSR)
+		at91_set_A_periph(AT91_PIN_PB25, 0);	/* DSR1 */
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PB26, 0);	/* RTS1 */
 }
 
 static struct resource uart2_resources[] = {
@@ -776,21 +951,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91rm9200_uart2_device = {
 	.name		= "atmel_usart",
 	.id		= 3,
 	.dev		= {
-				.platform_data	= &uart2_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart2_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart2_data,
 	},
 	.resource	= uart2_resources,
 	.num_resources	= ARRAY_SIZE(uart2_resources),
 };
 
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PA22, 0);		/* RXD2 */
 	at91_set_A_periph(AT91_PIN_PA23, 1);		/* TXD2 */
+
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PA30, 0);	/* CTS2 */
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PA31, 0);	/* RTS2 */
 }
 
 static struct resource uart3_resources[] = {
@@ -811,27 +994,35 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart3_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91rm9200_uart3_device = {
 	.name		= "atmel_usart",
 	.id		= 4,
 	.dev		= {
-				.platform_data	= &uart3_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart3_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart3_data,
 	},
 	.resource	= uart3_resources,
 	.num_resources	= ARRAY_SIZE(uart3_resources),
 };
 
-static inline void configure_usart3_pins(void)
+static inline void configure_usart3_pins(unsigned pins)
 {
 	at91_set_B_periph(AT91_PIN_PA5, 1);		/* TXD3 */
 	at91_set_B_periph(AT91_PIN_PA6, 0);		/* RXD3 */
+
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PB1, 0);	/* CTS3 */
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PB0, 0);	/* RTS3 */
 }
 
-struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
+static struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
 struct platform_device *atmel_default_console_device;	/* the serial console device */
 
-void __init at91_init_serial(struct at91_uart_config *config)
+void __init __deprecated at91_init_serial(struct at91_uart_config *config)
 {
 	int i;
 
@@ -839,22 +1030,22 @@
 	for (i = 0; i < config->nr_tty; i++) {
 		switch (config->tty_map[i]) {
 			case 0:
-				configure_usart0_pins();
+				configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
 				at91_uarts[i] = &at91rm9200_uart0_device;
 				at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart");
 				break;
 			case 1:
-				configure_usart1_pins();
+				configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
 				at91_uarts[i] = &at91rm9200_uart1_device;
 				at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart");
 				break;
 			case 2:
-				configure_usart2_pins();
+				configure_usart2_pins(0);
 				at91_uarts[i] = &at91rm9200_uart2_device;
 				at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart");
 				break;
 			case 3:
-				configure_usart3_pins();
+				configure_usart3_pins(0);
 				at91_uarts[i] = &at91rm9200_uart3_device;
 				at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart");
 				break;
@@ -876,6 +1067,53 @@
 		printk(KERN_INFO "AT91: No default serial console defined.\n");
 }
 
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	switch (id) {
+		case 0:		/* DBGU */
+			pdev = &at91rm9200_dbgu_device;
+			configure_dbgu_pins();
+			at91_clock_associate("mck", &pdev->dev, "usart");
+			break;
+		case AT91RM9200_ID_US0:
+			pdev = &at91rm9200_uart0_device;
+			configure_usart0_pins(pins);
+			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+			break;
+		case AT91RM9200_ID_US1:
+			pdev = &at91rm9200_uart1_device;
+			configure_usart1_pins(pins);
+			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+			break;
+		case AT91RM9200_ID_US2:
+			pdev = &at91rm9200_uart2_device;
+			configure_usart2_pins(pins);
+			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+			break;
+		case AT91RM9200_ID_US3:
+			pdev = &at91rm9200_uart3_device;
+			configure_usart3_pins(pins);
+			at91_clock_associate("usart3_clk", &pdev->dev, "usart");
+			break;
+		default:
+			return;
+	}
+	pdev->id = portnr;		/* update to mapped ID */
+
+	if (portnr < ATMEL_MAX_UART)
+		at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+	if (portnr < ATMEL_MAX_UART)
+		atmel_default_console_device = at91_uarts[portnr];
+	if (!atmel_default_console_device)
+		printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
 void __init at91_add_device_serial(void)
 {
 	int i;
@@ -886,7 +1124,9 @@
 	}
 }
 #else
-void __init at91_init_serial(struct at91_uart_config *config) {}
+void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
 #endif
 
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index e47381e..18d0661 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -327,30 +327,30 @@
 static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
 	7,	/* Advanced Interrupt Controller */
 	7,	/* System Peripherals */
-	0,	/* Parallel IO Controller A */
-	0,	/* Parallel IO Controller B */
-	0,	/* Parallel IO Controller C */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C */
 	0,	/* Analog-to-Digital Converter */
-	6,	/* USART 0 */
-	6,	/* USART 1 */
-	6,	/* USART 2 */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
 	0,	/* Multimedia Card Interface */
-	4,	/* USB Device Port */
-	0,	/* Two-Wire Interface */
-	6,	/* Serial Peripheral Interface 0 */
-	6,	/* Serial Peripheral Interface 1 */
+	2,	/* USB Device Port */
+	6,	/* Two-Wire Interface */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
 	5,	/* Serial Synchronous Controller */
 	0,
 	0,
 	0,	/* Timer Counter 0 */
 	0,	/* Timer Counter 1 */
 	0,	/* Timer Counter 2 */
-	3,	/* USB Host port */
+	2,	/* USB Host port */
 	3,	/* Ethernet */
 	0,	/* Image Sensor Interface */
-	6,	/* USART 3 */
-	6,	/* USART 4 */
-	6,	/* USART 5 */
+	5,	/* USART 3 */
+	5,	/* USART 4 */
+	5,	/* USART 5 */
 	0,	/* Timer Counter 3 */
 	0,	/* Timer Counter 4 */
 	0,	/* Timer Counter 5 */
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 3091bf4..105f840 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -12,6 +12,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
@@ -29,7 +30,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static u64 ohci_dmamask = 0xffffffffUL;
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
 static struct at91_usbh_data usbh_data;
 
 static struct resource usbh_resources[] = {
@@ -50,7 +51,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &ohci_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &usbh_data,
 	},
 	.resource	= usbh_resources,
@@ -125,7 +126,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
-static u64 eth_dmamask = 0xffffffffUL;
+static u64 eth_dmamask = DMA_BIT_MASK(32);
 static struct at91_eth_data eth_data;
 
 static struct resource eth_resources[] = {
@@ -146,7 +147,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &eth_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &eth_data,
 	},
 	.resource	= eth_resources,
@@ -199,7 +200,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
-static u64 mmc_dmamask = 0xffffffffUL;
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
 static struct at91_mmc_data mmc_data;
 
 static struct resource mmc_resources[] = {
@@ -220,7 +221,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &mmc_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &mmc_data,
 	},
 	.resource	= mmc_resources,
@@ -289,7 +290,7 @@
 static struct resource nand_resources[] = {
 	{
 		.start	= NAND_BASE,
-		.end	= NAND_BASE + SZ_8M - 1,
+		.end	= NAND_BASE + SZ_256M - 1,
 		.flags	= IORESOURCE_MEM,
 	}
 };
@@ -312,7 +313,7 @@
 		return;
 
 	csa = at91_sys_read(AT91_MATRIX_EBICSA);
-	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC);
+	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
 
 	/* set the bus interface characteristics */
 	at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
@@ -431,7 +432,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = 0xffffffffUL;
+static u64 spi_dmamask = DMA_BIT_MASK(32);
 
 static struct resource spi0_resources[] = {
 	[0] = {
@@ -451,7 +452,7 @@
 	.id		= 0,
 	.dev		= {
 				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.resource	= spi0_resources,
 	.num_resources	= ARRAY_SIZE(spi0_resources),
@@ -477,7 +478,7 @@
 	.id		= 1,
 	.dev		= {
 				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.resource	= spi1_resources,
 	.num_resources	= ARRAY_SIZE(spi1_resources),
@@ -539,24 +540,126 @@
 
 
 /* --------------------------------------------------------------------
- *  LEDs
+ *  RTT
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_LEDS)
-u8 at91_leds_cpu;
-u8 at91_leds_timer;
+static struct resource rtt_resources[] = {
+	{
+		.start	= AT91_BASE_SYS + AT91_RTT,
+		.end	= AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
 
-void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+static struct platform_device at91sam9260_rtt_device = {
+	.name		= "at91_rtt",
+	.id		= -1,
+	.resource	= rtt_resources,
+	.num_resources	= ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
 {
-	/* Enable GPIO to access the LEDs */
-	at91_set_gpio_output(cpu_led, 1);
-	at91_set_gpio_output(timer_led, 1);
+	platform_device_register(&at91sam9260_rtt_device);
+}
 
-	at91_leds_cpu	= cpu_led;
-	at91_leds_timer	= timer_led;
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+static struct platform_device at91sam9260_wdt_device = {
+	.name		= "at91_wdt",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+	platform_device_register(&at91sam9260_wdt_device);
 }
 #else
-void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc_resources[] = {
+	[0] = {
+		.start	= AT91SAM9260_BASE_SSC,
+		.end	= AT91SAM9260_BASE_SSC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9260_ID_SSC,
+		.end	= AT91SAM9260_ID_SSC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9260_ssc_device = {
+	.name	= "ssc",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ssc_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc_resources,
+	.num_resources	= ARRAY_SIZE(ssc_resources),
+};
+
+static inline void configure_ssc_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PB17, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PB16, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PB18, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PB19, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PB20, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PB21, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver.  For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	/*
+	 * NOTE: caller is responsible for passing information matching
+	 * "pins" to whatever will be using each particular controller.
+	 */
+	switch (id) {
+	case AT91SAM9260_ID_SSC:
+		pdev = &at91sam9260_ssc_device;
+		configure_ssc_pins(pins);
+		at91_clock_associate("ssc_clk", &pdev->dev, "pclk");
+		break;
+	default:
+		return;
+	}
+
+	platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #endif
 
 
@@ -583,12 +686,15 @@
 	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9260_dbgu_device = {
 	.name		= "atmel_usart",
 	.id		= 0,
 	.dev		= {
-				.platform_data	= &dbgu_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &dbgu_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &dbgu_data,
 	},
 	.resource	= dbgu_resources,
 	.num_resources	= ARRAY_SIZE(dbgu_resources),
@@ -618,27 +724,37 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9260_uart0_device = {
 	.name		= "atmel_usart",
 	.id		= 1,
 	.dev		= {
-				.platform_data	= &uart0_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart0_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart0_data,
 	},
 	.resource	= uart0_resources,
 	.num_resources	= ARRAY_SIZE(uart0_resources),
 };
 
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PB4, 1);		/* TXD0 */
 	at91_set_A_periph(AT91_PIN_PB5, 0);		/* RXD0 */
-	at91_set_A_periph(AT91_PIN_PB26, 0);		/* RTS0 */
-	at91_set_A_periph(AT91_PIN_PB27, 0);		/* CTS0 */
-	at91_set_A_periph(AT91_PIN_PB24, 0);		/* DTR0 */
-	at91_set_A_periph(AT91_PIN_PB22, 0);		/* DSR0 */
-	at91_set_A_periph(AT91_PIN_PB23, 0);		/* DCD0 */
-	at91_set_A_periph(AT91_PIN_PB25, 0);		/* RI0 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PB26, 0);	/* RTS0 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PB27, 0);	/* CTS0 */
+	if (pins & ATMEL_UART_DTR)
+		at91_set_A_periph(AT91_PIN_PB24, 0);	/* DTR0 */
+	if (pins & ATMEL_UART_DSR)
+		at91_set_A_periph(AT91_PIN_PB22, 0);	/* DSR0 */
+	if (pins & ATMEL_UART_DCD)
+		at91_set_A_periph(AT91_PIN_PB23, 0);	/* DCD0 */
+	if (pins & ATMEL_UART_RI)
+		at91_set_A_periph(AT91_PIN_PB25, 0);	/* RI0 */
 }
 
 static struct resource uart1_resources[] = {
@@ -659,23 +775,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9260_uart1_device = {
 	.name		= "atmel_usart",
 	.id		= 2,
 	.dev		= {
-				.platform_data	= &uart1_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart1_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart1_data,
 	},
 	.resource	= uart1_resources,
 	.num_resources	= ARRAY_SIZE(uart1_resources),
 };
 
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PB6, 1);		/* TXD1 */
 	at91_set_A_periph(AT91_PIN_PB7, 0);		/* RXD1 */
-	at91_set_A_periph(AT91_PIN_PB28, 0);		/* RTS1 */
-	at91_set_A_periph(AT91_PIN_PB29, 0);		/* CTS1 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PB28, 0);	/* RTS1 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PB29, 0);	/* CTS1 */
 }
 
 static struct resource uart2_resources[] = {
@@ -696,21 +818,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9260_uart2_device = {
 	.name		= "atmel_usart",
 	.id		= 3,
 	.dev		= {
-				.platform_data	= &uart2_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart2_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart2_data,
 	},
 	.resource	= uart2_resources,
 	.num_resources	= ARRAY_SIZE(uart2_resources),
 };
 
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PB8, 1);		/* TXD2 */
 	at91_set_A_periph(AT91_PIN_PB9, 0);		/* RXD2 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PA4, 0);	/* RTS2 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PA5, 0);	/* CTS2 */
 }
 
 static struct resource uart3_resources[] = {
@@ -731,21 +861,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart3_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9260_uart3_device = {
 	.name		= "atmel_usart",
 	.id		= 4,
 	.dev		= {
-				.platform_data	= &uart3_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart3_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart3_data,
 	},
 	.resource	= uart3_resources,
 	.num_resources	= ARRAY_SIZE(uart3_resources),
 };
 
-static inline void configure_usart3_pins(void)
+static inline void configure_usart3_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PB10, 1);		/* TXD3 */
 	at91_set_A_periph(AT91_PIN_PB11, 0);		/* RXD3 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PC8, 0);	/* RTS3 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PC10, 0);	/* CTS3 */
 }
 
 static struct resource uart4_resources[] = {
@@ -766,12 +904,15 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart4_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9260_uart4_device = {
 	.name		= "atmel_usart",
 	.id		= 5,
 	.dev		= {
-				.platform_data	= &uart4_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart4_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart4_data,
 	},
 	.resource	= uart4_resources,
 	.num_resources	= ARRAY_SIZE(uart4_resources),
@@ -801,12 +942,15 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart5_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9260_uart5_device = {
 	.name		= "atmel_usart",
 	.id		= 6,
 	.dev		= {
-				.platform_data	= &uart5_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart5_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart5_data,
 	},
 	.resource	= uart5_resources,
 	.num_resources	= ARRAY_SIZE(uart5_resources),
@@ -818,10 +962,10 @@
 	at91_set_A_periph(AT91_PIN_PB13, 0);		/* RXD5 */
 }
 
-struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
+static struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
 struct platform_device *atmel_default_console_device;	/* the serial console device */
 
-void __init at91_init_serial(struct at91_uart_config *config)
+void __init __deprecated at91_init_serial(struct at91_uart_config *config)
 {
 	int i;
 
@@ -829,22 +973,22 @@
 	for (i = 0; i < config->nr_tty; i++) {
 		switch (config->tty_map[i]) {
 			case 0:
-				configure_usart0_pins();
+				configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
 				at91_uarts[i] = &at91sam9260_uart0_device;
 				at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart");
 				break;
 			case 1:
-				configure_usart1_pins();
+				configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
 				at91_uarts[i] = &at91sam9260_uart1_device;
 				at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart");
 				break;
 			case 2:
-				configure_usart2_pins();
+				configure_usart2_pins(0);
 				at91_uarts[i] = &at91sam9260_uart2_device;
 				at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart");
 				break;
 			case 3:
-				configure_usart3_pins();
+				configure_usart3_pins(0);
 				at91_uarts[i] = &at91sam9260_uart3_device;
 				at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart");
 				break;
@@ -876,6 +1020,63 @@
 		printk(KERN_INFO "AT91: No default serial console defined.\n");
 }
 
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	switch (id) {
+		case 0:		/* DBGU */
+			pdev = &at91sam9260_dbgu_device;
+			configure_dbgu_pins();
+			at91_clock_associate("mck", &pdev->dev, "usart");
+			break;
+		case AT91SAM9260_ID_US0:
+			pdev = &at91sam9260_uart0_device;
+			configure_usart0_pins(pins);
+			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9260_ID_US1:
+			pdev = &at91sam9260_uart1_device;
+			configure_usart1_pins(pins);
+			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9260_ID_US2:
+			pdev = &at91sam9260_uart2_device;
+			configure_usart2_pins(pins);
+			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9260_ID_US3:
+			pdev = &at91sam9260_uart3_device;
+			configure_usart3_pins(pins);
+			at91_clock_associate("usart3_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9260_ID_US4:
+			pdev = &at91sam9260_uart4_device;
+			configure_usart4_pins();
+			at91_clock_associate("usart4_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9260_ID_US5:
+			pdev = &at91sam9260_uart5_device;
+			configure_usart5_pins();
+			at91_clock_associate("usart5_clk", &pdev->dev, "usart");
+			break;
+		default:
+			return;
+	}
+	pdev->id = portnr;		/* update to mapped ID */
+
+	if (portnr < ATMEL_MAX_UART)
+		at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+	if (portnr < ATMEL_MAX_UART)
+		atmel_default_console_device = at91_uarts[portnr];
+	if (!atmel_default_console_device)
+		printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
 void __init at91_add_device_serial(void)
 {
 	int i;
@@ -886,7 +1087,9 @@
 	}
 }
 #else
-void __init at91_init_serial(struct at91_uart_config *config) {}
+void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
 #endif
 
@@ -898,6 +1101,8 @@
  */
 static int __init at91_add_standard_devices(void)
 {
+	at91_add_device_rtt();
+	at91_add_device_watchdog();
 	return 0;
 }
 
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index dfe8c39..90b87e1 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -279,25 +279,25 @@
 static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
 	7,	/* Advanced Interrupt Controller */
 	7,	/* System Peripherals */
-	0,	/* Parallel IO Controller A */
-	0,	/* Parallel IO Controller B */
-	0,	/* Parallel IO Controller C */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C */
 	0,
-	6,	/* USART 0 */
-	6,	/* USART 1 */
-	6,	/* USART 2 */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
 	0,	/* Multimedia Card Interface */
-	4,	/* USB Device Port */
-	0,	/* Two-Wire Interface */
-	6,	/* Serial Peripheral Interface 0 */
-	6,	/* Serial Peripheral Interface 1 */
-	5,	/* Serial Synchronous Controller 0 */
-	5,	/* Serial Synchronous Controller 1 */
-	5,	/* Serial Synchronous Controller 2 */
+	2,	/* USB Device Port */
+	6,	/* Two-Wire Interface */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	4,	/* Serial Synchronous Controller 0 */
+	4,	/* Serial Synchronous Controller 1 */
+	4,	/* Serial Synchronous Controller 2 */
 	0,	/* Timer Counter 0 */
 	0,	/* Timer Counter 1 */
 	0,	/* Timer Counter 2 */
-	3,	/* USB Host port */
+	2,	/* USB Host port */
 	3,	/* LCD Controller */
 	0,
 	0,
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 64979a9..2456412 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -13,6 +13,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
@@ -33,7 +34,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static u64 ohci_dmamask = 0xffffffffUL;
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
 static struct at91_usbh_data usbh_data;
 
 static struct resource usbh_resources[] = {
@@ -54,7 +55,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &ohci_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &usbh_data,
 	},
 	.resource	= usbh_resources,
@@ -106,8 +107,6 @@
 
 void __init at91_add_device_udc(struct at91_udc_data *data)
 {
-	unsigned long x;
-
 	if (!data)
 		return;
 
@@ -116,9 +115,7 @@
 		at91_set_deglitch(data->vbus_pin, 1);
 	}
 
-	/* Pullup pin is handled internally */
-	x = at91_sys_read(AT91_MATRIX_USBPUCR);
-	at91_sys_write(AT91_MATRIX_USBPUCR, x | AT91_MATRIX_USBPUCR_PUON);
+	/* Pullup pin is handled internally by USB device peripheral */
 
 	udc_data = *data;
 	platform_device_register(&at91sam9261_udc_device);
@@ -132,7 +129,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
-static u64 mmc_dmamask = 0xffffffffUL;
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
 static struct at91_mmc_data mmc_data;
 
 static struct resource mmc_resources[] = {
@@ -153,7 +150,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &mmc_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &mmc_data,
 	},
 	.resource	= mmc_resources,
@@ -232,7 +229,7 @@
 		return;
 
 	csa = at91_sys_read(AT91_MATRIX_EBICSA);
-	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC);
+	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
 
 	/* set the bus interface characteristics */
 	at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
@@ -354,7 +351,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = 0xffffffffUL;
+static u64 spi_dmamask = DMA_BIT_MASK(32);
 
 static struct resource spi0_resources[] = {
 	[0] = {
@@ -374,7 +371,7 @@
 	.id		= 0,
 	.dev		= {
 				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.resource	= spi0_resources,
 	.num_resources	= ARRAY_SIZE(spi0_resources),
@@ -400,7 +397,7 @@
 	.id		= 1,
 	.dev		= {
 				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.resource	= spi1_resources,
 	.num_resources	= ARRAY_SIZE(spi1_resources),
@@ -466,7 +463,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
-static u64 lcdc_dmamask = 0xffffffffUL;
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
 static struct atmel_lcdfb_info lcdc_data;
 
 static struct resource lcdc_resources[] = {
@@ -494,7 +491,7 @@
 	.id		= 0,
 	.dev		= {
 				.dma_mask		= &lcdc_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &lcdc_data,
 	},
 	.resource	= lcdc_resources,
@@ -507,6 +504,17 @@
 		return;
 	}
 
+#if defined(CONFIG_FB_ATMEL_STN)
+	at91_set_A_periph(AT91_PIN_PB0, 0);     /* LCDVSYNC */
+	at91_set_A_periph(AT91_PIN_PB1, 0);     /* LCDHSYNC */
+	at91_set_A_periph(AT91_PIN_PB2, 0);     /* LCDDOTCK */
+	at91_set_A_periph(AT91_PIN_PB3, 0);     /* LCDDEN */
+	at91_set_A_periph(AT91_PIN_PB4, 0);     /* LCDCC */
+	at91_set_A_periph(AT91_PIN_PB5, 0);     /* LCDD0 */
+	at91_set_A_periph(AT91_PIN_PB6, 0);     /* LCDD1 */
+	at91_set_A_periph(AT91_PIN_PB7, 0);     /* LCDD2 */
+	at91_set_A_periph(AT91_PIN_PB8, 0);     /* LCDD3 */
+#else
 	at91_set_A_periph(AT91_PIN_PB1, 0);	/* LCDHSYNC */
 	at91_set_A_periph(AT91_PIN_PB2, 0);	/* LCDDOTCK */
 	at91_set_A_periph(AT91_PIN_PB3, 0);	/* LCDDEN */
@@ -529,6 +537,7 @@
 	at91_set_B_periph(AT91_PIN_PB26, 0);	/* LCDD21 */
 	at91_set_B_periph(AT91_PIN_PB27, 0);	/* LCDD22 */
 	at91_set_B_periph(AT91_PIN_PB28, 0);	/* LCDD23 */
+#endif
 
 	lcdc_data = *data;
 	platform_device_register(&at91_lcdc_device);
@@ -539,24 +548,220 @@
 
 
 /* --------------------------------------------------------------------
- *  LEDs
+ *  RTT
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_LEDS)
-u8 at91_leds_cpu;
-u8 at91_leds_timer;
+static struct resource rtt_resources[] = {
+	{
+		.start	= AT91_BASE_SYS + AT91_RTT,
+		.end	= AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
 
-void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+static struct platform_device at91sam9261_rtt_device = {
+	.name		= "at91_rtt",
+	.id		= -1,
+	.resource	= rtt_resources,
+	.num_resources	= ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
 {
-	/* Enable GPIO to access the LEDs */
-	at91_set_gpio_output(cpu_led, 1);
-	at91_set_gpio_output(timer_led, 1);
+	platform_device_register(&at91sam9261_rtt_device);
+}
 
-	at91_leds_cpu	= cpu_led;
-	at91_leds_timer	= timer_led;
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+static struct platform_device at91sam9261_wdt_device = {
+	.name		= "at91_wdt",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+	platform_device_register(&at91sam9261_wdt_device);
 }
 #else
-void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9261_BASE_SSC0,
+		.end	= AT91SAM9261_BASE_SSC0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9261_ID_SSC0,
+		.end	= AT91SAM9261_ID_SSC0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9261_ssc0_device = {
+	.name	= "ssc",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ssc0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc0_resources,
+	.num_resources	= ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PB21, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PB22, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PB23, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PB24, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PB25, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PB26, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9261_BASE_SSC1,
+		.end	= AT91SAM9261_BASE_SSC1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9261_ID_SSC1,
+		.end	= AT91SAM9261_ID_SSC1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9261_ssc1_device = {
+	.name	= "ssc",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ssc1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc1_resources,
+	.num_resources	= ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_B_periph(AT91_PIN_PA17, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_B_periph(AT91_PIN_PA18, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_B_periph(AT91_PIN_PA19, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_B_periph(AT91_PIN_PA20, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_B_periph(AT91_PIN_PA21, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_B_periph(AT91_PIN_PA22, 1);
+}
+
+static u64 ssc2_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc2_resources[] = {
+	[0] = {
+		.start	= AT91SAM9261_BASE_SSC2,
+		.end	= AT91SAM9261_BASE_SSC2 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9261_ID_SSC2,
+		.end	= AT91SAM9261_ID_SSC2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9261_ssc2_device = {
+	.name	= "ssc",
+	.id	= 2,
+	.dev	= {
+		.dma_mask		= &ssc2_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc2_resources,
+	.num_resources	= ARRAY_SIZE(ssc2_resources),
+};
+
+static inline void configure_ssc2_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_B_periph(AT91_PIN_PC25, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_B_periph(AT91_PIN_PC26, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_B_periph(AT91_PIN_PC27, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_B_periph(AT91_PIN_PC28, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_B_periph(AT91_PIN_PC29, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_B_periph(AT91_PIN_PC30, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver.  For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	/*
+	 * NOTE: caller is responsible for passing information matching
+	 * "pins" to whatever will be using each particular controller.
+	 */
+	switch (id) {
+	case AT91SAM9261_ID_SSC0:
+		pdev = &at91sam9261_ssc0_device;
+		configure_ssc0_pins(pins);
+		at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
+		break;
+	case AT91SAM9261_ID_SSC1:
+		pdev = &at91sam9261_ssc1_device;
+		configure_ssc1_pins(pins);
+		at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
+		break;
+	case AT91SAM9261_ID_SSC2:
+		pdev = &at91sam9261_ssc2_device;
+		configure_ssc2_pins(pins);
+		at91_clock_associate("ssc2_clk", &pdev->dev, "pclk");
+		break;
+	default:
+		return;
+	}
+
+	platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #endif
 
 
@@ -584,12 +789,15 @@
 	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9261_dbgu_device = {
 	.name		= "atmel_usart",
 	.id		= 0,
 	.dev		= {
-				.platform_data	= &dbgu_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &dbgu_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &dbgu_data,
 	},
 	.resource	= dbgu_resources,
 	.num_resources	= ARRAY_SIZE(dbgu_resources),
@@ -619,23 +827,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9261_uart0_device = {
 	.name		= "atmel_usart",
 	.id		= 1,
 	.dev		= {
-				.platform_data	= &uart0_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart0_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart0_data,
 	},
 	.resource	= uart0_resources,
 	.num_resources	= ARRAY_SIZE(uart0_resources),
 };
 
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PC8, 1);		/* TXD0 */
 	at91_set_A_periph(AT91_PIN_PC9, 0);		/* RXD0 */
-	at91_set_A_periph(AT91_PIN_PC10, 0);		/* RTS0 */
-	at91_set_A_periph(AT91_PIN_PC11, 0);		/* CTS0 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PC10, 0);	/* RTS0 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PC11, 0);	/* CTS0 */
 }
 
 static struct resource uart1_resources[] = {
@@ -656,21 +870,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9261_uart1_device = {
 	.name		= "atmel_usart",
 	.id		= 2,
 	.dev		= {
-				.platform_data	= &uart1_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart1_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart1_data,
 	},
 	.resource	= uart1_resources,
 	.num_resources	= ARRAY_SIZE(uart1_resources),
 };
 
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PC12, 1);		/* TXD1 */
 	at91_set_A_periph(AT91_PIN_PC13, 0);		/* RXD1 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PA12, 0);	/* RTS1 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PA13, 0);	/* CTS1 */
 }
 
 static struct resource uart2_resources[] = {
@@ -691,27 +913,35 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9261_uart2_device = {
 	.name		= "atmel_usart",
 	.id		= 3,
 	.dev		= {
-				.platform_data	= &uart2_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart2_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart2_data,
 	},
 	.resource	= uart2_resources,
 	.num_resources	= ARRAY_SIZE(uart2_resources),
 };
 
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PC15, 0);		/* RXD2 */
 	at91_set_A_periph(AT91_PIN_PC14, 1);		/* TXD2 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PA15, 0);	/* RTS2*/
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PA16, 0);	/* CTS2 */
 }
 
-struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
+static struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
 struct platform_device *atmel_default_console_device;	/* the serial console device */
 
-void __init at91_init_serial(struct at91_uart_config *config)
+void __init __deprecated at91_init_serial(struct at91_uart_config *config)
 {
 	int i;
 
@@ -719,17 +949,17 @@
 	for (i = 0; i < config->nr_tty; i++) {
 		switch (config->tty_map[i]) {
 			case 0:
-				configure_usart0_pins();
+				configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
 				at91_uarts[i] = &at91sam9261_uart0_device;
 				at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart");
 				break;
 			case 1:
-				configure_usart1_pins();
+				configure_usart1_pins(0);
 				at91_uarts[i] = &at91sam9261_uart1_device;
 				at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart");
 				break;
 			case 2:
-				configure_usart2_pins();
+				configure_usart2_pins(0);
 				at91_uarts[i] = &at91sam9261_uart2_device;
 				at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart");
 				break;
@@ -751,6 +981,48 @@
 		printk(KERN_INFO "AT91: No default serial console defined.\n");
 }
 
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	switch (id) {
+		case 0:		/* DBGU */
+			pdev = &at91sam9261_dbgu_device;
+			configure_dbgu_pins();
+			at91_clock_associate("mck", &pdev->dev, "usart");
+			break;
+		case AT91SAM9261_ID_US0:
+			pdev = &at91sam9261_uart0_device;
+			configure_usart0_pins(pins);
+			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9261_ID_US1:
+			pdev = &at91sam9261_uart1_device;
+			configure_usart1_pins(pins);
+			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9261_ID_US2:
+			pdev = &at91sam9261_uart2_device;
+			configure_usart2_pins(pins);
+			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+			break;
+		default:
+			return;
+	}
+	pdev->id = portnr;		/* update to mapped ID */
+
+	if (portnr < ATMEL_MAX_UART)
+		at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+	if (portnr < ATMEL_MAX_UART)
+		atmel_default_console_device = at91_uarts[portnr];
+	if (!atmel_default_console_device)
+		printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
 void __init at91_add_device_serial(void)
 {
 	int i;
@@ -761,7 +1033,9 @@
 	}
 }
 #else
-void __init at91_init_serial(struct at91_uart_config *config) {}
+void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
 #endif
 
@@ -774,6 +1048,8 @@
  */
 static int __init at91_add_standard_devices(void)
 {
+	at91_add_device_rtt();
+	at91_add_device_watchdog();
 	return 0;
 }
 
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 00e27b1..a53ba0f 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -304,34 +304,34 @@
 static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
 	7,	/* Advanced Interrupt Controller (FIQ) */
 	7,	/* System Peripherals */
-	0,	/* Parallel IO Controller A */
-	0,	/* Parallel IO Controller B */
-	0,	/* Parallel IO Controller C, D and E */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C, D and E */
 	0,
 	0,
-	6,	/* USART 0 */
-	6,	/* USART 1 */
-	6,	/* USART 2 */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
 	0,	/* Multimedia Card Interface 0 */
 	0,	/* Multimedia Card Interface 1 */
-	4,	/* CAN */
-	0,	/* Two-Wire Interface */
-	6,	/* Serial Peripheral Interface 0 */
-	6,	/* Serial Peripheral Interface 1 */
-	5,	/* Serial Synchronous Controller 0 */
-	5,	/* Serial Synchronous Controller 1 */
-	6,	/* AC97 Controller */
+	3,	/* CAN */
+	6,	/* Two-Wire Interface */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	4,	/* Serial Synchronous Controller 0 */
+	4,	/* Serial Synchronous Controller 1 */
+	5,	/* AC97 Controller */
 	0,	/* Timer Counter 0, 1 and 2 */
 	0,	/* Pulse Width Modulation Controller */
 	3,	/* Ethernet */
 	0,
 	0,	/* 2D Graphic Engine */
-	3,	/* USB Device Port */
+	2,	/* USB Device Port */
 	0,	/* Image Sensor Interface */
 	3,	/* LDC Controller */
 	0,	/* DMA Controller */
 	0,
-	3,	/* USB Host port */
+	2,	/* USB Host port */
 	0,	/* Advanced Interrupt Controller (IRQ0) */
 	0,	/* Advanced Interrupt Controller (IRQ1) */
 };
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index ac329a9..0b12e1a 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -12,6 +12,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
@@ -32,7 +33,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static u64 ohci_dmamask = 0xffffffffUL;
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
 static struct at91_usbh_data usbh_data;
 
 static struct resource usbh_resources[] = {
@@ -53,7 +54,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &ohci_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &usbh_data,
 	},
 	.resource	= usbh_resources,
@@ -136,7 +137,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
-static u64 eth_dmamask = 0xffffffffUL;
+static u64 eth_dmamask = DMA_BIT_MASK(32);
 static struct at91_eth_data eth_data;
 
 static struct resource eth_resources[] = {
@@ -157,7 +158,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &eth_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &eth_data,
 	},
 	.resource	= eth_resources,
@@ -210,7 +211,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
-static u64 mmc_dmamask = 0xffffffffUL;
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
 static struct at91_mmc_data mmc0_data, mmc1_data;
 
 static struct resource mmc0_resources[] = {
@@ -231,7 +232,7 @@
 	.id		= 0,
 	.dev		= {
 				.dma_mask		= &mmc_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &mmc0_data,
 	},
 	.resource	= mmc0_resources,
@@ -256,7 +257,7 @@
 	.id		= 1,
 	.dev		= {
 				.dma_mask		= &mmc_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &mmc1_data,
 	},
 	.resource	= mmc1_resources,
@@ -382,7 +383,7 @@
 		return;
 
 	csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
-	at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC);
+	at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
 
 	/* set the bus interface characteristics */
 	at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
@@ -500,7 +501,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = 0xffffffffUL;
+static u64 spi_dmamask = DMA_BIT_MASK(32);
 
 static struct resource spi0_resources[] = {
 	[0] = {
@@ -520,7 +521,7 @@
 	.id		= 0,
 	.dev		= {
 				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.resource	= spi0_resources,
 	.num_resources	= ARRAY_SIZE(spi0_resources),
@@ -546,7 +547,7 @@
 	.id		= 1,
 	.dev		= {
 				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.resource	= spi1_resources,
 	.num_resources	= ARRAY_SIZE(spi1_resources),
@@ -612,7 +613,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
-static u64 ac97_dmamask = 0xffffffffUL;
+static u64 ac97_dmamask = DMA_BIT_MASK(32);
 static struct atmel_ac97_data ac97_data;
 
 static struct resource ac97_resources[] = {
@@ -633,7 +634,7 @@
 	.id		= 1,
 	.dev		= {
 				.dma_mask		= &ac97_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &ac97_data,
 	},
 	.resource	= ac97_resources,
@@ -667,7 +668,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
-static u64 lcdc_dmamask = 0xffffffffUL;
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
 static struct atmel_lcdfb_info lcdc_data;
 
 static struct resource lcdc_resources[] = {
@@ -688,7 +689,7 @@
 	.id		= 0,
 	.dev		= {
 				.dma_mask		= &lcdc_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &lcdc_data,
 	},
 	.resource	= lcdc_resources,
@@ -732,24 +733,242 @@
 
 
 /* --------------------------------------------------------------------
- *  LEDs
+ *  Image Sensor Interface
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_LEDS)
-u8 at91_leds_cpu;
-u8 at91_leds_timer;
+#if defined(CONFIG_VIDEO_AT91_ISI) || defined(CONFIG_VIDEO_AT91_ISI_MODULE)
 
-void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+struct resource isi_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_ISI,
+		.end	= AT91SAM9263_BASE_ISI + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_ISI,
+		.end	= AT91SAM9263_ID_ISI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_isi_device = {
+	.name		= "at91_isi",
+	.id		= -1,
+	.resource	= isi_resources,
+	.num_resources	= ARRAY_SIZE(isi_resources),
+};
+
+void __init at91_add_device_isi(void)
 {
-	/* Enable GPIO to access the LEDs */
-	at91_set_gpio_output(cpu_led, 1);
-	at91_set_gpio_output(timer_led, 1);
-
-	at91_leds_cpu	= cpu_led;
-	at91_leds_timer	= timer_led;
+	at91_set_A_periph(AT91_PIN_PE0, 0);	/* ISI_D0 */
+	at91_set_A_periph(AT91_PIN_PE1, 0);	/* ISI_D1 */
+	at91_set_A_periph(AT91_PIN_PE2, 0);	/* ISI_D2 */
+	at91_set_A_periph(AT91_PIN_PE3, 0);	/* ISI_D3 */
+	at91_set_A_periph(AT91_PIN_PE4, 0);	/* ISI_D4 */
+	at91_set_A_periph(AT91_PIN_PE5, 0);	/* ISI_D5 */
+	at91_set_A_periph(AT91_PIN_PE6, 0);	/* ISI_D6 */
+	at91_set_A_periph(AT91_PIN_PE7, 0);	/* ISI_D7 */
+	at91_set_A_periph(AT91_PIN_PE8, 0);	/* ISI_PCK */
+	at91_set_A_periph(AT91_PIN_PE9, 0);	/* ISI_HSYNC */
+	at91_set_A_periph(AT91_PIN_PE10, 0);	/* ISI_VSYNC */
+	at91_set_B_periph(AT91_PIN_PE11, 0);	/* ISI_MCK (PCK3) */
+	at91_set_B_periph(AT91_PIN_PE12, 0);	/* ISI_PD8 */
+	at91_set_B_periph(AT91_PIN_PE13, 0);	/* ISI_PD9 */
+	at91_set_B_periph(AT91_PIN_PE14, 0);	/* ISI_PD10 */
+	at91_set_B_periph(AT91_PIN_PE15, 0);	/* ISI_PD11 */
 }
 #else
-void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+void __init at91_add_device_isi(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt0_resources[] = {
+	{
+		.start	= AT91_BASE_SYS + AT91_RTT0,
+		.end	= AT91_BASE_SYS + AT91_RTT0 + SZ_16 - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91sam9263_rtt0_device = {
+	.name		= "at91_rtt",
+	.id		= 0,
+	.resource	= rtt0_resources,
+	.num_resources	= ARRAY_SIZE(rtt0_resources),
+};
+
+static struct resource rtt1_resources[] = {
+	{
+		.start	= AT91_BASE_SYS + AT91_RTT1,
+		.end	= AT91_BASE_SYS + AT91_RTT1 + SZ_16 - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91sam9263_rtt1_device = {
+	.name		= "at91_rtt",
+	.id		= 1,
+	.resource	= rtt1_resources,
+	.num_resources	= ARRAY_SIZE(rtt1_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+	platform_device_register(&at91sam9263_rtt0_device);
+	platform_device_register(&at91sam9263_rtt1_device);
+}
+
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+static struct platform_device at91sam9263_wdt_device = {
+	.name		= "at91_wdt",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+	platform_device_register(&at91sam9263_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_SSC0,
+		.end	= AT91SAM9263_BASE_SSC0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_SSC0,
+		.end	= AT91SAM9263_ID_SSC0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_ssc0_device = {
+	.name	= "ssc",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ssc0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc0_resources,
+	.num_resources	= ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_B_periph(AT91_PIN_PB0, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_B_periph(AT91_PIN_PB1, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_B_periph(AT91_PIN_PB2, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_B_periph(AT91_PIN_PB3, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_B_periph(AT91_PIN_PB4, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_B_periph(AT91_PIN_PB5, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_SSC1,
+		.end	= AT91SAM9263_BASE_SSC1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_SSC1,
+		.end	= AT91SAM9263_ID_SSC1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_ssc1_device = {
+	.name	= "ssc",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ssc1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc1_resources,
+	.num_resources	= ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PB6, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PB7, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PB8, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PB9, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PB10, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PB11, 1);
+}
+
+/*
+ * Return the device node so that board init code can use it as the
+ * parent for the device node reflecting how it's used on this board.
+ *
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver.  For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	/*
+	 * NOTE: caller is responsible for passing information matching
+	 * "pins" to whatever will be using each particular controller.
+	 */
+	switch (id) {
+	case AT91SAM9263_ID_SSC0:
+		pdev = &at91sam9263_ssc0_device;
+		configure_ssc0_pins(pins);
+		at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
+		break;
+	case AT91SAM9263_ID_SSC1:
+		pdev = &at91sam9263_ssc1_device;
+		configure_ssc1_pins(pins);
+		at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
+		break;
+	default:
+		return;
+	}
+
+	platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #endif
 
 
@@ -778,12 +997,15 @@
 	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9263_dbgu_device = {
 	.name		= "atmel_usart",
 	.id		= 0,
 	.dev		= {
-				.platform_data	= &dbgu_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &dbgu_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &dbgu_data,
 	},
 	.resource	= dbgu_resources,
 	.num_resources	= ARRAY_SIZE(dbgu_resources),
@@ -813,23 +1035,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9263_uart0_device = {
 	.name		= "atmel_usart",
 	.id		= 1,
 	.dev		= {
-				.platform_data	= &uart0_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart0_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart0_data,
 	},
 	.resource	= uart0_resources,
 	.num_resources	= ARRAY_SIZE(uart0_resources),
 };
 
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PA26, 1);		/* TXD0 */
 	at91_set_A_periph(AT91_PIN_PA27, 0);		/* RXD0 */
-	at91_set_A_periph(AT91_PIN_PA28, 0);		/* RTS0 */
-	at91_set_A_periph(AT91_PIN_PA29, 0);		/* CTS0 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PA28, 0);	/* RTS0 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PA29, 0);	/* CTS0 */
 }
 
 static struct resource uart1_resources[] = {
@@ -850,23 +1078,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9263_uart1_device = {
 	.name		= "atmel_usart",
 	.id		= 2,
 	.dev		= {
-				.platform_data	= &uart1_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart1_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart1_data,
 	},
 	.resource	= uart1_resources,
 	.num_resources	= ARRAY_SIZE(uart1_resources),
 };
 
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PD0, 1);		/* TXD1 */
 	at91_set_A_periph(AT91_PIN_PD1, 0);		/* RXD1 */
-	at91_set_B_periph(AT91_PIN_PD7, 0);		/* RTS1 */
-	at91_set_B_periph(AT91_PIN_PD8, 0);		/* CTS1 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PD7, 0);	/* RTS1 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PD8, 0);	/* CTS1 */
 }
 
 static struct resource uart2_resources[] = {
@@ -887,29 +1121,35 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9263_uart2_device = {
 	.name		= "atmel_usart",
 	.id		= 3,
 	.dev		= {
-				.platform_data	= &uart2_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart2_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart2_data,
 	},
 	.resource	= uart2_resources,
 	.num_resources	= ARRAY_SIZE(uart2_resources),
 };
 
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PD2, 1);		/* TXD2 */
 	at91_set_A_periph(AT91_PIN_PD3, 0);		/* RXD2 */
-	at91_set_B_periph(AT91_PIN_PD5, 0);		/* RTS2 */
-	at91_set_B_periph(AT91_PIN_PD6, 0);		/* CTS2 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PD5, 0);	/* RTS2 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PD6, 0);	/* CTS2 */
 }
 
-struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
+static struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
 struct platform_device *atmel_default_console_device;	/* the serial console device */
 
-void __init at91_init_serial(struct at91_uart_config *config)
+void __init __deprecated at91_init_serial(struct at91_uart_config *config)
 {
 	int i;
 
@@ -917,17 +1157,17 @@
 	for (i = 0; i < config->nr_tty; i++) {
 		switch (config->tty_map[i]) {
 			case 0:
-				configure_usart0_pins();
+				configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
 				at91_uarts[i] = &at91sam9263_uart0_device;
 				at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart");
 				break;
 			case 1:
-				configure_usart1_pins();
+				configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
 				at91_uarts[i] = &at91sam9263_uart1_device;
 				at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart");
 				break;
 			case 2:
-				configure_usart2_pins();
+				configure_usart2_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
 				at91_uarts[i] = &at91sam9263_uart2_device;
 				at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart");
 				break;
@@ -949,6 +1189,48 @@
 		printk(KERN_INFO "AT91: No default serial console defined.\n");
 }
 
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	switch (id) {
+		case 0:		/* DBGU */
+			pdev = &at91sam9263_dbgu_device;
+			configure_dbgu_pins();
+			at91_clock_associate("mck", &pdev->dev, "usart");
+			break;
+		case AT91SAM9263_ID_US0:
+			pdev = &at91sam9263_uart0_device;
+			configure_usart0_pins(pins);
+			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9263_ID_US1:
+			pdev = &at91sam9263_uart1_device;
+			configure_usart1_pins(pins);
+			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9263_ID_US2:
+			pdev = &at91sam9263_uart2_device;
+			configure_usart2_pins(pins);
+			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+			break;
+		default:
+			return;
+	}
+	pdev->id = portnr;		/* update to mapped ID */
+
+	if (portnr < ATMEL_MAX_UART)
+		at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+	if (portnr < ATMEL_MAX_UART)
+		atmel_default_console_device = at91_uarts[portnr];
+	if (!atmel_default_console_device)
+		printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
 void __init at91_add_device_serial(void)
 {
 	int i;
@@ -960,6 +1242,8 @@
 }
 #else
 void __init at91_init_serial(struct at91_uart_config *config) {}
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
 #endif
 
@@ -971,6 +1255,8 @@
  */
 static int __init at91_add_standard_devices(void)
 {
+	at91_add_device_rtt();
+	at91_add_device_watchdog();
 	return 0;
 }
 
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 2bd60a3..f43b5c3 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -9,6 +9,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
@@ -29,7 +30,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
-static u64 mmc_dmamask = 0xffffffffUL;
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
 static struct at91_mmc_data mmc_data;
 
 static struct resource mmc_resources[] = {
@@ -50,7 +51,7 @@
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &mmc_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &mmc_data,
 	},
 	.resource	= mmc_resources,
@@ -247,7 +248,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = 0xffffffffUL;
+static u64 spi_dmamask = DMA_BIT_MASK(32);
 
 static struct resource spi_resources[] = {
 	[0] = {
@@ -267,7 +268,7 @@
 	.id		= 0,
 	.dev		= {
 				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.resource	= spi_resources,
 	.num_resources	= ARRAY_SIZE(spi_resources),
@@ -312,7 +313,7 @@
  * -------------------------------------------------------------------- */
 
 #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
-static u64 lcdc_dmamask = 0xffffffffUL;
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
 static struct atmel_lcdfb_info lcdc_data;
 
 static struct resource lcdc_resources[] = {
@@ -340,7 +341,7 @@
 	.id		= 0,
 	.dev		= {
 				.dma_mask		= &lcdc_dmamask,
-				.coherent_dma_mask	= 0xffffffff,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
 				.platform_data		= &lcdc_data,
 	},
 	.resource	= lcdc_resources,
@@ -384,24 +385,196 @@
 
 
 /* --------------------------------------------------------------------
- *  LEDs
+ *  RTC
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_LEDS)
-u8 at91_leds_cpu;
-u8 at91_leds_timer;
+#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
+static struct platform_device at91sam9rl_rtc_device = {
+	.name		= "at91_rtc",
+	.id		= -1,
+	.num_resources	= 0,
+};
 
-void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+static void __init at91_add_device_rtc(void)
 {
-	/* Enable GPIO to access the LEDs */
-	at91_set_gpio_output(cpu_led, 1);
-	at91_set_gpio_output(timer_led, 1);
-
-	at91_leds_cpu	= cpu_led;
-	at91_leds_timer	= timer_led;
+	platform_device_register(&at91sam9rl_rtc_device);
 }
 #else
-void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+static void __init at91_add_device_rtc(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt_resources[] = {
+	{
+		.start	= AT91_BASE_SYS + AT91_RTT,
+		.end	= AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91sam9rl_rtt_device = {
+	.name		= "at91_rtt",
+	.id		= -1,
+	.resource	= rtt_resources,
+	.num_resources	= ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+	platform_device_register(&at91sam9rl_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+static struct platform_device at91sam9rl_wdt_device = {
+	.name		= "at91_wdt",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+	platform_device_register(&at91sam9rl_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9RL_BASE_SSC0,
+		.end	= AT91SAM9RL_BASE_SSC0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9RL_ID_SSC0,
+		.end	= AT91SAM9RL_ID_SSC0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9rl_ssc0_device = {
+	.name	= "ssc",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ssc0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc0_resources,
+	.num_resources	= ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PC0, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PC1, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PA15, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PA16, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_B_periph(AT91_PIN_PA10, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_B_periph(AT91_PIN_PA22, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9RL_BASE_SSC1,
+		.end	= AT91SAM9RL_BASE_SSC1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9RL_ID_SSC1,
+		.end	= AT91SAM9RL_ID_SSC1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9rl_ssc1_device = {
+	.name	= "ssc",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ssc1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc1_resources,
+	.num_resources	= ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_B_periph(AT91_PIN_PA29, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_B_periph(AT91_PIN_PA30, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_B_periph(AT91_PIN_PA13, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_B_periph(AT91_PIN_PA14, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_B_periph(AT91_PIN_PA9, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_B_periph(AT91_PIN_PA8, 1);
+}
+
+/*
+ * Return the device node so that board init code can use it as the
+ * parent for the device node reflecting how it's used on this board.
+ *
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver.  For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	/*
+	 * NOTE: caller is responsible for passing information matching
+	 * "pins" to whatever will be using each particular controller.
+	 */
+	switch (id) {
+	case AT91SAM9RL_ID_SSC0:
+		pdev = &at91sam9rl_ssc0_device;
+		configure_ssc0_pins(pins);
+		at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
+		break;
+	case AT91SAM9RL_ID_SSC1:
+		pdev = &at91sam9rl_ssc1_device;
+		configure_ssc1_pins(pins);
+		at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
+		break;
+	default:
+		return;
+	}
+
+	platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #endif
 
 
@@ -429,12 +602,15 @@
 	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9rl_dbgu_device = {
 	.name		= "atmel_usart",
 	.id		= 0,
 	.dev		= {
-				.platform_data	= &dbgu_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &dbgu_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &dbgu_data,
 	},
 	.resource	= dbgu_resources,
 	.num_resources	= ARRAY_SIZE(dbgu_resources),
@@ -464,23 +640,37 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9rl_uart0_device = {
 	.name		= "atmel_usart",
 	.id		= 1,
 	.dev		= {
-				.platform_data	= &uart0_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart0_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart0_data,
 	},
 	.resource	= uart0_resources,
 	.num_resources	= ARRAY_SIZE(uart0_resources),
 };
 
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PA6, 1);		/* TXD0 */
 	at91_set_A_periph(AT91_PIN_PA7, 0);		/* RXD0 */
-	at91_set_A_periph(AT91_PIN_PA9, 0);		/* RTS0 */
-	at91_set_A_periph(AT91_PIN_PA10, 0);		/* CTS0 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PA9, 0);	/* RTS0 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PA10, 0);	/* CTS0 */
+	if (pins & ATMEL_UART_DSR)
+		at91_set_A_periph(AT91_PIN_PD14, 0);	/* DSR0 */
+	if (pins & ATMEL_UART_DTR)
+		at91_set_A_periph(AT91_PIN_PD15, 0);	/* DTR0 */
+	if (pins & ATMEL_UART_DCD)
+		at91_set_A_periph(AT91_PIN_PD16, 0);	/* DCD0 */
+	if (pins & ATMEL_UART_RI)
+		at91_set_A_periph(AT91_PIN_PD17, 0);	/* RI0 */
 }
 
 static struct resource uart1_resources[] = {
@@ -501,21 +691,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9rl_uart1_device = {
 	.name		= "atmel_usart",
 	.id		= 2,
 	.dev		= {
-				.platform_data	= &uart1_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart1_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart1_data,
 	},
 	.resource	= uart1_resources,
 	.num_resources	= ARRAY_SIZE(uart1_resources),
 };
 
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PA11, 1);		/* TXD1 */
 	at91_set_A_periph(AT91_PIN_PA12, 0);		/* RXD1 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PA18, 0);	/* RTS1 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PA19, 0);	/* CTS1 */
 }
 
 static struct resource uart2_resources[] = {
@@ -536,21 +734,29 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9rl_uart2_device = {
 	.name		= "atmel_usart",
 	.id		= 3,
 	.dev		= {
-				.platform_data	= &uart2_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart2_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart2_data,
 	},
 	.resource	= uart2_resources,
 	.num_resources	= ARRAY_SIZE(uart2_resources),
 };
 
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PA13, 1);		/* TXD2 */
 	at91_set_A_periph(AT91_PIN_PA14, 0);		/* RXD2 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PA29, 0);	/* RTS2 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PA30, 0);	/* CTS2 */
 }
 
 static struct resource uart3_resources[] = {
@@ -571,27 +777,35 @@
 	.use_dma_rx	= 1,
 };
 
+static u64 uart3_dmamask = DMA_BIT_MASK(32);
+
 static struct platform_device at91sam9rl_uart3_device = {
 	.name		= "atmel_usart",
 	.id		= 4,
 	.dev		= {
-				.platform_data	= &uart3_data,
-				.coherent_dma_mask = 0xffffffff,
+				.dma_mask		= &uart3_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart3_data,
 	},
 	.resource	= uart3_resources,
 	.num_resources	= ARRAY_SIZE(uart3_resources),
 };
 
-static inline void configure_usart3_pins(void)
+static inline void configure_usart3_pins(unsigned pins)
 {
 	at91_set_A_periph(AT91_PIN_PB0, 1);		/* TXD3 */
 	at91_set_A_periph(AT91_PIN_PB1, 0);		/* RXD3 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PD4, 0);	/* RTS3 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PD3, 0);	/* CTS3 */
 }
 
-struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
+static struct platform_device *at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
 struct platform_device *atmel_default_console_device;	/* the serial console device */
 
-void __init at91_init_serial(struct at91_uart_config *config)
+void __init __deprecated at91_init_serial(struct at91_uart_config *config)
 {
 	int i;
 
@@ -599,22 +813,22 @@
 	for (i = 0; i < config->nr_tty; i++) {
 		switch (config->tty_map[i]) {
 			case 0:
-				configure_usart0_pins();
+				configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
 				at91_uarts[i] = &at91sam9rl_uart0_device;
 				at91_clock_associate("usart0_clk", &at91sam9rl_uart0_device.dev, "usart");
 				break;
 			case 1:
-				configure_usart1_pins();
+				configure_usart1_pins(0);
 				at91_uarts[i] = &at91sam9rl_uart1_device;
 				at91_clock_associate("usart1_clk", &at91sam9rl_uart1_device.dev, "usart");
 				break;
 			case 2:
-				configure_usart2_pins();
+				configure_usart2_pins(0);
 				at91_uarts[i] = &at91sam9rl_uart2_device;
 				at91_clock_associate("usart2_clk", &at91sam9rl_uart2_device.dev, "usart");
 				break;
 			case 3:
-				configure_usart3_pins();
+				configure_usart3_pins(0);
 				at91_uarts[i] = &at91sam9rl_uart3_device;
 				at91_clock_associate("usart3_clk", &at91sam9rl_uart3_device.dev, "usart");
 				break;
@@ -636,6 +850,53 @@
 		printk(KERN_INFO "AT91: No default serial console defined.\n");
 }
 
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	switch (id) {
+		case 0:		/* DBGU */
+			pdev = &at91sam9rl_dbgu_device;
+			configure_dbgu_pins();
+			at91_clock_associate("mck", &pdev->dev, "usart");
+			break;
+		case AT91SAM9RL_ID_US0:
+			pdev = &at91sam9rl_uart0_device;
+			configure_usart0_pins(pins);
+			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9RL_ID_US1:
+			pdev = &at91sam9rl_uart1_device;
+			configure_usart1_pins(pins);
+			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9RL_ID_US2:
+			pdev = &at91sam9rl_uart2_device;
+			configure_usart2_pins(pins);
+			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9RL_ID_US3:
+			pdev = &at91sam9rl_uart3_device;
+			configure_usart3_pins(pins);
+			at91_clock_associate("usart3_clk", &pdev->dev, "usart");
+			break;
+		default:
+			return;
+	}
+	pdev->id = portnr;		/* update to mapped ID */
+
+	if (portnr < ATMEL_MAX_UART)
+		at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+	if (portnr < ATMEL_MAX_UART)
+		atmel_default_console_device = at91_uarts[portnr];
+	if (!atmel_default_console_device)
+		printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
 void __init at91_add_device_serial(void)
 {
 	int i;
@@ -646,7 +907,9 @@
 	}
 }
 #else
-void __init at91_init_serial(struct at91_uart_config *config) {}
+void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
 #endif
 
@@ -659,6 +922,9 @@
  */
 static int __init at91_add_standard_devices(void)
 {
+	at91_add_device_rtc();
+	at91_add_device_rtt();
+	at91_add_device_watchdog();
 	return 0;
 }
 
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
new file mode 100644
index 0000000..1854371
--- /dev/null
+++ b/arch/arm/mach-at91/board-cap9adk.c
@@ -0,0 +1,359 @@
+/*
+ * linux/arch/arm/mach-at91/board-cap9adk.c
+ *
+ *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/fb.h>
+#include <linux/mtd/physmap.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91cap9_matrix.h>
+#include <asm/arch/at91sam926x_mc.h>
+
+#include "generic.h"
+
+
+static void __init cap9adk_map_io(void)
+{
+	/* Initialize processor: 12 MHz crystal */
+	at91cap9_initialize(12000000);
+
+	/* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */
+	at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11);
+	/* ... POWER LED always on */
+	at91_set_gpio_output(AT91_PIN_PC29, 1);
+
+	/* Setup the serial ports and console */
+	at91_register_uart(0, 0, 0);		/* DBGU = ttyS0 */
+	at91_set_serial_console(0);
+}
+
+static void __init cap9adk_init_irq(void)
+{
+	at91cap9_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata cap9adk_usbh_data = {
+	.ports		= 2,
+};
+
+
+/*
+ * ADS7846 Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static int ads7843_pendown_state(void)
+{
+	return !at91_get_gpio_value(AT91_PIN_PC4);	/* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+	.model			= 7843,
+	.x_min			= 150,
+	.x_max			= 3830,
+	.y_min			= 190,
+	.y_max			= 3830,
+	.vref_delay_usecs	= 100,
+	.x_plate_ohms		= 450,
+	.y_plate_ohms		= 250,
+	.pressure_max		= 15000,
+	.debounce_max		= 1,
+	.debounce_rep		= 0,
+	.debounce_tol		= (~0),
+	.get_pendown_state	= ads7843_pendown_state,
+};
+
+static void __init cap9adk_add_device_ts(void)
+{
+	at91_set_gpio_input(AT91_PIN_PC4, 1);	/* Touchscreen PENIRQ */
+	at91_set_gpio_input(AT91_PIN_PC5, 1);	/* Touchscreen BUSY */
+}
+#else
+static void __init cap9adk_add_device_ts(void) {}
+#endif
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info cap9adk_spi_devices[] = {
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+	{	/* DataFlash card */
+		.modalias	= "mtd_dataflash",
+		.chip_select	= 0,
+		.max_speed_hz	= 15 * 1000 * 1000,
+		.bus_num	= 0,
+	},
+#endif
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+	{
+		.modalias	= "ads7846",
+		.chip_select	= 3,		/* can be 2 or 3, depending on J2 jumper */
+		.max_speed_hz	= 125000 * 26,	/* (max sample rate @ 3V) * (cmd + data + overhead) */
+		.bus_num	= 0,
+		.platform_data	= &ads_info,
+		.irq		= AT91_PIN_PC4,
+	},
+#endif
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata cap9adk_mmc_data = {
+	.wire4		= 1,
+//	.det_pin	= ... not connected
+//	.wp_pin		= ... not connected
+//	.vcc_pin	= ... not connected
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata cap9adk_macb_data = {
+	.is_rmii	= 1,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
+	{
+		.name	= "NAND partition",
+		.offset	= 0,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+	*num_partitions = ARRAY_SIZE(cap9adk_nand_partitions);
+	return cap9adk_nand_partitions;
+}
+
+static struct at91_nand_data __initdata cap9adk_nand_data = {
+	.ale		= 21,
+	.cle		= 22,
+//	.det_pin	= ... not connected
+//	.rdy_pin	= ... not connected
+	.enable_pin	= AT91_PIN_PD15,
+	.partition_info	= nand_partitions,
+#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+	.bus_width_16	= 1,
+#else
+	.bus_width_16	= 0,
+#endif
+};
+
+
+/*
+ * NOR flash
+ */
+static struct mtd_partition cap9adk_nor_partitions[] = {
+	{
+		.name		= "NOR partition",
+		.offset		= 0,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data cap9adk_nor_data = {
+	.width		= 2,
+	.parts		= cap9adk_nor_partitions,
+	.nr_parts	= ARRAY_SIZE(cap9adk_nor_partitions),
+};
+
+#define NOR_BASE	AT91_CHIPSELECT_0
+#define NOR_SIZE	0x800000
+
+static struct resource nor_flash_resources[] = {
+	{
+		.start	= NOR_BASE,
+		.end	= NOR_BASE + NOR_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device cap9adk_nor_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+				.platform_data	= &cap9adk_nor_data,
+	},
+	.resource	= nor_flash_resources,
+	.num_resources	= ARRAY_SIZE(nor_flash_resources),
+};
+
+static __init void cap9adk_add_device_nor(void)
+{
+	unsigned long csa;
+
+	csa = at91_sys_read(AT91_MATRIX_EBICSA);
+	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
+
+	/* set the bus interface characteristics */
+	at91_sys_write(AT91_SMC_SETUP(0), AT91_SMC_NWESETUP_(4) | AT91_SMC_NCS_WRSETUP_(2)
+			| AT91_SMC_NRDSETUP_(4) | AT91_SMC_NCS_RDSETUP_(2));
+
+	at91_sys_write(AT91_SMC_PULSE(0), AT91_SMC_NWEPULSE_(8) | AT91_SMC_NCS_WRPULSE_(10)
+			| AT91_SMC_NRDPULSE_(8) | AT91_SMC_NCS_RDPULSE_(10));
+
+	at91_sys_write(AT91_SMC_CYCLE(0), AT91_SMC_NWECYCLE_(16) | AT91_SMC_NRDCYCLE_(16));
+
+	at91_sys_write(AT91_SMC_MODE(0), AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+			| AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
+			| AT91_SMC_DBW_16 | AT91_SMC_TDF_(1));
+
+	platform_device_register(&cap9adk_nor_flash);
+}
+
+
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static struct fb_videomode at91_tft_vga_modes[] = {
+	{
+	        .name           = "TX09D50VM1CCA @ 60",
+		.refresh	= 60,
+		.xres		= 240,		.yres		= 320,
+		.pixclock	= KHZ2PICOS(4965),
+
+		.left_margin	= 1,		.right_margin	= 33,
+		.upper_margin	= 1,		.lower_margin	= 0,
+		.hsync_len	= 5,		.vsync_len	= 1,
+
+		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+};
+
+static struct fb_monspecs at91fb_default_monspecs = {
+	.manufacturer	= "HIT",
+	.monitor        = "TX09D70VM1CCA",
+
+	.modedb		= at91_tft_vga_modes,
+	.modedb_len	= ARRAY_SIZE(at91_tft_vga_modes),
+	.hfmin		= 15000,
+	.hfmax		= 64000,
+	.vfmin		= 50,
+	.vfmax		= 150,
+};
+
+#define AT91CAP9_DEFAULT_LCDCON2 	(ATMEL_LCDC_MEMOR_LITTLE \
+					| ATMEL_LCDC_DISTYPE_TFT    \
+					| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+static void at91_lcdc_power_control(int on)
+{
+	if (on)
+		at91_set_gpio_value(AT91_PIN_PC0, 0);	/* power up */
+	else
+		at91_set_gpio_value(AT91_PIN_PC0, 1);	/* power down */
+}
+
+/* Driver datas */
+static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = {
+	.default_bpp			= 16,
+	.default_dmacon			= ATMEL_LCDC_DMAEN,
+	.default_lcdcon2		= AT91CAP9_DEFAULT_LCDCON2,
+	.default_monspecs		= &at91fb_default_monspecs,
+	.atmel_lcdfb_power_control	= at91_lcdc_power_control,
+	.guard_time			= 1,
+};
+
+#else
+static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data;
+#endif
+
+
+/*
+ * AC97
+ */
+static struct atmel_ac97_data cap9adk_ac97_data = {
+//	.reset_pin	= ... not connected
+};
+
+
+static void __init cap9adk_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* USB Host */
+	set_irq_type(AT91CAP9_ID_UHP, IRQT_HIGH);
+	at91_add_device_usbh(&cap9adk_usbh_data);
+	/* SPI */
+	at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
+	/* Touchscreen */
+	cap9adk_add_device_ts();
+	/* MMC */
+	at91_add_device_mmc(1, &cap9adk_mmc_data);
+	/* Ethernet */
+	at91_add_device_eth(&cap9adk_macb_data);
+	/* NAND */
+	at91_add_device_nand(&cap9adk_nand_data);
+	/* NOR Flash */
+	cap9adk_add_device_nor();
+	/* I2C */
+	at91_add_device_i2c(NULL, 0);
+	/* LCD Controller */
+	set_irq_type(AT91CAP9_ID_LCDC, IRQT_HIGH);
+	at91_add_device_lcdc(&cap9adk_lcdc_data);
+	/* AC97 */
+	at91_add_device_ac97(&cap9adk_ac97_data);
+}
+
+MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK")
+	/* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91sam926x_timer,
+	.map_io		= cap9adk_map_io,
+	.init_irq	= cap9adk_init_irq,
+	.init_machine	= cap9adk_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index d0aa20c..0e2a11f 100644
--- a/arch/arm/mach-at91/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -25,6 +25,8 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
@@ -156,6 +158,85 @@
 	.num_resources	= ARRAY_SIZE(csb_flash_resources),
 };
 
+/*
+ * GPIO Buttons (on CSB300)
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button csb300_buttons[] = {
+	{
+		.gpio		= AT91_PIN_PB29,
+		.code		= BTN_0,
+		.desc		= "sw0",
+		.active_low	= 1,
+		.wakeup		= 1,
+	},
+	{
+		.gpio		= AT91_PIN_PB28,
+		.code		= BTN_1,
+		.desc		= "sw1",
+		.active_low	= 1,
+		.wakeup		= 1,
+	},
+	{
+		.gpio		= AT91_PIN_PA21,
+		.code		= BTN_2,
+		.desc		= "sw2",
+		.active_low	= 1,
+		.wakeup		= 1,
+	}
+};
+
+static struct gpio_keys_platform_data csb300_button_data = {
+	.buttons	= csb300_buttons,
+	.nbuttons	= ARRAY_SIZE(csb300_buttons),
+};
+
+static struct platform_device csb300_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &csb300_button_data,
+	}
+};
+
+static void __init csb300_add_device_buttons(void)
+{
+	at91_set_gpio_input(AT91_PIN_PB29, 0);	/* sw0 */
+	at91_set_deglitch(AT91_PIN_PB29, 1);
+	at91_set_gpio_input(AT91_PIN_PB28, 0);	/* sw1 */
+	at91_set_deglitch(AT91_PIN_PB28, 1);
+	at91_set_gpio_input(AT91_PIN_PA21, 0);	/* sw2 */
+	at91_set_deglitch(AT91_PIN_PA21, 1);
+
+	platform_device_register(&csb300_button_device);
+}
+#else
+static void __init csb300_add_device_buttons(void) {}
+#endif
+
+static struct gpio_led csb_leds[] = {
+	{	/* "led0", yellow */
+		.name			= "led0",
+		.gpio			= AT91_PIN_PB2,
+		.active_low		= 1,
+		.default_trigger	= "heartbeat",
+	},
+	{	/* "led1", green */
+		.name			= "led1",
+		.gpio			= AT91_PIN_PB1,
+		.active_low		= 1,
+		.default_trigger	= "mmc0",
+	},
+	{	/* "led2", yellow */
+		.name			= "led2",
+		.gpio			= AT91_PIN_PB0,
+		.active_low		= 1,
+		.default_trigger	= "ide-disk",
+	},
+};
+
+
 static void __init csb337_board_init(void)
 {
 	/* Serial */
@@ -177,6 +258,10 @@
 	at91_add_device_mmc(0, &csb337_mmc_data);
 	/* NOR flash */
 	platform_device_register(&csb_flash);
+	/* LEDs */
+	at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds));
+	/* Switches on CSB300 */
+	csb300_add_device_buttons();
 }
 
 MACHINE_START(CSB337, "Cogent CSB337")
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
index 40c9e43..0a897ef 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -183,6 +183,14 @@
 	.num_resources	= 1,
 };
 
+static struct gpio_led dk_leds[] = {
+	{
+		.name			= "led0",
+		.gpio			= AT91_PIN_PB2,
+		.active_low		= 1,
+		.default_trigger	= "heartbeat",
+	}
+};
 
 static void __init dk_board_init(void)
 {
@@ -213,6 +221,8 @@
 	at91_add_device_nand(&dk_nand_data);
 	/* NOR Flash */
 	platform_device_register(&dk_flash);
+	/* LEDs */
+	at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));
 	/* VGA */
 //	dk_add_device_video();
 }
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c
index 53a5ef9..0574e50 100644
--- a/arch/arm/mach-at91/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -141,6 +141,25 @@
 	.num_resources	= 1,
 };
 
+static struct gpio_led ek_leds[] = {
+	{	/* "user led 1", DS2 */
+		.name			= "green",
+		.gpio			= AT91_PIN_PB0,
+		.active_low		= 1,
+		.default_trigger	= "mmc0",
+	},
+	{	/* "user led 2", DS4 */
+		.name			= "yellow",
+		.gpio			= AT91_PIN_PB1,
+		.active_low		= 1,
+		.default_trigger	= "heartbeat",
+	},
+	{	/* "user led 3", DS6 */
+		.name			= "red",
+		.gpio			= AT91_PIN_PB2,
+		.active_low		= 1,
+	}
+};
 
 static void __init ek_board_init(void)
 {
@@ -167,6 +186,8 @@
 #endif
 	/* NOR Flash */
 	platform_device_register(&ek_flash);
+	/* LEDs */
+	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
 	/* VGA */
 //	ek_add_device_video();
 }
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 550ae59..aa29ea5 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -280,6 +280,68 @@
  * LCD Controller
  */
 #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+
+#if defined(CONFIG_FB_ATMEL_STN)
+
+/* STN */
+static struct fb_videomode at91_stn_modes[] = {
+        {
+		.name           = "SP06Q002 @ 75",
+		.refresh        = 75,
+		.xres           = 320,          .yres           = 240,
+		.pixclock       = KHZ2PICOS(1440),
+
+		.left_margin    = 1,            .right_margin   = 1,
+		.upper_margin   = 0,            .lower_margin   = 0,
+		.hsync_len      = 1,            .vsync_len      = 1,
+
+		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		.vmode          = FB_VMODE_NONINTERLACED,
+        },
+};
+
+static struct fb_monspecs at91fb_default_stn_monspecs = {
+        .manufacturer   = "HIT",
+        .monitor        = "SP06Q002",
+
+        .modedb         = at91_stn_modes,
+        .modedb_len     = ARRAY_SIZE(at91_stn_modes),
+        .hfmin          = 15000,
+        .hfmax          = 64000,
+        .vfmin          = 50,
+        .vfmax          = 150,
+};
+
+#define AT91SAM9261_DEFAULT_STN_LCDCON2	(ATMEL_LCDC_MEMOR_LITTLE \
+					| ATMEL_LCDC_DISTYPE_STNMONO \
+					| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE \
+					| ATMEL_LCDC_IFWIDTH_4 \
+					| ATMEL_LCDC_SCANMOD_SINGLE)
+
+static void at91_lcdc_stn_power_control(int on)
+{
+	/* backlight */
+	if (on) {	/* power up */
+		at91_set_gpio_value(AT91_PIN_PC14, 0);
+		at91_set_gpio_value(AT91_PIN_PC15, 0);
+	} else {	/* power down */
+		at91_set_gpio_value(AT91_PIN_PC14, 1);
+		at91_set_gpio_value(AT91_PIN_PC15, 1);
+	}
+}
+
+static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+	.default_bpp			= 1,
+	.default_dmacon			= ATMEL_LCDC_DMAEN,
+	.default_lcdcon2		= AT91SAM9261_DEFAULT_STN_LCDCON2,
+	.default_monspecs		= &at91fb_default_stn_monspecs,
+	.atmel_lcdfb_power_control	= at91_lcdc_stn_power_control,
+	.guard_time			= 1,
+};
+
+#else
+
+/* TFT */
 static struct fb_videomode at91_tft_vga_modes[] = {
 	{
 	        .name           = "TX09D50VM1CCA @ 60",
@@ -296,7 +358,7 @@
 	},
 };
 
-static struct fb_monspecs at91fb_default_monspecs = {
+static struct fb_monspecs at91fb_default_tft_monspecs = {
 	.manufacturer	= "HIT",
 	.monitor        = "TX09D50VM1CCA",
 
@@ -308,11 +370,11 @@
 	.vfmax		= 150,
 };
 
-#define AT91SAM9261_DEFAULT_LCDCON2 	(ATMEL_LCDC_MEMOR_LITTLE \
+#define AT91SAM9261_DEFAULT_TFT_LCDCON2	(ATMEL_LCDC_MEMOR_LITTLE \
 					| ATMEL_LCDC_DISTYPE_TFT    \
 					| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
 
-static void at91_lcdc_power_control(int on)
+static void at91_lcdc_tft_power_control(int on)
 {
 	if (on)
 		at91_set_gpio_value(AT91_PIN_PA12, 0);	/* power up */
@@ -320,15 +382,15 @@
 		at91_set_gpio_value(AT91_PIN_PA12, 1);	/* power down */
 }
 
-/* Driver datas */
 static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
 	.default_bpp			= 16,
 	.default_dmacon			= ATMEL_LCDC_DMAEN,
-	.default_lcdcon2		= AT91SAM9261_DEFAULT_LCDCON2,
-	.default_monspecs		= &at91fb_default_monspecs,
-	.atmel_lcdfb_power_control	= at91_lcdc_power_control,
+	.default_lcdcon2		= AT91SAM9261_DEFAULT_TFT_LCDCON2,
+	.default_monspecs		= &at91fb_default_tft_monspecs,
+	.atmel_lcdfb_power_control	= at91_lcdc_tft_power_control,
 	.guard_time			= 1,
 };
+#endif
 
 #else
 static struct atmel_lcdfb_info __initdata ek_lcdc_data;
@@ -342,25 +404,25 @@
 static struct gpio_keys_button ek_buttons[] = {
 	{
 		.gpio		= AT91_PIN_PA27,
-		.keycode	= BTN_0,
+		.code		= BTN_0,
 		.desc		= "Button 0",
 		.active_low	= 1,
 	},
 	{
 		.gpio		= AT91_PIN_PA26,
-		.keycode	= BTN_1,
+		.code		= BTN_1,
 		.desc		= "Button 1",
 		.active_low	= 1,
 	},
 	{
 		.gpio		= AT91_PIN_PA25,
-		.keycode	= BTN_2,
+		.code		= BTN_2,
 		.desc		= "Button 2",
 		.active_low	= 1,
 	},
 	{
 		.gpio		= AT91_PIN_PA24,
-		.keycode	= BTN_3,
+		.code		= BTN_3,
 		.desc		= "Button 3",
 		.active_low	= 1,
 	}
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index ab9dcc0..f09347a 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -27,6 +27,8 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/fb.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
 
 #include <video/atmel_lcdc.h>
 
@@ -163,6 +165,7 @@
  * MACB Ethernet device
  */
 static struct at91_eth_data __initdata ek_macb_data = {
+	.phy_irq_pin	= AT91_PIN_PE31,
 	.is_rmii	= 1,
 };
 
@@ -264,6 +267,55 @@
 
 
 /*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+	{	/* BP1, "leftclic" */
+		.code		= BTN_LEFT,
+		.gpio		= AT91_PIN_PC5,
+		.active_low	= 1,
+		.desc		= "left_click",
+		.wakeup		= 1,
+	},
+	{	/* BP2, "rightclic" */
+		.code		= BTN_RIGHT,
+		.gpio		= AT91_PIN_PC4,
+		.active_low	= 1,
+		.desc		= "right_click",
+		.wakeup		= 1,
+	},
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+	.buttons	= ek_buttons,
+	.nbuttons	= ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &ek_button_data,
+	}
+};
+
+static void __init ek_add_device_buttons(void)
+{
+	at91_set_GPIO_periph(AT91_PIN_PC5, 0);	/* left button */
+	at91_set_deglitch(AT91_PIN_PC5, 1);
+	at91_set_GPIO_periph(AT91_PIN_PC4, 0);	/* right button */
+	at91_set_deglitch(AT91_PIN_PC4, 1);
+
+	platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+
+/*
  * AC97
  */
 static struct atmel_ac97_data ek_ac97_data = {
@@ -271,6 +323,30 @@
 };
 
 
+/*
+ * LEDs ... these could all be PWM-driven, for variable brightness
+ */
+static struct gpio_led ek_leds[] = {
+	{	/* "left" led, green, userled1, pwm1 */
+		.name			= "ds1",
+		.gpio			= AT91_PIN_PB8,
+		.active_low		= 1,
+		.default_trigger	= "mmc0",
+	},
+	{	/* "right" led, green, userled2, pwm2 */
+		.name			= "ds2",
+		.gpio			= AT91_PIN_PC29,
+		.active_low		= 1,
+		.default_trigger	= "nand-disk",
+	},
+	{	/* "power" led, yellow, pwm0 */
+		.name			= "ds3",
+		.gpio			= AT91_PIN_PB7,
+		.default_trigger	= "heartbeat",
+	},
+};
+
+
 static void __init ek_board_init(void)
 {
 	/* Serial */
@@ -294,8 +370,12 @@
 	at91_add_device_i2c(NULL, 0);
 	/* LCD Controller */
 	at91_add_device_lcdc(&ek_lcdc_data);
+	/* Push Buttons */
+	ek_add_device_buttons();
 	/* AC97 */
 	at91_add_device_ac97(&ek_ac97_data);
+	/* LEDs */
+	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
 }
 
 MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 57c3b64..ec76eea 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -574,6 +574,8 @@
 	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) {
 		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
 		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
+	} else if (cpu_is_at91cap9()) {
+		uhpck.pmc_mask = AT91CAP9_PMC_UHP;
 	}
 	at91_sys_write(AT91_CKGR_PLLBR, 0);
 
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 77d4c0a..b5daf7f 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -15,6 +15,7 @@
 extern void __init at91sam9263_initialize(unsigned long main_clock);
 extern void __init at91sam9rl_initialize(unsigned long main_clock);
 extern void __init at91x40_initialize(unsigned long main_clock);
+extern void __init at91cap9_initialize(unsigned long main_clock);
 
  /* Interrupts */
 extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
@@ -23,6 +24,7 @@
 extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
 extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
 extern void __init at91x40_init_interrupts(unsigned int priority[]);
+extern void __init at91cap9_init_interrupts(unsigned int priority[]);
 extern void __init at91_aic_init(unsigned int priority[]);
 
  /* Timer */
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index aa2d365..6aeddd6 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -13,6 +13,8 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
@@ -414,6 +416,66 @@
 
 /*--------------------------------------------------------------------------*/
 
+#ifdef CONFIG_DEBUG_FS
+
+static int at91_gpio_show(struct seq_file *s, void *unused)
+{
+	int bank, j;
+
+	/* print heading */
+	seq_printf(s, "Pin\t");
+	for (bank = 0; bank < gpio_banks; bank++) {
+		seq_printf(s, "PIO%c\t", 'A' + bank);
+	};
+	seq_printf(s, "\n\n");
+
+	/* print pin status */
+	for (j = 0; j < 32; j++) {
+		seq_printf(s, "%i:\t", j);
+
+		for (bank = 0; bank < gpio_banks; bank++) {
+			unsigned	pin  = PIN_BASE + (32 * bank) + j;
+			void __iomem	*pio = pin_to_controller(pin);
+			unsigned	mask = pin_to_mask(pin);
+
+			if (__raw_readl(pio + PIO_PSR) & mask)
+				seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
+			else
+				seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A");
+
+			seq_printf(s, "\t");
+		}
+
+		seq_printf(s, "\n");
+	}
+
+	return 0;
+}
+
+static int at91_gpio_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, at91_gpio_show, NULL);
+}
+
+static const struct file_operations at91_gpio_operations = {
+	.open		= at91_gpio_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init at91_gpio_debugfs_init(void)
+{
+	/* /sys/kernel/debug/at91_gpio */
+	(void) debugfs_create_file("at91_gpio", S_IFREG | S_IRUGO, NULL, NULL, &at91_gpio_operations);
+	return 0;
+}
+postcore_initcall(at91_gpio_debugfs_init);
+
+#endif
+
+/*--------------------------------------------------------------------------*/
+
 /*
  * Called from the processor-specific init to enable GPIO interrupt support.
  */
diff --git a/arch/arm/mach-at91/leds.c b/arch/arm/mach-at91/leds.c
index 0d51449..9cdcda5 100644
--- a/arch/arm/mach-at91/leds.c
+++ b/arch/arm/mach-at91/leds.c
@@ -14,11 +14,62 @@
 #include <linux/init.h>
 
 #include <asm/mach-types.h>
-#include <asm/leds.h>
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
 
 
+/* ------------------------------------------------------------------------- */
+
+#if defined(CONFIG_NEW_LEDS)
+
+#include <linux/platform_device.h>
+
+/*
+ * New cross-platform LED support.
+ */
+
+static struct gpio_led_platform_data led_data;
+
+static struct platform_device at91_leds = {
+	.name			= "leds-gpio",
+	.id			= -1,
+	.dev.platform_data	= &led_data,
+};
+
+void __init at91_gpio_leds(struct gpio_led *leds, int nr)
+{
+	int i;
+
+	if (!nr)
+		return;
+
+	for (i = 0; i < nr; i++)
+		at91_set_gpio_output(leds[i].gpio, leds[i].active_low);
+
+	led_data.leds = leds;
+	led_data.num_leds = nr;
+	platform_device_register(&at91_leds);
+}
+
+#else
+void __init at91_gpio_leds(struct gpio_led *leds, int nr) {}
+#endif
+
+
+/* ------------------------------------------------------------------------- */
+
+#if defined(CONFIG_LEDS)
+
+#include <asm/leds.h>
+
+/*
+ * Old ARM-specific LED framework; not fully functional when generic time is
+ * in use.
+ */
+
+static u8 at91_leds_cpu;
+static u8 at91_leds_timer;
+
 static inline void at91_led_on(unsigned int led)
 {
 	at91_set_gpio_value(led, 0);
@@ -93,3 +144,18 @@
 }
 
 __initcall(leds_init);
+
+
+void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+{
+	/* Enable GPIO to access the LEDs */
+	at91_set_gpio_output(cpu_led, 1);
+	at91_set_gpio_output(timer_led, 1);
+
+	at91_leds_cpu	= cpu_led;
+	at91_leds_timer	= timer_led;
+}
+
+#else
+void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 98cb614..4b120cc 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -80,6 +80,11 @@
 			pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
 			return 0;
 		}
+	} else if (cpu_is_at91cap9()) {
+		if ((scsr & AT91CAP9_PMC_UHP) != 0) {
+			pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+			return 0;
+		}
 	}
 
 #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
index f428af7..e5dc33f 100644
--- a/arch/arm/mach-clps711x/time.c
+++ b/arch/arm/mach-clps711x/time.c
@@ -50,9 +50,7 @@
 static irqreturn_t
 p720t_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
 	timer_tick();
-	write_sequnlock(&xtime_lock);
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 986205e..2ac6367 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -298,8 +298,6 @@
 static irqreturn_t
 clps7500_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	timer_tick();
 
 	/* Why not using do_leds interface?? */
@@ -313,8 +311,6 @@
 		}
 	}
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 8c1b569..7710e14 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -178,8 +178,6 @@
 {
 	u32 count;
 
-	write_seqlock(&xtime_lock);
-
 	/* latch and read timer 1 */
 	__raw_writeb(0x40, PIT_CTRL);
 	count = __raw_readb(PIT_T1);
@@ -192,8 +190,6 @@
 
 	timer_tick();
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 70b2c78..91f6a07 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -3,6 +3,7 @@
  * Core routines for Cirrus EP93xx chips.
  *
  * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
  *
  * Thanks go to Michael Burian and Ray Lehtiniemi for their key
  * role in the ep93xx linux community.
@@ -21,7 +22,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/bitops.h>
-#include <linux/serial.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_core.h>
 #include <linux/device.h>
@@ -99,8 +99,6 @@
 
 static int ep93xx_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	__raw_writel(1, EP93XX_TIMER1_CLEAR);
 	while ((signed long)
 		(__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
@@ -109,8 +107,6 @@
 		timer_tick();
 	}
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
@@ -157,38 +153,41 @@
 static unsigned char gpio_int_type1[3];
 static unsigned char gpio_int_type2[3];
 
-static void update_gpio_int_params(int abf)
+/* Port ordering is: A B F */
+static const u8 int_type1_register_offset[3]	= { 0x90, 0xac, 0x4c };
+static const u8 int_type2_register_offset[3]	= { 0x94, 0xb0, 0x50 };
+static const u8 eoi_register_offset[3]		= { 0x98, 0xb4, 0x54 };
+static const u8 int_en_register_offset[3]	= { 0x9c, 0xb8, 0x5c };
+
+static void update_gpio_int_params(unsigned port)
 {
-	if (abf == 0) {
-		__raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE);
-		__raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2);
-		__raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1);
-		__raw_writeb(gpio_int_unmasked[0] & gpio_int_enabled[0], EP93XX_GPIO_A_INT_ENABLE);
-	} else if (abf == 1) {
-		__raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE);
-		__raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2);
-		__raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1);
-		__raw_writeb(gpio_int_unmasked[1] & gpio_int_enabled[1], EP93XX_GPIO_B_INT_ENABLE);
-	} else if (abf == 2) {
-		__raw_writeb(0, EP93XX_GPIO_F_INT_ENABLE);
-		__raw_writeb(gpio_int_type2[2], EP93XX_GPIO_F_INT_TYPE2);
-		__raw_writeb(gpio_int_type1[2], EP93XX_GPIO_F_INT_TYPE1);
-		__raw_writeb(gpio_int_unmasked[2] & gpio_int_enabled[2], EP93XX_GPIO_F_INT_ENABLE);
-	} else {
-		BUG();
-	}
+	BUG_ON(port > 2);
+
+	__raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
+
+	__raw_writeb(gpio_int_type2[port],
+		EP93XX_GPIO_REG(int_type2_register_offset[port]));
+
+	__raw_writeb(gpio_int_type1[port],
+		EP93XX_GPIO_REG(int_type1_register_offset[port]));
+
+	__raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
+		EP93XX_GPIO_REG(int_en_register_offset[port]));
 }
 
-
-static unsigned char data_register_offset[8] = {
-	0x00, 0x04, 0x08, 0x0c, 0x20, 0x30, 0x38, 0x40,
+/* Port ordering is: A B F D E C G H */
+static const u8 data_register_offset[8] = {
+	0x00, 0x04, 0x30, 0x0c, 0x20, 0x08, 0x38, 0x40,
 };
 
-static unsigned char data_direction_register_offset[8] = {
-	0x10, 0x14, 0x18, 0x1c, 0x24, 0x34, 0x3c, 0x44,
+static const u8 data_direction_register_offset[8] = {
+	0x10, 0x14, 0x34, 0x1c, 0x24, 0x18, 0x3c, 0x44,
 };
 
-void gpio_line_config(int line, int direction)
+#define GPIO_IN		0
+#define GPIO_OUT	1
+
+static void ep93xx_gpio_set_direction(unsigned line, int direction)
 {
 	unsigned int data_direction_register;
 	unsigned long flags;
@@ -199,14 +198,10 @@
 
 	local_irq_save(flags);
 	if (direction == GPIO_OUT) {
-		if (line >= 0 && line < 16) {
-			/* Port A/B.  */
+		if (line >= 0 && line <= EP93XX_GPIO_LINE_MAX_IRQ) {
+			/* Port A/B/F */
 			gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
 			update_gpio_int_params(line >> 3);
-		} else if (line >= 40 && line < 48) {
-			/* Port F.  */
-			gpio_int_unmasked[2] &= ~(1 << (line & 7));
-			update_gpio_int_params(2);
 		}
 
 		v = __raw_readb(data_direction_register);
@@ -219,39 +214,58 @@
 	}
 	local_irq_restore(flags);
 }
-EXPORT_SYMBOL(gpio_line_config);
 
-int gpio_line_get(int line)
+int gpio_direction_input(unsigned gpio)
+{
+	if (gpio > EP93XX_GPIO_LINE_MAX)
+		return -EINVAL;
+
+	ep93xx_gpio_set_direction(gpio, GPIO_IN);
+
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+	if (gpio > EP93XX_GPIO_LINE_MAX)
+		return -EINVAL;
+
+	gpio_set_value(gpio, value);
+	ep93xx_gpio_set_direction(gpio, GPIO_OUT);
+
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+int gpio_get_value(unsigned gpio)
 {
 	unsigned int data_register;
 
-	data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]);
+	data_register = EP93XX_GPIO_REG(data_register_offset[gpio >> 3]);
 
-	return !!(__raw_readb(data_register) & (1 << (line & 7)));
+	return !!(__raw_readb(data_register) & (1 << (gpio & 7)));
 }
-EXPORT_SYMBOL(gpio_line_get);
+EXPORT_SYMBOL(gpio_get_value);
 
-void gpio_line_set(int line, int value)
+void gpio_set_value(unsigned gpio, int value)
 {
 	unsigned int data_register;
 	unsigned long flags;
 	unsigned char v;
 
-	data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]);
+	data_register = EP93XX_GPIO_REG(data_register_offset[gpio >> 3]);
 
 	local_irq_save(flags);
-	if (value == EP93XX_GPIO_HIGH) {
-		v = __raw_readb(data_register);
-		v |= 1 << (line & 7);
-		__raw_writeb(v, data_register);
-	} else if (value == EP93XX_GPIO_LOW) {
-		v = __raw_readb(data_register);
-		v &= ~(1 << (line & 7));
-		__raw_writeb(v, data_register);
-	}
+	v = __raw_readb(data_register);
+	if (value)
+		v |= 1 << (gpio & 7);
+	else
+		v &= ~(1 << (gpio & 7));
+	__raw_writeb(v, data_register);
 	local_irq_restore(flags);
 }
-EXPORT_SYMBOL(gpio_line_set);
+EXPORT_SYMBOL(gpio_set_value);
 
 
 /*************************************************************************
@@ -265,47 +279,67 @@
 	status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
-			desc = irq_desc + IRQ_EP93XX_GPIO(0) + i;
-			desc_handle_irq(IRQ_EP93XX_GPIO(0) + i, desc);
+			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
+			desc = irq_desc + gpio_irq;
+			desc_handle_irq(gpio_irq, desc);
 		}
 	}
 
 	status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i)) {
-			desc = irq_desc + IRQ_EP93XX_GPIO(8) + i;
-			desc_handle_irq(IRQ_EP93XX_GPIO(8) + i, desc);
+			int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
+			desc = irq_desc + gpio_irq;
+			desc_handle_irq(gpio_irq, desc);
 		}
 	}
 }
 
 static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
-	int gpio_irq = IRQ_EP93XX_GPIO(16) + (((irq + 1) & 7) ^ 4);
+	/*
+	 * map discontiguous hw irq range to continous sw irq range:
+	 *
+	 *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
+	 */
+	int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
+	int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
 
 	desc_handle_irq(gpio_irq, irq_desc + gpio_irq);
 }
 
+static void ep93xx_gpio_irq_ack(unsigned int irq)
+{
+	int line = irq_to_gpio(irq);
+	int port = line >> 3;
+	int port_mask = 1 << (line & 7);
+
+	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) {
+		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
+		update_gpio_int_params(port);
+	}
+
+	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+}
+
 static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
 {
-	int line = irq - IRQ_EP93XX_GPIO(0);
+	int line = irq_to_gpio(irq);
 	int port = line >> 3;
+	int port_mask = 1 << (line & 7);
 
-	gpio_int_unmasked[port] &= ~(1 << (line & 7));
+	if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE)
+		gpio_int_type2[port] ^= port_mask; /* switch edge direction */
+
+	gpio_int_unmasked[port] &= ~port_mask;
 	update_gpio_int_params(port);
 
-	if (port == 0) {
-		__raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK);
-	} else if (port == 1) {
-		__raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
-	} else if (port == 2) {
-		__raw_writel(1 << (line & 7), EP93XX_GPIO_F_INT_ACK);
-	}
+	__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
 }
 
 static void ep93xx_gpio_irq_mask(unsigned int irq)
 {
-	int line = irq - IRQ_EP93XX_GPIO(0);
+	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 
 	gpio_int_unmasked[port] &= ~(1 << (line & 7));
@@ -314,7 +348,7 @@
 
 static void ep93xx_gpio_irq_unmask(unsigned int irq)
 {
-	int line = irq - IRQ_EP93XX_GPIO(0);
+	int line = irq_to_gpio(irq);
 	int port = line >> 3;
 
 	gpio_int_unmasked[port] |= 1 << (line & 7);
@@ -329,38 +363,54 @@
  */
 static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
 {
-	int port;
-	int line;
+	struct irq_desc *desc = irq_desc + irq;
+	const int gpio = irq_to_gpio(irq);
+	const int port = gpio >> 3;
+	const int port_mask = 1 << (gpio & 7);
 
-	line = irq - IRQ_EP93XX_GPIO(0);
-	if (line >= 0 && line < 16) {
-		gpio_line_config(line, GPIO_IN);
-	} else {
-		gpio_line_config(EP93XX_GPIO_LINE_F(line-16), GPIO_IN);
+	ep93xx_gpio_set_direction(gpio, GPIO_IN);
+
+	switch (type) {
+	case IRQT_RISING:
+		gpio_int_type1[port] |= port_mask;
+		gpio_int_type2[port] |= port_mask;
+		desc->handle_irq = handle_edge_irq;
+		break;
+	case IRQT_FALLING:
+		gpio_int_type1[port] |= port_mask;
+		gpio_int_type2[port] &= ~port_mask;
+		desc->handle_irq = handle_edge_irq;
+		break;
+	case IRQT_HIGH:
+		gpio_int_type1[port] &= ~port_mask;
+		gpio_int_type2[port] |= port_mask;
+		desc->handle_irq = handle_level_irq;
+		break;
+	case IRQT_LOW:
+		gpio_int_type1[port] &= ~port_mask;
+		gpio_int_type2[port] &= ~port_mask;
+		desc->handle_irq = handle_level_irq;
+		break;
+	case IRQT_BOTHEDGE:
+		gpio_int_type1[port] |= port_mask;
+		/* set initial polarity based on current input level */
+		if (gpio_get_value(gpio))
+			gpio_int_type2[port] &= ~port_mask; /* falling */
+		else
+			gpio_int_type2[port] |= port_mask; /* rising */
+		desc->handle_irq = handle_edge_irq;
+		break;
+	default:
+		pr_err("ep93xx: failed to set irq type %d for gpio %d\n",
+		       type, gpio);
+		return -EINVAL;
 	}
 
-	port = line >> 3;
-	line &= 7;
+	gpio_int_enabled[port] |= port_mask;
 
-	if (type & IRQT_RISING) {
-		gpio_int_enabled[port] |= 1 << line;
-		gpio_int_type1[port] |= 1 << line;
-		gpio_int_type2[port] |= 1 << line;
-	} else if (type & IRQT_FALLING) {
-		gpio_int_enabled[port] |= 1 << line;
-		gpio_int_type1[port] |= 1 << line;
-		gpio_int_type2[port] &= ~(1 << line);
-	} else if (type & IRQT_HIGH) {
-		gpio_int_enabled[port] |= 1 << line;
-		gpio_int_type1[port] &= ~(1 << line);
-		gpio_int_type2[port] |= 1 << line;
-	} else if (type & IRQT_LOW) {
-		gpio_int_enabled[port] |= 1 << line;
-		gpio_int_type1[port] &= ~(1 << line);
-		gpio_int_type2[port] &= ~(1 << line);
-	} else {
-		gpio_int_enabled[port] &= ~(1 << line);
-	}
+	desc->status &= ~IRQ_TYPE_SENSE_MASK;
+	desc->status |= type & IRQ_TYPE_SENSE_MASK;
+
 	update_gpio_int_params(port);
 
 	return 0;
@@ -368,7 +418,8 @@
 
 static struct irq_chip ep93xx_gpio_irq_chip = {
 	.name		= "GPIO",
-	.ack		= ep93xx_gpio_irq_mask_ack,
+	.ack		= ep93xx_gpio_irq_ack,
+	.mask_ack	= ep93xx_gpio_irq_mask_ack,
 	.mask		= ep93xx_gpio_irq_mask,
 	.unmask		= ep93xx_gpio_irq_unmask,
 	.set_type	= ep93xx_gpio_irq_type,
@@ -377,15 +428,16 @@
 
 void __init ep93xx_init_irq(void)
 {
-	int irq;
+	int gpio_irq;
 
 	vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
 	vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
 
-	for (irq = IRQ_EP93XX_GPIO(0); irq <= IRQ_EP93XX_GPIO(23); irq++) {
-		set_irq_chip(irq, &ep93xx_gpio_irq_chip);
-		set_irq_handler(irq, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
+	for (gpio_irq = gpio_to_irq(0);
+	     gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
+		set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
+		set_irq_handler(gpio_irq, handle_level_irq);
+		set_irq_flags(gpio_irq, IRQF_VALID);
 	}
 
 	set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
index 3a63941..b2a2118 100644
--- a/arch/arm/mach-footbridge/dc21285-timer.c
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -30,14 +30,10 @@
 static irqreturn_t
 timer1_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	*CSR_TIMER1_CLR = 0;
 
 	timer_tick();
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
index d08d641..a764e01 100644
--- a/arch/arm/mach-footbridge/isa-timer.c
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -64,9 +64,7 @@
 static irqreturn_t
 isa_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
 	timer_tick();
-	write_sequnlock(&xtime_lock);
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c
index 9107b8e..c2a431f 100644
--- a/arch/arm/mach-h720x/cpu-h7201.c
+++ b/arch/arm/mach-h720x/cpu-h7201.c
@@ -29,13 +29,9 @@
 static irqreturn_t
 h7201_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);
 	timer_tick();
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 0a1a25f..c627fa1 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -113,9 +113,7 @@
 	mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);
 
 	if ( mask & TSTAT_T0INT ) {
-		write_seqlock(&xtime_lock);
 		timer_tick();
-		write_sequnlock(&xtime_lock);
 		if( mask == TSTAT_T0INT )
 			return;
 	}
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index e9c82de..7fbbc17 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -250,8 +250,6 @@
 static irqreturn_t
 integrator_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	/*
 	 * clear the interrupt
 	 */
@@ -259,8 +257,6 @@
 
 	timer_tick();
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index d4d8134..d55fa4e 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -440,7 +440,7 @@
 	return 1;
 }
 
-static irqreturn_t v3_irq(int irq, void *devid)
+static irqreturn_t v3_irq(int dummy, void *devid)
 {
 #ifdef CONFIG_DEBUG_LL
 	struct pt_regs *regs = get_irq_regs();
@@ -448,8 +448,10 @@
 	unsigned long instr = *(unsigned long *)pc;
 	char buf[128];
 
-	sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n", irq,
-		pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
+	sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
+		"ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
+		__raw_readl(SC_LBFADDR),
+		__raw_readl(SC_LBFCODE) & 255,
 		v3_readb(V3_LB_ISTAT));
 	printascii(buf);
 #endif
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
index 2b086ab..74c65ce 100644
--- a/arch/arm/mach-iop32x/glantank.c
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -3,7 +3,7 @@
  *
  * Board support code for the GLAN Tank.
  *
- * Copyright (C) 2006 Martin Michlmayr <tbm@cyrius.com>
+ * Copyright (C) 2006, 2007 Martin Michlmayr <tbm@cyrius.com>
  * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -118,7 +119,7 @@
  * GLAN Tank machine initialization.
  */
 static struct physmap_flash_data glantank_flash_data = {
-	.width		= 1,
+	.width		= 2,
 };
 
 static struct resource glantank_flash_resource = {
@@ -166,6 +167,13 @@
 	.resource	= &glantank_uart_resource,
 };
 
+static struct i2c_board_info __initdata glantank_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("rtc-rs5c372", 0x32),
+		.type = "rs5c372a",
+	},
+};
+
 static void glantank_power_off(void)
 {
 	__raw_writeb(0x01, 0xfe8d0004);
@@ -183,6 +191,9 @@
 	platform_device_register(&iop3xx_dma_0_channel);
 	platform_device_register(&iop3xx_dma_1_channel);
 
+	i2c_register_board_info(0, glantank_i2c_devices,
+		ARRAY_SIZE(glantank_i2c_devices));
+
 	pm_power_off = glantank_power_off;
 }
 
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index cb6ad21..81cdc82 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -206,8 +206,6 @@
 
 static int ixp2000_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	/* clear timer 1 */
 	ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
 
@@ -217,8 +215,6 @@
 		next_jiffy_time -= ticks_per_jiffy;
 	}
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index 16356ff..5fea5a1 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -22,7 +22,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/bitops.h>
-#include <linux/serial.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_core.h>
 #include <linux/device.h>
diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c
index 7a85ced..d3a779a 100644
--- a/arch/arm/mach-ixp23xx/espresso.c
+++ b/arch/arm/mach-ixp23xx/espresso.c
@@ -19,7 +19,6 @@
 #include <linux/tty.h>
 #include <linux/bitops.h>
 #include <linux/ioport.h>
-#include <linux/serial.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_core.h>
 #include <linux/device.h>
@@ -40,7 +39,6 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
 #include <asm/mach/pci.h>
 
 static int __init espresso_pci_init(void)
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index c41a6b5..5c5d4d6 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -24,7 +24,6 @@
 #include <linux/tty.h>
 #include <linux/bitops.h>
 #include <linux/ioport.h>
-#include <linux/serial.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_core.h>
 #include <linux/device.h>
@@ -44,7 +43,6 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
 #include <asm/mach/pci.h>
 
 /*
diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c
index e356449..f0f70ba 100644
--- a/arch/arm/mach-ixp23xx/roadrunner.c
+++ b/arch/arm/mach-ixp23xx/roadrunner.c
@@ -23,7 +23,6 @@
 #include <linux/tty.h>
 #include <linux/bitops.h>
 #include <linux/ioport.h>
-#include <linux/serial.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_core.h>
 #include <linux/device.h>
@@ -44,7 +43,6 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
 #include <asm/mach/pci.h>
 
 /*
diff --git a/arch/arm/mach-ixp4xx/nslu2-power.c b/arch/arm/mach-ixp4xx/nslu2-power.c
index acd71e9..6f10dc2 100644
--- a/arch/arm/mach-ixp4xx/nslu2-power.c
+++ b/arch/arm/mach-ixp4xx/nslu2-power.c
@@ -21,7 +21,6 @@
 #include <linux/reboot.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/reboot.h>
 
 #include <asm/mach-types.h>
 
diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile
index 2a07a28..730a3af 100644
--- a/arch/arm/mach-ks8695/Makefile
+++ b/arch/arm/mach-ks8695/Makefile
@@ -9,7 +9,7 @@
 obj-				:=
 
 # PCI support is optional
-#obj-$(CONFIG_PCI)		+= pci.o
+obj-$(CONFIG_PCI)		+= pci.o
 
 # Board-specific support
 obj-$(CONFIG_MACH_KS8695)	+= board-micrel.o
diff --git a/arch/arm/mach-ks8695/board-micrel.c b/arch/arm/mach-ks8695/board-micrel.c
index 2feeef8..05ac2bd 100644
--- a/arch/arm/mach-ks8695/board-micrel.c
+++ b/arch/arm/mach-ks8695/board-micrel.c
@@ -40,7 +40,7 @@
 	printk(KERN_INFO "Micrel KS8695 Development Board initializing\n");
 
 #ifdef CONFIG_PCI
-//	ks8695_init_pci(&micrel_pci);
+	ks8695_init_pci(&micrel_pci);
 #endif
 
 	/* Add devices */
diff --git a/arch/arm/mach-ks8695/gpio.c b/arch/arm/mach-ks8695/gpio.c
index b1aa3cb..5e46191 100644
--- a/arch/arm/mach-ks8695/gpio.c
+++ b/arch/arm/mach-ks8695/gpio.c
@@ -20,6 +20,8 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/module.h>
 
 #include <asm/io.h>
@@ -216,3 +218,84 @@
 	return (irq - KS8695_IRQ_EXTERN0);
 }
 EXPORT_SYMBOL(irq_to_gpio);
+
+
+/* .... Debug interface ..................................................... */
+
+#ifdef CONFIG_DEBUG_FS
+
+static int ks8695_gpio_show(struct seq_file *s, void *unused)
+{
+	unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
+	unsigned int intmask[] = { IOPC_IOEINT0TM, IOPC_IOEINT1TM, IOPC_IOEINT2TM, IOPC_IOEINT3TM };
+	unsigned long mode, ctrl, data;
+	int i;
+
+	mode = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
+	ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
+	data = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
+
+	seq_printf(s, "Pin\tI/O\tFunction\tState\n\n");
+
+	for (i = KS8695_GPIO_0; i <= KS8695_GPIO_15 ; i++) {
+		seq_printf(s, "%i:\t", i);
+
+		seq_printf(s, "%s\t", (mode & IOPM_(i)) ? "Output" : "Input");
+
+		if (i <= KS8695_GPIO_3) {
+			if (ctrl & enable[i]) {
+				seq_printf(s, "EXT%i ", i);
+
+				switch ((ctrl & intmask[i]) >> (4 * i)) {
+					case IOPC_TM_LOW:
+						seq_printf(s, "(Low)");		break;
+					case IOPC_TM_HIGH:
+						seq_printf(s, "(High)");	break;
+					case IOPC_TM_RISING:
+						seq_printf(s, "(Rising)");	break;
+					case IOPC_TM_FALLING:
+						seq_printf(s, "(Falling)");	break;
+					case IOPC_TM_EDGE:
+						seq_printf(s, "(Edges)");	break;
+				}
+			}
+			else
+				seq_printf(s, "GPIO\t");
+		}
+		else if (i <= KS8695_GPIO_5) {
+			if (ctrl & enable[i])
+				seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4);
+			else
+				seq_printf(s, "GPIO\t");
+		}
+		else
+			seq_printf(s, "GPIO\t");
+
+		seq_printf(s, "\t");
+
+		seq_printf(s, "%i\n", (data & IOPD_(i)) ? 1 : 0);
+	}
+	return 0;
+}
+
+static int ks8695_gpio_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ks8695_gpio_show, NULL);
+}
+
+static const struct file_operations ks8695_gpio_operations = {
+	.open		= ks8695_gpio_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init ks8695_gpio_debugfs_init(void)
+{
+	/* /sys/kernel/debug/ks8695_gpio */
+	(void) debugfs_create_file("ks8695_gpio", S_IFREG | S_IRUGO, NULL, NULL, &ks8695_gpio_operations);
+	return 0;
+}
+postcore_initcall(ks8695_gpio_debugfs_init);
+
+#endif
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
new file mode 100644
index 0000000..3f4e033
--- /dev/null
+++ b/arch/arm/mach-ks8695/pci.c
@@ -0,0 +1,326 @@
+/*
+ * arch/arm/mach-ks8695/pci.c
+ *
+ *  Copyright (C) 2003, Micrel Semiconductors
+ *  Copyright (C) 2006, Greg Ungerer <gerg@snapgear.com>
+ *  Copyright (C) 2006, Ben Dooks
+ *  Copyright (C) 2007, Andrew Victor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/signal.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/devices.h>
+#include <asm/arch/regs-pci.h>
+
+
+static int pci_dbg;
+static int pci_cfg_dbg;
+
+
+static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where)
+{
+	unsigned long pbca;
+
+	pbca = PBCA_ENABLE | (where & ~3);
+	pbca |= PCI_SLOT(devfn) << 11 ;
+	pbca |= PCI_FUNC(devfn) << 8;
+	pbca |= bus_nr << 16;
+
+	if (bus_nr == 0) {
+		/* use Type-0 transaction */
+		__raw_writel(pbca, KS8695_PCI_VA + KS8695_PBCA);
+	} else {
+		/* use Type-1 transaction */
+		__raw_writel(pbca | PBCA_TYPE1, KS8695_PCI_VA + KS8695_PBCA);
+	}
+}
+
+
+/*
+ * The KS8695 datasheet prohibits anything other than 32bit accesses
+ * to the IO registers, so all our configuration must be done with
+ * 32bit operations, and the correct bit masking and shifting.
+ */
+
+static int ks8695_pci_readconfig(struct pci_bus *bus,
+			unsigned int devfn, int where, int size, u32 *value)
+{
+	ks8695_pci_setupconfig(bus->number, devfn, where);
+
+	*value = __raw_readl(KS8695_PCI_VA +  KS8695_PBCD);
+
+	switch (size) {
+		case 4:
+			break;
+		case 2:
+			*value = *value >> ((where & 2) * 8);
+			*value &= 0xffff;
+			break;
+		case 1:
+			*value = *value >> ((where & 3) * 8);
+			*value &= 0xff;
+			break;
+	}
+
+	if (pci_cfg_dbg) {
+		printk("read: %d,%08x,%02x,%d: %08x (%08x)\n",
+			bus->number, devfn, where, size, *value,
+			__raw_readl(KS8695_PCI_VA +  KS8695_PBCD));
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int ks8695_pci_writeconfig(struct pci_bus *bus,
+			unsigned int devfn, int where, int size, u32 value)
+{
+	unsigned long tmp;
+
+	if (pci_cfg_dbg) {
+		printk("write: %d,%08x,%02x,%d: %08x\n",
+			bus->number, devfn, where, size, value);
+	}
+
+	ks8695_pci_setupconfig(bus->number, devfn, where);
+
+	switch (size) {
+		case 4:
+			__raw_writel(value, KS8695_PCI_VA +  KS8695_PBCD);
+			break;
+		case 2:
+			tmp = __raw_readl(KS8695_PCI_VA +  KS8695_PBCD);
+			tmp &= ~(0xffff << ((where & 2) * 8));
+			tmp |= value << ((where & 2) * 8);
+
+			__raw_writel(tmp, KS8695_PCI_VA +  KS8695_PBCD);
+			break;
+		case 1:
+			tmp = __raw_readl(KS8695_PCI_VA +  KS8695_PBCD);
+			tmp &= ~(0xff << ((where & 3) * 8));
+			tmp |= value << ((where & 3) * 8);
+
+			__raw_writel(tmp, KS8695_PCI_VA +  KS8695_PBCD);
+			break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void ks8695_local_writeconfig(int where, u32 value)
+{
+	ks8695_pci_setupconfig(0, 0, where);
+	__raw_writel(value, KS8695_PCI_VA + KS8695_PBCD);
+}
+
+static struct pci_ops ks8695_pci_ops = {
+	.read	= ks8695_pci_readconfig,
+	.write	= ks8695_pci_writeconfig,
+};
+
+static struct pci_bus *ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	return pci_scan_bus(sys->busnr, &ks8695_pci_ops, sys);
+}
+
+static struct resource pci_mem = {
+	.name	= "PCI Memory space",
+	.start	= KS8695_PCIMEM_PA,
+	.end	= KS8695_PCIMEM_PA + (KS8695_PCIMEM_SIZE - 1),
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource pci_io = {
+	.name	= "PCI IO space",
+	.start	= KS8695_PCIIO_PA,
+	.end	= KS8695_PCIIO_PA + (KS8695_PCIIO_SIZE - 1),
+	.flags	= IORESOURCE_IO,
+};
+
+static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys)
+{
+	if (nr > 0)
+		return 0;
+
+	request_resource(&iomem_resource, &pci_mem);
+	request_resource(&ioport_resource, &pci_io);
+
+	sys->resource[0] = &pci_io;
+	sys->resource[1] = &pci_mem;
+	sys->resource[2] = NULL;
+
+	/* Assign and enable processor bridge */
+	ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA);
+
+	/* Enable bus-master & Memory Space access */
+	ks8695_local_writeconfig(PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+
+	/* Set cache-line size & latency. */
+	ks8695_local_writeconfig(PCI_CACHE_LINE_SIZE, (32 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
+
+	/* Reserve PCI memory space for PCI-AHB resources */
+	if (!request_mem_region(KS8695_PCIMEM_PA, SZ_64M, "PCI-AHB Bridge")) {
+		printk(KERN_ERR "Cannot allocate PCI-AHB Bridge memory.\n");
+		return -EBUSY;
+	}
+
+	return 1;
+}
+
+static inline unsigned int size_mask(unsigned long size)
+{
+	return (~size) + 1;
+}
+
+static int ks8695_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+	unsigned long pc = instruction_pointer(regs);
+	unsigned long instr = *(unsigned long *)pc;
+	unsigned long cmdstat;
+
+	cmdstat = __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS);
+
+	printk(KERN_ERR "PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx [%s%s%s%s%s]\n",
+		addr, fsr, regs->ARM_pc, regs->ARM_lr,
+		cmdstat & (PCI_STATUS_SIG_TARGET_ABORT << 16) ? "GenTarget" : " ",
+		cmdstat & (PCI_STATUS_REC_TARGET_ABORT << 16) ? "RecvTarget" : " ",
+		cmdstat & (PCI_STATUS_REC_MASTER_ABORT << 16) ? "MasterAbort" : " ",
+		cmdstat & (PCI_STATUS_SIG_SYSTEM_ERROR << 16) ? "SysError" : " ",
+		cmdstat & (PCI_STATUS_DETECTED_PARITY << 16)  ? "Parity" : " "
+	);
+
+	__raw_writel(cmdstat, KS8695_PCI_VA + KS8695_CRCFCS);
+
+	/*
+	 * If the instruction being executed was a read,
+	 * make it look like it read all-ones.
+	 */
+	if ((instr & 0x0c100000) == 0x04100000) {
+		int reg = (instr >> 12) & 15;
+		unsigned long val;
+
+		if (instr & 0x00400000)
+			val = 255;
+		else
+			val = -1;
+
+		regs->uregs[reg] = val;
+		regs->ARM_pc += 4;
+		return 0;
+	}
+
+	if ((instr & 0x0e100090) == 0x00100090) {
+		int reg = (instr >> 12) & 15;
+
+		regs->uregs[reg] = -1;
+		regs->ARM_pc += 4;
+		return 0;
+	}
+
+	return 1;
+}
+
+static void __init ks8695_pci_preinit(void)
+{
+	/* stage 1 initialization, subid, subdevice = 0x0001 */
+	__raw_writel(0x00010001, KS8695_PCI_VA + KS8695_CRCSID);
+
+	/* stage 2 initialization */
+	/* prefetch limits with 16 words, retry enable */
+	__raw_writel(0x40000000, KS8695_PCI_VA + KS8695_PBCS);
+
+	/* configure memory mapping */
+	__raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBA);
+	__raw_writel(size_mask(KS8695_PCIMEM_SIZE), KS8695_PCI_VA + KS8695_PMBAM);
+	__raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBAT);
+	__raw_writel(0, KS8695_PCI_VA + KS8695_PMBAC);
+
+	/* configure IO mapping */
+	__raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBA);
+	__raw_writel(size_mask(KS8695_PCIIO_SIZE), KS8695_PCI_VA + KS8695_PIOBAM);
+	__raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBAT);
+	__raw_writel(0, KS8695_PCI_VA + KS8695_PIOBAC);
+
+	/* hook in fault handlers */
+	hook_fault_code(8, ks8695_pci_fault, SIGBUS, "external abort on non-linefetch");
+	hook_fault_code(10, ks8695_pci_fault, SIGBUS, "external abort on non-linefetch");
+}
+
+static void ks8695_show_pciregs(void)
+{
+	if (!pci_dbg)
+		return;
+
+	printk(KERN_INFO "PCI: CRCFID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFID));
+	printk(KERN_INFO "PCI: CRCFCS = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS));
+	printk(KERN_INFO "PCI: CRCFRV = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFRV));
+	printk(KERN_INFO "PCI: CRCFLT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFLT));
+	printk(KERN_INFO "PCI: CRCBMA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCBMA));
+	printk(KERN_INFO "PCI: CRCSID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCSID));
+	printk(KERN_INFO "PCI: CRCFIT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFIT));
+
+	printk(KERN_INFO "PCI: PBM    = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBM));
+	printk(KERN_INFO "PCI: PBCS   = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBCS));
+
+	printk(KERN_INFO "PCI: PMBA   = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBA));
+	printk(KERN_INFO "PCI: PMBAC  = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAC));
+	printk(KERN_INFO "PCI: PMBAM  = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAM));
+	printk(KERN_INFO "PCI: PMBAT  = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAT));
+
+	printk(KERN_INFO "PCI: PIOBA  = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBA));
+	printk(KERN_INFO "PCI: PIOBAC = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAC));
+	printk(KERN_INFO "PCI: PIOBAM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAM));
+	printk(KERN_INFO "PCI: PIOBAT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAT));
+}
+
+
+static struct hw_pci ks8695_pci __initdata = {
+	.nr_controllers	= 1,
+	.preinit	= ks8695_pci_preinit,
+	.setup		= ks8695_pci_setup,
+	.scan		= ks8695_pci_scan_bus,
+	.postinit	= NULL,
+	.swizzle	= pci_std_swizzle,
+	.map_irq	= NULL,
+};
+
+void __init ks8695_init_pci(struct ks8695_pci_cfg *cfg)
+{
+	if (__raw_readl(KS8695_PCI_VA + KS8695_CRCFRV) & CFRV_GUEST) {
+		printk("PCI: KS8695 in guest mode, not initialising\n");
+		return;
+	}
+
+	printk(KERN_INFO "PCI: Initialising\n");
+	ks8695_show_pciregs();
+
+	/* set Mode */
+	__raw_writel(cfg->mode << 29, KS8695_PCI_VA + KS8695_PBM);
+
+	ks8695_pci.map_irq = cfg->map_irq;	/* board-specific map_irq method */
+
+	pci_common_init(&ks8695_pci);
+}
diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c
index d2c86e4..02f766b 100644
--- a/arch/arm/mach-ks8695/time.c
+++ b/arch/arm/mach-ks8695/time.c
@@ -70,10 +70,7 @@
  */
 static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
 	timer_tick();
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c
index c25316d..e50e60b 100644
--- a/arch/arm/mach-lh7a40x/time.c
+++ b/arch/arm/mach-lh7a40x/time.c
@@ -41,13 +41,9 @@
 static irqreturn_t
 lh7a40x_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	TIMER_EOI = 0;
 	timer_tick();
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
new file mode 100644
index 0000000..3553bab
--- /dev/null
+++ b/arch/arm/mach-msm/Kconfig
@@ -0,0 +1,18 @@
+if ARCH_MSM7X00A
+
+comment "MSM7X00A Board Type"
+	depends on ARCH_MSM7X00A
+
+config MACH_HALIBUT
+	depends on ARCH_MSM7X00A
+	default y
+	bool "Halibut Board (QCT SURF7200A)"
+	help
+	  Support for the Qualcomm SURF7200A eval board.
+
+config MSM7X00A_IDLE
+	depends on ARCH_MSM7X00A
+	default y
+	bool "Idle Support for MSM7X00A"
+
+endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
new file mode 100644
index 0000000..d12f236
--- /dev/null
+++ b/arch/arm/mach-msm/Makefile
@@ -0,0 +1,7 @@
+obj-y += io.o idle.o irq.o timer.o dma.o
+
+# Common code for board init
+obj-y += common.o
+
+obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o
+
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
new file mode 100644
index 0000000..24dfbf8
--- /dev/null
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -0,0 +1,3 @@
+  zreladdr-y		:= 0x10008000
+params_phys-y		:= 0x10000100
+initrd_phys-y		:= 0x10800000
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
new file mode 100644
index 0000000..86dfb2b
--- /dev/null
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -0,0 +1,114 @@
+/* linux/arch/arm/mach-msm/board-halibut.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/msm_iomap.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= 0x9C004300,
+		.end	= 0x9C004400,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= MSM_GPIO_TO_INT(49),
+		.end	= MSM_GPIO_TO_INT(49),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static void mddi0_panel_power(int on)
+{
+}
+
+static struct msm_mddi_platform_data msm_mddi0_pdata = {
+	.panel_power	= mddi0_panel_power,
+	.has_vsync_irq	= 0,
+};
+
+static struct platform_device msm_mddi0_device = {
+	.name	= "msm_mddi",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &msm_mddi0_pdata
+	},
+};
+
+static struct platform_device msm_serial0_device = {
+	.name	= "msm_serial",
+	.id	= 0,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&msm_serial0_device,
+	&msm_mddi0_device,
+	&smc91x_device,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init halibut_init_irq(void)
+{
+	msm_init_irq();
+}
+
+static void __init halibut_init(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	msm_add_devices();
+}
+
+static void __init halibut_map_io(void)
+{
+	msm_map_common_io();
+}
+
+MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
+
+/* UART for LL DEBUG */
+	.phys_io	= MSM_UART1_PHYS,
+	.io_pg_offst	= ((MSM_UART1_BASE) >> 18) & 0xfffc,
+
+	.boot_params	= 0x10000100,
+	.map_io		= halibut_map_io,
+	.init_irq	= halibut_init_irq,
+	.init_machine	= halibut_init,
+	.timer		= &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/common.c b/arch/arm/mach-msm/common.c
new file mode 100644
index 0000000..3f5d336
--- /dev/null
+++ b/arch/arm/mach-msm/common.c
@@ -0,0 +1,116 @@
+/* linux/arch/arm/mach-msm/common.c
+ *
+ * Common setup code for MSM7K Boards
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/flash.h>
+#include <asm/io.h>
+
+#include <asm/setup.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/arch/msm_iomap.h>
+
+#include <asm/arch/board.h>
+
+struct flash_platform_data msm_nand_data = {
+	.parts		= 0,
+	.nr_parts	= 0,
+};
+
+static struct resource msm_nand_resources[] = {
+	[0] = {
+		.start	= 7,
+		.end	= 7,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device msm_nand_device = {
+	.name		= "msm_nand",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(msm_nand_resources),
+	.resource	= msm_nand_resources,
+	.dev		= {
+		.platform_data	= &msm_nand_data,
+	},
+};
+
+static struct platform_device msm_smd_device = {
+	.name	= "msm_smd",
+	.id	= -1,
+};
+
+static struct resource msm_i2c_resources[] = {
+	{
+		.start	= MSM_I2C_BASE,
+		.end	= MSM_I2C_BASE + MSM_I2C_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_PWB_I2C,
+		.end	= INT_PWB_I2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device msm_i2c_device = {
+	.name		= "msm_i2c",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(msm_i2c_resources),
+	.resource	= msm_i2c_resources,
+};
+
+static struct resource usb_resources[] = {
+	{
+		.start	= MSM_HSUSB_PHYS,
+		.end	= MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_USB_HS,
+		.end	= INT_USB_HS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device msm_hsusb_device = {
+	.name		= "msm_hsusb",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(usb_resources),
+	.resource	= usb_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
+};
+
+static struct platform_device *devices[] __initdata = {
+	&msm_nand_device,
+	&msm_smd_device,
+	&msm_i2c_device,
+	&msm_hsusb_device,
+};
+
+void __init msm_add_devices(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
new file mode 100644
index 0000000..8b0f339
--- /dev/null
+++ b/arch/arm/mach-msm/dma.c
@@ -0,0 +1,214 @@
+/* linux/arch/arm/mach-msm/dma.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/io.h>
+#include <linux/interrupt.h>
+#include <asm/arch/dma.h>
+
+#define MSM_DMOV_CHANNEL_COUNT 16
+
+enum {
+	MSM_DMOV_PRINT_ERRORS = 1,
+	MSM_DMOV_PRINT_IO = 2,
+	MSM_DMOV_PRINT_FLOW = 4
+};
+
+static DEFINE_SPINLOCK(msm_dmov_lock);
+static struct msm_dmov_cmd active_command;
+static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
+static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
+unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
+
+#define MSM_DMOV_DPRINTF(mask, format, args...) \
+	do { \
+		if ((mask) & msm_dmov_print_mask) \
+			printk(KERN_ERR format, args); \
+	} while (0)
+#define PRINT_ERROR(format, args...) \
+	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_ERRORS, format, args);
+#define PRINT_IO(format, args...) \
+	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_IO, format, args);
+#define PRINT_FLOW(format, args...) \
+	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
+
+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
+{
+	unsigned long irq_flags;
+	unsigned int status;
+
+	spin_lock_irqsave(&msm_dmov_lock, irq_flags);
+	status = readl(DMOV_STATUS(id));
+	if (list_empty(&ready_commands[id]) &&
+		(status & DMOV_STATUS_CMD_PTR_RDY)) {
+#if 0
+		if (list_empty(&active_commands[id])) {
+			PRINT_FLOW("msm_dmov_enqueue_cmd(%d), enable interrupt\n", id);
+			writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id));
+		}
+#endif
+		PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
+		list_add_tail(&cmd->list, &active_commands[id]);
+		writel(cmd->cmdptr, DMOV_CMD_PTR(id));
+	} else {
+		if (list_empty(&active_commands[id]))
+			PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
+
+		PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status %x\n", id, status);
+		list_add_tail(&cmd->list, &ready_commands[id]);
+	}
+	spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
+}
+
+struct msm_dmov_exec_cmdptr_cmd {
+	struct msm_dmov_cmd dmov_cmd;
+	struct completion complete;
+	unsigned id;
+	unsigned int result;
+	unsigned int flush[6];
+};
+
+static void dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd, unsigned int result)
+{
+	struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
+	cmd->result = result;
+	if (result != 0x80000002) {
+		cmd->flush[0] = readl(DMOV_FLUSH0(cmd->id));
+		cmd->flush[1] = readl(DMOV_FLUSH1(cmd->id));
+		cmd->flush[2] = readl(DMOV_FLUSH2(cmd->id));
+		cmd->flush[3] = readl(DMOV_FLUSH3(cmd->id));
+		cmd->flush[4] = readl(DMOV_FLUSH4(cmd->id));
+		cmd->flush[5] = readl(DMOV_FLUSH5(cmd->id));
+	}
+	complete(&cmd->complete);
+}
+
+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
+{
+	struct msm_dmov_exec_cmdptr_cmd cmd;
+
+	PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
+
+	cmd.dmov_cmd.cmdptr = cmdptr;
+	cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func;
+	cmd.id = id;
+	init_completion(&cmd.complete);
+
+	msm_dmov_enqueue_cmd(id, &cmd.dmov_cmd);
+	wait_for_completion(&cmd.complete);
+
+	if (cmd.result != 0x80000002) {
+		PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
+		PRINT_ERROR("dmov_exec_cmdptr(%d):  flush: %x %x %x %x\n",
+			id, cmd.flush[0], cmd.flush[1], cmd.flush[2], cmd.flush[3]);
+		return -EIO;
+	}
+	PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
+	return 0;
+}
+
+
+static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
+{
+	unsigned int int_status, mask, id;
+	unsigned long irq_flags;
+	unsigned int ch_status;
+	unsigned int ch_result;
+	struct msm_dmov_cmd *cmd;
+
+	spin_lock_irqsave(&msm_dmov_lock, irq_flags);
+
+	int_status = readl(DMOV_ISR); /* read and clear interrupt */
+	PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
+
+	while (int_status) {
+		mask = int_status & -int_status;
+		id = fls(mask) - 1;
+		PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
+		int_status &= ~mask;
+		ch_status = readl(DMOV_STATUS(id));
+		if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
+			PRINT_FLOW("msm_datamover_irq_handler id %d, result not valid %x\n", id, ch_status);
+			continue;
+		}
+		do {
+			ch_result = readl(DMOV_RSLT(id));
+			if (list_empty(&active_commands[id])) {
+				PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
+					"with no active command, status %x, result %x\n",
+					id, ch_status, ch_result);
+				cmd = NULL;
+			} else
+				cmd = list_entry(active_commands[id].next, typeof(*cmd), list);
+			PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
+			if (ch_result & DMOV_RSLT_DONE) {
+				PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
+					id, ch_status);
+				PRINT_IO("msm_datamover_irq_handler id %d, got result "
+					"for %p, result %x\n", id, cmd, ch_result);
+				if (cmd) {
+					list_del(&cmd->list);
+					cmd->complete_func(cmd, ch_result);
+				}
+			}
+			if (ch_result & DMOV_RSLT_FLUSH) {
+				unsigned int flush0 = readl(DMOV_FLUSH0(id));
+				PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
+				PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, flush0);
+				if (cmd) {
+					list_del(&cmd->list);
+					cmd->complete_func(cmd, ch_result);
+				}
+			}
+			if (ch_result & DMOV_RSLT_ERROR) {
+				unsigned int flush0 = readl(DMOV_FLUSH0(id));
+				PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
+				PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, flush0);
+				if (cmd) {
+					list_del(&cmd->list);
+					cmd->complete_func(cmd, ch_result);
+				}
+				/* this does not seem to work, once we get an error */
+				/* the datamover will no longer accept commands */
+				writel(0, DMOV_FLUSH0(id));
+			}
+			ch_status = readl(DMOV_STATUS(id));
+			PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
+			if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) && !list_empty(&ready_commands[id])) {
+				cmd = list_entry(ready_commands[id].next, typeof(*cmd), list);
+				list_del(&cmd->list);
+				list_add_tail(&cmd->list, &active_commands[id]);
+				PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id);
+				writel(cmd->cmdptr, DMOV_CMD_PTR(id));
+			}
+		} while (ch_status & DMOV_STATUS_RSLT_VALID);
+		PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
+	}
+	spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
+	return IRQ_HANDLED;
+}
+
+static int __init msm_init_datamover(void)
+{
+	int i;
+	for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
+		INIT_LIST_HEAD(&ready_commands[i]);
+		INIT_LIST_HEAD(&active_commands[i]);
+		writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
+	}
+	return request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
+}
+
+arch_initcall(msm_init_datamover);
+
diff --git a/arch/arm/mach-msm/idle.S b/arch/arm/mach-msm/idle.S
new file mode 100644
index 0000000..2b1cb7f
--- /dev/null
+++ b/arch/arm/mach-msm/idle.S
@@ -0,0 +1,36 @@
+/* linux/include/asm-arm/arch-msm/idle.S
+ *
+ * Idle processing for MSM7K - work around bugs with SWFI.
+ *
+ * Copyright (c) 2007 QUALCOMM Incorporated.
+ * Copyright (C) 2007 Google, Inc. 
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */ 
+		
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ENTRY(arch_idle)
+#ifdef CONFIG_MSM7X00A_IDLE
+	mrc     p15, 0, r1, c1, c0, 0    /* read current CR    */
+	bic     r0, r1, #(1 << 2)        /* clear dcache bit   */
+	bic     r0, r0, #(1 << 12)       /* clear icache bit   */
+	mcr     p15, 0, r0, c1, c0, 0    /* disable d/i cache  */
+
+	mov     r0, #0                   /* prepare wfi value  */
+	mcr     p15, 0, r0, c7, c10, 0   /* flush the cache    */
+	mcr     p15, 0, r0, c7, c10, 4   /* memory barrier     */
+	mcr     p15, 0, r0, c7, c0, 4    /* wait for interrupt */
+
+	mcr     p15, 0, r1, c1, c0, 0    /* restore d/i cache  */
+#endif
+	mov     pc, lr
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
new file mode 100644
index 0000000..c39edb9
--- /dev/null
+++ b/arch/arm/mach-msm/io.c
@@ -0,0 +1,85 @@
+/* arch/arm/mach-msm/io.c
+ *
+ * MSM7K io support
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/arch/msm_iomap.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/board.h>
+
+#define MSM_DEVICE(name) { \
+		.virtual = MSM_##name##_BASE, \
+		.pfn = __phys_to_pfn(MSM_##name##_PHYS), \
+		.length = MSM_##name##_SIZE, \
+		.type = MT_DEVICE_NONSHARED, \
+	 }
+
+static struct map_desc msm_io_desc[] __initdata = {
+	MSM_DEVICE(VIC),
+	MSM_DEVICE(CSR),
+	MSM_DEVICE(GPT),
+	MSM_DEVICE(DMOV),
+	MSM_DEVICE(UART1),
+	MSM_DEVICE(UART2),
+	MSM_DEVICE(UART3),
+	MSM_DEVICE(I2C),
+	MSM_DEVICE(GPIO1),
+	MSM_DEVICE(GPIO2),
+	MSM_DEVICE(HSUSB),
+	MSM_DEVICE(CLK_CTL),
+	MSM_DEVICE(PMDH),
+	MSM_DEVICE(EMDH),
+	MSM_DEVICE(MDP),
+	{
+		.virtual =  MSM_SHARED_RAM_BASE,
+		.pfn =      __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+		.length =   MSM_SHARED_RAM_SIZE,
+		.type =     MT_DEVICE,
+	},
+};
+
+void __init msm_map_common_io(void)
+{
+	/* Make sure the peripheral register window is closed, since
+	 * we will use PTE flags (TEX[1]=1,B=0,C=1) to determine which
+	 * pages are peripheral interface or not.
+	 */
+	asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0));
+
+	iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc));
+}
+
+void __iomem *
+__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+{
+	if (mtype == MT_DEVICE) {
+		/* The peripherals in the 88000000 - D0000000 range
+		 * are only accessable by type MT_DEVICE_NONSHARED.
+		 * Adjust mtype as necessary to make this "just work."
+		 */
+		if ((phys_addr >= 0x88000000) && (phys_addr < 0xD0000000))
+			mtype = MT_DEVICE_NONSHARED;
+	}
+
+	return __arm_ioremap(phys_addr, size, mtype);
+}
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c
new file mode 100644
index 0000000..2415804
--- /dev/null
+++ b/arch/arm/mach-msm/irq.c
@@ -0,0 +1,154 @@
+/* linux/arch/arm/mach-msm/irq.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/timer.h>
+
+#include <linux/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/msm_iomap.h>
+
+#define VIC_REG(off) (MSM_VIC_BASE + (off))
+
+#define VIC_INT_SELECT0     VIC_REG(0x0000)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT1     VIC_REG(0x0004)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_EN0         VIC_REG(0x0010)
+#define VIC_INT_EN1         VIC_REG(0x0014)
+#define VIC_INT_ENCLEAR0    VIC_REG(0x0020)
+#define VIC_INT_ENCLEAR1    VIC_REG(0x0024)
+#define VIC_INT_ENSET0      VIC_REG(0x0030)
+#define VIC_INT_ENSET1      VIC_REG(0x0034)
+#define VIC_INT_TYPE0       VIC_REG(0x0040)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_TYPE1       VIC_REG(0x0044)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_POLARITY0   VIC_REG(0x0050)  /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY1   VIC_REG(0x0054)  /* 1: NEG, 0: POS */
+#define VIC_NO_PEND_VAL     VIC_REG(0x0060)
+#define VIC_INT_MASTEREN    VIC_REG(0x0064)  /* 1: IRQ, 2: FIQ     */
+#define VIC_PROTECTION      VIC_REG(0x006C)  /* 1: ENABLE          */
+#define VIC_CONFIG          VIC_REG(0x0068)  /* 1: USE ARM1136 VIC */
+#define VIC_IRQ_STATUS0     VIC_REG(0x0080)
+#define VIC_IRQ_STATUS1     VIC_REG(0x0084)
+#define VIC_FIQ_STATUS0     VIC_REG(0x0090)
+#define VIC_FIQ_STATUS1     VIC_REG(0x0094)
+#define VIC_RAW_STATUS0     VIC_REG(0x00A0)
+#define VIC_RAW_STATUS1     VIC_REG(0x00A4)
+#define VIC_INT_CLEAR0      VIC_REG(0x00B0)
+#define VIC_INT_CLEAR1      VIC_REG(0x00B4)
+#define VIC_SOFTINT0        VIC_REG(0x00C0)
+#define VIC_SOFTINT1        VIC_REG(0x00C4)
+#define VIC_IRQ_VEC_RD      VIC_REG(0x00D0)  /* pending int # */
+#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4)  /* pending vector addr */
+#define VIC_IRQ_VEC_WR      VIC_REG(0x00D8)
+#define VIC_IRQ_IN_SERVICE  VIC_REG(0x00E0)
+#define VIC_IRQ_IN_STACK    VIC_REG(0x00E4)
+#define VIC_TEST_BUS_SEL    VIC_REG(0x00E8)
+
+#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4))
+#define VIC_VECTADDR(n)     VIC_REG(0x0400+((n) * 4))
+
+static void msm_irq_ack(unsigned int irq)
+{
+	unsigned reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0);
+	irq = 1 << (irq & 31);
+	writel(irq, reg);
+}
+
+static void msm_irq_mask(unsigned int irq)
+{
+	unsigned reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0);
+	writel(1 << (irq & 31), reg);
+}
+
+static void msm_irq_unmask(unsigned int irq)
+{
+	unsigned reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0);
+	writel(1 << (irq & 31), reg);
+}
+
+static int msm_irq_set_wake(unsigned int irq, unsigned int on)
+{
+	return -EINVAL;
+}
+
+static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+	unsigned treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0);
+	unsigned preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0);
+	int b = 1 << (irq & 31);
+
+	if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
+		writel(readl(preg) | b, preg);
+	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+		writel(readl(preg) & (~b), preg);
+
+	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+		writel(readl(treg) | b, treg);
+		set_irq_handler(irq, handle_edge_irq);
+	}
+	if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
+		writel(readl(treg) & (~b), treg);
+		set_irq_handler(irq, handle_level_irq);
+	}
+	return 0;
+}
+
+static struct irq_chip msm_irq_chip = {
+	.name      = "msm",
+	.ack       = msm_irq_ack,
+	.mask      = msm_irq_mask,
+	.unmask    = msm_irq_unmask,
+	.set_wake  = msm_irq_set_wake,
+	.set_type  = msm_irq_set_type,
+};
+
+void __init msm_init_irq(void)
+{
+	unsigned n;
+
+	/* select level interrupts */
+	writel(0, VIC_INT_TYPE0);
+	writel(0, VIC_INT_TYPE1);
+
+	/* select highlevel interrupts */
+	writel(0, VIC_INT_POLARITY0);
+	writel(0, VIC_INT_POLARITY1);
+
+	/* select IRQ for all INTs */
+	writel(0, VIC_INT_SELECT0);
+	writel(0, VIC_INT_SELECT1);
+
+	/* disable all INTs */
+	writel(0, VIC_INT_EN0);
+	writel(0, VIC_INT_EN1);
+
+	/* don't use 1136 vic */
+	writel(0, VIC_CONFIG);
+
+	/* enable interrupt controller */
+	writel(1, VIC_INT_MASTEREN);
+
+	for (n = 0; n < NR_MSM_IRQS; n++) {
+		set_irq_chip(n, &msm_irq_chip);
+		set_irq_handler(n, handle_level_irq);
+		set_irq_flags(n, IRQF_VALID);
+	}
+}
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
new file mode 100644
index 0000000..bd4732d
--- /dev/null
+++ b/arch/arm/mach-msm/timer.c
@@ -0,0 +1,205 @@
+/* linux/arch/arm/mach-msm/timer.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+
+#include <asm/mach/time.h>
+#include <asm/arch/msm_iomap.h>
+
+#include <asm/io.h>
+
+#define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
+#define MSM_DGT_SHIFT (5)
+
+#define TIMER_MATCH_VAL         0x0000
+#define TIMER_COUNT_VAL         0x0004
+#define TIMER_ENABLE            0x0008
+#define TIMER_ENABLE_CLR_ON_MATCH_EN    2
+#define TIMER_ENABLE_EN                 1
+#define TIMER_CLEAR             0x000C
+
+#define CSR_PROTECTION          0x0020
+#define CSR_PROTECTION_EN               1
+
+#define GPT_HZ 32768
+#define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
+
+struct msm_clock {
+	struct clock_event_device   clockevent;
+	struct clocksource          clocksource;
+	struct irqaction            irq;
+	uint32_t                    regbase;
+	uint32_t                    freq;
+	uint32_t                    shift;
+};
+
+static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+	evt->event_handler(evt);
+	return IRQ_HANDLED;
+}
+
+static cycle_t msm_gpt_read(void)
+{
+	return readl(MSM_GPT_BASE + TIMER_COUNT_VAL);
+}
+
+static cycle_t msm_dgt_read(void)
+{
+	return readl(MSM_DGT_BASE + TIMER_COUNT_VAL) >> MSM_DGT_SHIFT;
+}
+
+static int msm_timer_set_next_event(unsigned long cycles,
+				    struct clock_event_device *evt)
+{
+	struct msm_clock *clock = container_of(evt, struct msm_clock, clockevent);
+	uint32_t now = readl(clock->regbase + TIMER_COUNT_VAL);
+	uint32_t alarm = now + (cycles << clock->shift);
+	int late;
+
+	writel(alarm, clock->regbase + TIMER_MATCH_VAL);
+	now = readl(clock->regbase + TIMER_COUNT_VAL);
+	late = now - alarm;
+	if (late >= (-2 << clock->shift) && late < DGT_HZ*5) {
+		printk(KERN_NOTICE "msm_timer_set_next_event(%lu) clock %s, "
+		       "alarm already expired, now %x, alarm %x, late %d\n",
+		       cycles, clock->clockevent.name, now, alarm, late);
+		return -ETIME;
+	}
+	return 0;
+}
+
+static void msm_timer_set_mode(enum clock_event_mode mode,
+			      struct clock_event_device *evt)
+{
+	struct msm_clock *clock = container_of(evt, struct msm_clock, clockevent);
+	switch (mode) {
+	case CLOCK_EVT_MODE_RESUME:
+	case CLOCK_EVT_MODE_PERIODIC:
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		writel(TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		writel(0, clock->regbase + TIMER_ENABLE);
+		break;
+	}
+}
+
+static struct msm_clock msm_clocks[] = {
+	{
+		.clockevent = {
+			.name           = "gp_timer",
+			.features       = CLOCK_EVT_FEAT_ONESHOT,
+			.shift          = 32,
+			.rating         = 200,
+			.set_next_event = msm_timer_set_next_event,
+			.set_mode       = msm_timer_set_mode,
+		},
+		.clocksource = {
+			.name           = "gp_timer",
+			.rating         = 200,
+			.read           = msm_gpt_read,
+			.mask           = CLOCKSOURCE_MASK(32),
+			.shift          = 24,
+			.flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+		},
+		.irq = {
+			.name    = "gp_timer",
+			.flags   = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
+			.handler = msm_timer_interrupt,
+			.dev_id  = &msm_clocks[0].clockevent,
+			.irq     = INT_GP_TIMER_EXP
+		},
+		.regbase = MSM_GPT_BASE,
+		.freq = GPT_HZ
+	},
+	{
+		.clockevent = {
+			.name           = "dg_timer",
+			.features       = CLOCK_EVT_FEAT_ONESHOT,
+			.shift          = 32 + MSM_DGT_SHIFT,
+			.rating         = 300,
+			.set_next_event = msm_timer_set_next_event,
+			.set_mode       = msm_timer_set_mode,
+		},
+		.clocksource = {
+			.name           = "dg_timer",
+			.rating         = 300,
+			.read           = msm_dgt_read,
+			.mask           = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)),
+			.shift          = 24 - MSM_DGT_SHIFT,
+			.flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+		},
+		.irq = {
+			.name    = "dg_timer",
+			.flags   = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
+			.handler = msm_timer_interrupt,
+			.dev_id  = &msm_clocks[1].clockevent,
+			.irq     = INT_DEBUG_TIMER_EXP
+		},
+		.regbase = MSM_DGT_BASE,
+		.freq = DGT_HZ >> MSM_DGT_SHIFT,
+		.shift = MSM_DGT_SHIFT
+	}
+};
+
+static void __init msm_timer_init(void)
+{
+	int i;
+	int res;
+
+	for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) {
+		struct msm_clock *clock = &msm_clocks[i];
+		struct clock_event_device *ce = &clock->clockevent;
+		struct clocksource *cs = &clock->clocksource;
+		writel(0, clock->regbase + TIMER_ENABLE);
+		writel(0, clock->regbase + TIMER_CLEAR);
+		writel(~0, clock->regbase + TIMER_MATCH_VAL);
+
+		ce->mult = div_sc(clock->freq, NSEC_PER_SEC, ce->shift);
+		/* allow at least 10 seconds to notice that the timer wrapped */
+		ce->max_delta_ns =
+			clockevent_delta2ns(0xf0000000 >> clock->shift, ce);
+		/* 4 gets rounded down to 3 */
+		ce->min_delta_ns = clockevent_delta2ns(4, ce);
+		ce->cpumask = cpumask_of_cpu(0);
+
+		cs->mult = clocksource_hz2mult(clock->freq, cs->shift);
+		res = clocksource_register(cs);
+		if (res)
+			printk(KERN_ERR "msm_timer_init: clocksource_register "
+			       "failed for %s\n", cs->name);
+
+		res = setup_irq(clock->irq.irq, &clock->irq);
+		if (res)
+			printk(KERN_ERR "msm_timer_init: setup_irq "
+			       "failed for %s\n", cs->name);
+
+		clockevents_register_device(ce);
+	}
+}
+
+struct sys_timer msm_timer = {
+	.init = msm_timer_init
+};
diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c
index e81fb5c..fb565c9 100644
--- a/arch/arm/mach-mx3/time.c
+++ b/arch/arm/mach-mx3/time.c
@@ -45,8 +45,6 @@
 {
 	unsigned int next_match;
 
-	write_seqlock(&xtime_lock);
-
 	if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) {
 		do {
 			timer_tick();
@@ -57,8 +55,6 @@
 				       __raw_readl(MXC_GPT_GPTCNT)) <= 0);
 	}
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 4762e20..ea07b54 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -33,12 +33,8 @@
 static irqreturn_t
 netx_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	timer_tick();
 
-	write_sequnlock(&xtime_lock);
-
 	/* acknowledge interrupt */
 	writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
 
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index d5f6ea1..f550b19 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -76,7 +76,7 @@
 	[1] = {
 		.start	= INT_730_MPU_EXT_NIRQ,
 		.end	= 0,
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
 };
 
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 9393824..bfa04fa 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -209,7 +209,7 @@
 	[1] = {
 		.start	= OMAP_GPIO_IRQ(0),
 		.end	= OMAP_GPIO_IRQ(0),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
 	},
 };
 
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 978cdab..0565198 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -208,7 +208,7 @@
 	[1] = {
 		.start	= OMAP_GPIO_IRQ(40),
 		.end	= OMAP_GPIO_IRQ(40),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
 	},
 };
 
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 7e63a41..7d2d8af 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -202,7 +202,7 @@
 	[1] = {
 		.start	= OMAP1510_INT_ETHER,
 		.end	= OMAP1510_INT_ETHER,
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
 };
 
@@ -269,7 +269,7 @@
 	[1] = {
 		.start	= OMAP_GPIO_IRQ(0),
 		.end	= OMAP_GPIO_IRQ(0),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
 	},
 };
 
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 182a98a..e2c8ffd 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -32,7 +32,6 @@
 #include <asm/arch/common.h>
 #include <asm/arch/dsp_common.h>
 #include <asm/arch/aic23.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/omapfb.h>
 #include <asm/arch/lcd_mipid.h>
 
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 5b575e6..8433344 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -31,7 +31,6 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/interrupt.h>
 #include <linux/i2c.h>
 
 #include <linux/mtd/mtd.h>
@@ -112,7 +111,7 @@
 	[1] = {
 		.start	= OMAP_GPIO_IRQ(0),
 		.end	= OMAP_GPIO_IRQ(0),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
 };
 
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index e47010f..ed7094a 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -42,7 +42,6 @@
 #include <asm/arch/common.h>
 #include <asm/arch/omap-alsa.h>
 
-#include <linux/input.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index c275d51..a9a0f66 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -44,7 +44,6 @@
 #include <asm/arch/common.h>
 #include <asm/arch/omap-alsa.h>
 
-#include <linux/input.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index e44437e..534dcfb 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -75,7 +75,7 @@
 	[1] = {
 		.start	= INT_730_MPU_EXT_NIRQ,
 		.end	= 0,
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
 };
 
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 214dd19..c82a1cd 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -117,7 +117,7 @@
 	[1] = {
 		.start	= OMAP_GPIO_IRQ(8),
 		.end	= OMAP_GPIO_IRQ(8),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
 };
 
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index d9805e3..06b7e54 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -639,7 +639,7 @@
 }
 
 
-static irqreturn_t  omap_wakeup_interrupt(int irq, void *dev)
+static irqreturn_t omap_wakeup_interrupt(int irq, void *dev)
 {
 	return IRQ_HANDLED;
 }
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 7e76fbf..64235de 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -104,7 +104,7 @@
 	[1] = {
 		.start	= OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
 		.end	= OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
 };
 
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 3bb49c1..7846551 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -26,7 +26,6 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/leds.h>
-#include <linux/irq.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -127,7 +126,7 @@
 	[1] = {
 		.start	= OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
 		.end	= OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
 };
 
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 8d322c2..3234dee 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -40,13 +40,9 @@
 
 static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW);
 	timer_tick();
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-orion/Kconfig b/arch/arm/mach-orion/Kconfig
new file mode 100644
index 0000000..1dcbb6a
--- /dev/null
+++ b/arch/arm/mach-orion/Kconfig
@@ -0,0 +1,41 @@
+if ARCH_ORION
+
+menu "Orion Implementations"
+
+config MACH_DB88F5281
+	bool "Marvell Orion-2 Development Board"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell Orion-2 (88F5281) Development Board
+
+config MACH_RD88F5182
+	bool "Marvell Orion-NAS Reference Design"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell Orion-NAS (88F5182) RD2
+
+config MACH_KUROBOX_PRO
+	bool "KuroBox Pro"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  KuroBox Pro platform.
+
+config MACH_DNS323
+	bool "D-Link DNS-323"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  D-Link DNS-323 platform.
+
+config MACH_TS209
+	bool "QNAP TS-109/TS-209"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  QNAP TS-109/TS-209 platform.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile
new file mode 100644
index 0000000..f91d937
--- /dev/null
+++ b/arch/arm/mach-orion/Makefile
@@ -0,0 +1,6 @@
+obj-y				+= common.o addr-map.o pci.o gpio.o irq.o time.o
+obj-$(CONFIG_MACH_DB88F5281)	+= db88f5281-setup.o
+obj-$(CONFIG_MACH_RD88F5182)	+= rd88f5182-setup.o
+obj-$(CONFIG_MACH_KUROBOX_PRO)	+= kurobox_pro-setup.o
+obj-$(CONFIG_MACH_DNS323)	+= dns323-setup.o
+obj-$(CONFIG_MACH_TS209)	+= ts209-setup.o
diff --git a/arch/arm/mach-orion/Makefile.boot b/arch/arm/mach-orion/Makefile.boot
new file mode 100644
index 0000000..67039c3
--- /dev/null
+++ b/arch/arm/mach-orion/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
diff --git a/arch/arm/mach-orion/addr-map.c b/arch/arm/mach-orion/addr-map.c
new file mode 100644
index 0000000..488da38
--- /dev/null
+++ b/arch/arm/mach-orion/addr-map.c
@@ -0,0 +1,484 @@
+/*
+ * arch/arm/mach-orion/addr-map.c
+ *
+ * Address map functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include "common.h"
+
+/*
+ * The Orion has fully programable address map. There's a separate address
+ * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIE, USB,
+ * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own
+ * address decode windows that allow it to access any of the Orion resources.
+ *
+ * CPU address decoding --
+ * Linux assumes that it is the boot loader that already setup the access to
+ * DDR and internal registers.
+ * Setup access to PCI and PCI-E IO/MEM space is issued by core.c.
+ * Setup access to various devices located on the device bus interface (e.g.
+ * flashes, RTC, etc) should be issued by machine-setup.c according to
+ * specific board population (by using orion_setup_cpu_win()).
+ *
+ * Non-CPU Masters address decoding --
+ * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
+ * banks only (the typical use case).
+ * Setup access for each master to DDR is issued by common.c.
+ *
+ * Note: although orion_setbits() and orion_clrbits() are not atomic
+ * no locking is necessary here since code in this file is only called
+ * at boot time when there is no concurrency issues.
+ */
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR		0
+#define TARGET_PCI		3
+#define TARGET_PCIE		4
+#define TARGET_DEV_BUS		1
+#define ATTR_DDR_CS(n)		(((n) ==0) ? 0xe :	\
+				((n) == 1) ? 0xd :	\
+				((n) == 2) ? 0xb :	\
+				((n) == 3) ? 0x7 : 0xf)
+#define ATTR_PCIE_MEM		0x59
+#define ATTR_PCIE_IO		0x51
+#define ATTR_PCI_MEM		0x59
+#define ATTR_PCI_IO		0x51
+#define ATTR_DEV_CS0		0x1e
+#define ATTR_DEV_CS1		0x1d
+#define ATTR_DEV_CS2		0x1b
+#define ATTR_DEV_BOOT		0xf
+#define WIN_EN			1
+
+/*
+ * Helpers to get DDR banks info
+ */
+#define DDR_BASE_CS(n)		ORION_DDR_REG(0x1500 + ((n) * 8))
+#define DDR_SIZE_CS(n)		ORION_DDR_REG(0x1504 + ((n) * 8))
+#define DDR_MAX_CS		4
+#define DDR_REG_TO_SIZE(reg)	(((reg) | 0xffffff) + 1)
+#define DDR_REG_TO_BASE(reg)	((reg) & 0xff000000)
+#define DDR_BANK_EN		1
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define CPU_WIN_CTRL(n)		ORION_BRIDGE_REG(0x000 | ((n) << 4))
+#define CPU_WIN_BASE(n)		ORION_BRIDGE_REG(0x004 | ((n) << 4))
+#define CPU_WIN_REMAP_LO(n)	ORION_BRIDGE_REG(0x008 | ((n) << 4))
+#define CPU_WIN_REMAP_HI(n)	ORION_BRIDGE_REG(0x00c | ((n) << 4))
+#define CPU_MAX_WIN		8
+
+/*
+ * Use this CPU address decode windows allocation
+ */
+#define CPU_WIN_PCIE_IO		0
+#define CPU_WIN_PCI_IO		1
+#define CPU_WIN_PCIE_MEM	2
+#define CPU_WIN_PCI_MEM		3
+#define CPU_WIN_DEV_BOOT	4
+#define CPU_WIN_DEV_CS0		5
+#define CPU_WIN_DEV_CS1		6
+#define CPU_WIN_DEV_CS2		7
+
+/*
+ * PCIE Address Decode Windows registers
+ */
+#define PCIE_BAR_CTRL(n)	ORION_PCIE_REG(0x1804 + ((n - 1) * 4))
+#define PCIE_BAR_LO(n)		ORION_PCIE_REG(0x0010 + ((n) * 8))
+#define PCIE_BAR_HI(n)		ORION_PCIE_REG(0x0014 + ((n) * 8))
+#define PCIE_WIN_CTRL(n)	ORION_PCIE_REG(0x1820 + ((n) << 4))
+#define PCIE_WIN_BASE(n)	ORION_PCIE_REG(0x1824 + ((n) << 4))
+#define PCIE_WIN_REMAP(n)	ORION_PCIE_REG(0x182c + ((n) << 4))
+#define PCIE_DEFWIN_CTRL	ORION_PCIE_REG(0x18b0)
+#define PCIE_EXPROM_WIN_CTRL	ORION_PCIE_REG(0x18c0)
+#define PCIE_EXPROM_WIN_REMP	ORION_PCIE_REG(0x18c4)
+#define PCIE_MAX_BARS		3
+#define PCIE_MAX_WINS		5
+
+/*
+ * Use PCIE BAR '1' for all DDR banks
+ */
+#define PCIE_DRAM_BAR		1
+
+/*
+ * PCI Address Decode Windows registers
+ */
+#define PCI_BAR_SIZE_DDR_CS(n)	(((n) == 0) ? ORION_PCI_REG(0xc08) : \
+				((n) == 1) ? ORION_PCI_REG(0xd08) :  \
+				((n) == 2) ? ORION_PCI_REG(0xc0c) :  \
+				((n) == 3) ? ORION_PCI_REG(0xd0c) : 0)
+#define PCI_BAR_REMAP_DDR_CS(n)	(((n) ==0) ? ORION_PCI_REG(0xc48) : \
+				((n) == 1) ? ORION_PCI_REG(0xd48) :  \
+				((n) == 2) ? ORION_PCI_REG(0xc4c) :  \
+				((n) == 3) ? ORION_PCI_REG(0xd4c) : 0)
+#define PCI_BAR_ENABLE		ORION_PCI_REG(0xc3c)
+#define PCI_CTRL_BASE_LO(n)	ORION_PCI_REG(0x1e00 | ((n) << 4))
+#define PCI_CTRL_BASE_HI(n)	ORION_PCI_REG(0x1e04 | ((n) << 4))
+#define PCI_CTRL_SIZE(n)	ORION_PCI_REG(0x1e08 | ((n) << 4))
+#define PCI_ADDR_DECODE_CTRL	ORION_PCI_REG(0xd3c)
+
+/*
+ * PCI configuration heleprs for BAR settings
+ */
+#define PCI_CONF_FUNC_BAR_CS(n)		((n) >> 1)
+#define PCI_CONF_REG_BAR_LO_CS(n)	(((n) & 1) ? 0x18 : 0x10)
+#define PCI_CONF_REG_BAR_HI_CS(n)	(((n) & 1) ? 0x1c : 0x14)
+
+/*
+ * Gigabit Ethernet Address Decode Windows registers
+ */
+#define ETH_WIN_BASE(win)	ORION_ETH_REG(0x200 + ((win) * 8))
+#define ETH_WIN_SIZE(win)	ORION_ETH_REG(0x204 + ((win) * 8))
+#define ETH_WIN_REMAP(win)	ORION_ETH_REG(0x280 + ((win) * 4))
+#define ETH_WIN_EN		ORION_ETH_REG(0x290)
+#define ETH_WIN_PROT		ORION_ETH_REG(0x294)
+#define ETH_MAX_WIN		6
+#define ETH_MAX_REMAP_WIN	4
+
+/*
+ * USB Address Decode Windows registers
+ */
+#define USB_WIN_CTRL(i, w)	((i == 0) ? ORION_USB0_REG(0x320 + ((w) << 4)) \
+					: ORION_USB1_REG(0x320 + ((w) << 4)))
+#define USB_WIN_BASE(i, w)	((i == 0) ? ORION_USB0_REG(0x324 + ((w) << 4)) \
+					: ORION_USB1_REG(0x324 + ((w) << 4)))
+#define USB_MAX_WIN		4
+
+/*
+ * SATA Address Decode Windows registers
+ */
+#define SATA_WIN_CTRL(win)	ORION_SATA_REG(0x30 + ((win) * 0x10))
+#define SATA_WIN_BASE(win)	ORION_SATA_REG(0x34 + ((win) * 0x10))
+#define SATA_MAX_WIN		4
+
+static int __init orion_cpu_win_can_remap(u32 win)
+{
+	u32 dev, rev;
+
+	orion_pcie_id(&dev, &rev);
+	if ((dev == MV88F5281_DEV_ID && win < 4)
+	    || (dev == MV88F5182_DEV_ID && win < 2)
+	    || (dev == MV88F5181_DEV_ID && win < 2))
+		return 1;
+
+	return 0;
+}
+
+void __init orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap)
+{
+	u32 win, attr, ctrl;
+
+	switch (target) {
+	case ORION_PCIE_IO:
+		target = TARGET_PCIE;
+		attr = ATTR_PCIE_IO;
+		win = CPU_WIN_PCIE_IO;
+		break;
+	case ORION_PCI_IO:
+		target = TARGET_PCI;
+		attr = ATTR_PCI_IO;
+		win = CPU_WIN_PCI_IO;
+		break;
+	case ORION_PCIE_MEM:
+		target = TARGET_PCIE;
+		attr = ATTR_PCIE_MEM;
+		win = CPU_WIN_PCIE_MEM;
+		break;
+	case ORION_PCI_MEM:
+		target = TARGET_PCI;
+		attr = ATTR_PCI_MEM;
+		win = CPU_WIN_PCI_MEM;
+		break;
+	case ORION_DEV_BOOT:
+		target = TARGET_DEV_BUS;
+		attr = ATTR_DEV_BOOT;
+		win = CPU_WIN_DEV_BOOT;
+		break;
+	case ORION_DEV0:
+		target = TARGET_DEV_BUS;
+		attr = ATTR_DEV_CS0;
+		win = CPU_WIN_DEV_CS0;
+		break;
+	case ORION_DEV1:
+		target = TARGET_DEV_BUS;
+		attr = ATTR_DEV_CS1;
+		win = CPU_WIN_DEV_CS1;
+		break;
+	case ORION_DEV2:
+		target = TARGET_DEV_BUS;
+		attr = ATTR_DEV_CS2;
+		win = CPU_WIN_DEV_CS2;
+		break;
+	case ORION_DDR:
+	case ORION_REGS:
+		/*
+		 * Must be mapped by bootloader.
+		 */
+	default:
+		target = attr = win = -1;
+		BUG();
+	}
+
+	base &= 0xffff0000;
+	ctrl = (((size - 1) & 0xffff0000) | (attr << 8) |
+		(target << 4) | WIN_EN);
+
+	orion_write(CPU_WIN_BASE(win), base);
+	orion_write(CPU_WIN_CTRL(win), ctrl);
+
+	if (orion_cpu_win_can_remap(win)) {
+		if (remap >= 0) {
+			orion_write(CPU_WIN_REMAP_LO(win), remap & 0xffff0000);
+			orion_write(CPU_WIN_REMAP_HI(win), 0);
+		} else {
+			orion_write(CPU_WIN_REMAP_LO(win), base);
+			orion_write(CPU_WIN_REMAP_HI(win), 0);
+		}
+	}
+}
+
+void __init orion_setup_cpu_wins(void)
+{
+	int i;
+
+	/*
+	 * First, disable and clear windows
+	 */
+	for (i = 0; i < CPU_MAX_WIN; i++) {
+		orion_write(CPU_WIN_BASE(i), 0);
+		orion_write(CPU_WIN_CTRL(i), 0);
+		if (orion_cpu_win_can_remap(i)) {
+			orion_write(CPU_WIN_REMAP_LO(i), 0);
+			orion_write(CPU_WIN_REMAP_HI(i), 0);
+		}
+	}
+
+	/*
+	 * Setup windows for PCI+PCIE IO+MAM space
+	 */
+	orion_setup_cpu_win(ORION_PCIE_IO, ORION_PCIE_IO_BASE,
+				ORION_PCIE_IO_SIZE, ORION_PCIE_IO_REMAP);
+	orion_setup_cpu_win(ORION_PCI_IO, ORION_PCI_IO_BASE,
+				ORION_PCI_IO_SIZE, ORION_PCI_IO_REMAP);
+	orion_setup_cpu_win(ORION_PCIE_MEM, ORION_PCIE_MEM_BASE,
+				ORION_PCIE_MEM_SIZE, -1);
+	orion_setup_cpu_win(ORION_PCI_MEM, ORION_PCI_MEM_BASE,
+				ORION_PCI_MEM_SIZE, -1);
+}
+
+/*
+ * Setup PCIE BARs and Address Decode Wins:
+ * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
+ * WIN[0-3] -> DRAM bank[0-3]
+ */
+void __init orion_setup_pcie_wins(void)
+{
+	u32 base, size, i;
+
+	/*
+	 * First, disable and clear BARs and windows
+	 */
+	for (i = 1; i < PCIE_MAX_BARS; i++) {
+		orion_write(PCIE_BAR_CTRL(i), 0);
+		orion_write(PCIE_BAR_LO(i), 0);
+		orion_write(PCIE_BAR_HI(i), 0);
+	}
+
+	for (i = 0; i < PCIE_MAX_WINS; i++) {
+		orion_write(PCIE_WIN_CTRL(i), 0);
+		orion_write(PCIE_WIN_BASE(i), 0);
+		orion_write(PCIE_WIN_REMAP(i), 0);
+	}
+
+	/*
+	 * Setup windows for DDR banks. Count total DDR size on the fly.
+	 */
+	base = DDR_REG_TO_BASE(orion_read(DDR_BASE_CS(0)));
+	size = 0;
+	for (i = 0; i < DDR_MAX_CS; i++) {
+		u32 bank_base, bank_size;
+		bank_size = orion_read(DDR_SIZE_CS(i));
+		bank_base = orion_read(DDR_BASE_CS(i));
+		if (bank_size & DDR_BANK_EN) {
+			bank_size = DDR_REG_TO_SIZE(bank_size);
+			bank_base = DDR_REG_TO_BASE(bank_base);
+			orion_write(PCIE_WIN_BASE(i), bank_base & 0xffff0000);
+			orion_write(PCIE_WIN_REMAP(i), 0);
+			orion_write(PCIE_WIN_CTRL(i),
+					((bank_size-1) & 0xffff0000) |
+					(ATTR_DDR_CS(i) << 8) |
+					(TARGET_DDR << 4) |
+					(PCIE_DRAM_BAR << 1) | WIN_EN);
+			size += bank_size;
+		}
+	}
+
+	/*
+	 * Setup BAR[1] to all DRAM banks
+	 */
+	orion_write(PCIE_BAR_LO(PCIE_DRAM_BAR), base & 0xffff0000);
+	orion_write(PCIE_BAR_HI(PCIE_DRAM_BAR), 0);
+	orion_write(PCIE_BAR_CTRL(PCIE_DRAM_BAR),
+				((size - 1) & 0xffff0000) | WIN_EN);
+}
+
+void __init orion_setup_pci_wins(void)
+{
+	u32 base, size, i;
+
+	/*
+	 * First, disable windows
+	 */
+	orion_write(PCI_BAR_ENABLE, 0xffffffff);
+
+	/*
+	 * Setup windows for DDR banks.
+	 */
+	for (i = 0; i < DDR_MAX_CS; i++) {
+		base = orion_read(DDR_BASE_CS(i));
+		size = orion_read(DDR_SIZE_CS(i));
+		if (size & DDR_BANK_EN) {
+			u32 bus, dev, func, reg, val;
+			size = DDR_REG_TO_SIZE(size);
+			base = DDR_REG_TO_BASE(base);
+			bus = orion_pci_local_bus_nr();
+			dev = orion_pci_local_dev_nr();
+			func = PCI_CONF_FUNC_BAR_CS(i);
+			reg = PCI_CONF_REG_BAR_LO_CS(i);
+			orion_pci_hw_rd_conf(bus, dev, func, reg, 4, &val);
+			orion_pci_hw_wr_conf(bus, dev, func, reg, 4,
+					(base & 0xfffff000) | (val & 0xfff));
+			reg = PCI_CONF_REG_BAR_HI_CS(i);
+			orion_pci_hw_wr_conf(bus, dev, func, reg, 4, 0);
+			orion_write(PCI_BAR_SIZE_DDR_CS(i),
+					(size - 1) & 0xfffff000);
+			orion_write(PCI_BAR_REMAP_DDR_CS(i),
+					base & 0xfffff000);
+			orion_clrbits(PCI_BAR_ENABLE, (1 << i));
+		}
+	}
+
+	/*
+	 * Disable automatic update of address remaping when writing to BARs
+	 */
+	orion_setbits(PCI_ADDR_DECODE_CTRL, 1);
+}
+
+void __init orion_setup_usb_wins(void)
+{
+	int i;
+	u32 usb_if, dev, rev;
+	u32 max_usb_if = 1;
+
+	orion_pcie_id(&dev, &rev);
+	if (dev == MV88F5182_DEV_ID)
+		max_usb_if = 2;
+
+	for (usb_if = 0; usb_if < max_usb_if; usb_if++) {
+		/*
+		 * First, disable and clear windows
+		 */
+		for (i = 0; i < USB_MAX_WIN; i++) {
+			orion_write(USB_WIN_BASE(usb_if, i), 0);
+			orion_write(USB_WIN_CTRL(usb_if, i), 0);
+		}
+
+		/*
+		 * Setup windows for DDR banks.
+		 */
+		for (i = 0; i < DDR_MAX_CS; i++) {
+			u32 base, size;
+			size = orion_read(DDR_SIZE_CS(i));
+			base = orion_read(DDR_BASE_CS(i));
+			if (size & DDR_BANK_EN) {
+				base = DDR_REG_TO_BASE(base);
+				size = DDR_REG_TO_SIZE(size);
+				orion_write(USB_WIN_CTRL(usb_if, i),
+						((size-1) & 0xffff0000) |
+						(ATTR_DDR_CS(i) << 8) |
+						(TARGET_DDR << 4) | WIN_EN);
+				orion_write(USB_WIN_BASE(usb_if, i),
+						base & 0xffff0000);
+			}
+		}
+	}
+}
+
+void __init orion_setup_eth_wins(void)
+{
+	int i;
+
+	/*
+	 * First, disable and clear windows
+	 */
+	for (i = 0; i < ETH_MAX_WIN; i++) {
+		orion_write(ETH_WIN_BASE(i), 0);
+		orion_write(ETH_WIN_SIZE(i), 0);
+		orion_setbits(ETH_WIN_EN, 1 << i);
+		orion_clrbits(ETH_WIN_PROT, 0x3 << (i * 2));
+		if (i < ETH_MAX_REMAP_WIN)
+			orion_write(ETH_WIN_REMAP(i), 0);
+	}
+
+	/*
+	 * Setup windows for DDR banks.
+	 */
+	for (i = 0; i < DDR_MAX_CS; i++) {
+		u32 base, size;
+		size = orion_read(DDR_SIZE_CS(i));
+		base = orion_read(DDR_BASE_CS(i));
+		if (size & DDR_BANK_EN) {
+			base = DDR_REG_TO_BASE(base);
+			size = DDR_REG_TO_SIZE(size);
+			orion_write(ETH_WIN_SIZE(i), (size-1) & 0xffff0000);
+			orion_write(ETH_WIN_BASE(i), (base & 0xffff0000) |
+					(ATTR_DDR_CS(i) << 8) |
+					TARGET_DDR);
+			orion_clrbits(ETH_WIN_EN, 1 << i);
+			orion_setbits(ETH_WIN_PROT, 0x3 << (i * 2));
+		}
+	}
+}
+
+void __init orion_setup_sata_wins(void)
+{
+	int i;
+
+	/*
+	 * First, disable and clear windows
+	 */
+	for (i = 0; i < SATA_MAX_WIN; i++) {
+		orion_write(SATA_WIN_BASE(i), 0);
+		orion_write(SATA_WIN_CTRL(i), 0);
+	}
+
+	/*
+	 * Setup windows for DDR banks.
+	 */
+	for (i = 0; i < DDR_MAX_CS; i++) {
+		u32 base, size;
+		size = orion_read(DDR_SIZE_CS(i));
+		base = orion_read(DDR_BASE_CS(i));
+		if (size & DDR_BANK_EN) {
+			base = DDR_REG_TO_BASE(base);
+			size = DDR_REG_TO_SIZE(size);
+			orion_write(SATA_WIN_CTRL(i),
+					((size-1) & 0xffff0000) |
+					(ATTR_DDR_CS(i) << 8) |
+					(TARGET_DDR << 4) | WIN_EN);
+			orion_write(SATA_WIN_BASE(i),
+					base & 0xffff0000);
+		}
+	}
+}
diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c
new file mode 100644
index 0000000..5e20b6b
--- /dev/null
+++ b/arch/arm/mach-orion/common.c
@@ -0,0 +1,315 @@
+/*
+ * arch/arm/mach-orion/common.c
+ *
+ * Core functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
+#include <asm/page.h>
+#include <asm/timex.h>
+#include <asm/mach/map.h>
+#include <asm/arch/orion.h>
+#include "common.h"
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc orion_io_desc[] __initdata = {
+	{
+		.virtual	= ORION_REGS_BASE,
+		.pfn		= __phys_to_pfn(ORION_REGS_BASE),
+		.length		= ORION_REGS_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= ORION_PCIE_IO_BASE,
+		.pfn		= __phys_to_pfn(ORION_PCIE_IO_BASE),
+		.length		= ORION_PCIE_IO_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= ORION_PCI_IO_BASE,
+		.pfn		= __phys_to_pfn(ORION_PCI_IO_BASE),
+		.length		= ORION_PCI_IO_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= ORION_PCIE_WA_BASE,
+		.pfn		= __phys_to_pfn(ORION_PCIE_WA_BASE),
+		.length		= ORION_PCIE_WA_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+void __init orion_map_io(void)
+{
+	iotable_init(orion_io_desc, ARRAY_SIZE(orion_io_desc));
+}
+
+/*****************************************************************************
+ * UART
+ ****************************************************************************/
+
+static struct resource orion_uart_resources[] = {
+	{
+		.start		= UART0_BASE,
+		.end		= UART0_BASE + 0xff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IRQ_ORION_UART0,
+		.end		= IRQ_ORION_UART0,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= UART1_BASE,
+		.end		= UART1_BASE + 0xff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IRQ_ORION_UART1,
+		.end		= IRQ_ORION_UART1,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct plat_serial8250_port orion_uart_data[] = {
+	{
+		.mapbase	= UART0_BASE,
+		.membase	= (char *)UART0_BASE,
+		.irq		= IRQ_ORION_UART0,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= ORION_TCLK,
+	},
+	{
+		.mapbase	= UART1_BASE,
+		.membase	= (char *)UART1_BASE,
+		.irq		= IRQ_ORION_UART1,
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= ORION_TCLK,
+	},
+	{ },
+};
+
+static struct platform_device orion_uart = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= orion_uart_data,
+	},
+	.resource		= orion_uart_resources,
+	.num_resources		= ARRAY_SIZE(orion_uart_resources),
+};
+
+/*******************************************************************************
+ * USB Controller - 2 interfaces
+ ******************************************************************************/
+
+static struct resource orion_ehci0_resources[] = {
+	{
+		.start	= ORION_USB0_REG_BASE,
+		.end	= ORION_USB0_REG_BASE + SZ_4K,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_ORION_USB0_CTRL,
+		.end	= IRQ_ORION_USB0_CTRL,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource orion_ehci1_resources[] = {
+	{
+		.start	= ORION_USB1_REG_BASE,
+		.end	= ORION_USB1_REG_BASE + SZ_4K,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_ORION_USB1_CTRL,
+		.end	= IRQ_ORION_USB1_CTRL,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ehci_dmamask = 0xffffffffUL;
+
+static struct platform_device orion_ehci0 = {
+	.name		= "orion-ehci",
+	.id		= 0,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.resource	= orion_ehci0_resources,
+	.num_resources	= ARRAY_SIZE(orion_ehci0_resources),
+};
+
+static struct platform_device orion_ehci1 = {
+	.name		= "orion-ehci",
+	.id		= 1,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.resource	= orion_ehci1_resources,
+	.num_resources	= ARRAY_SIZE(orion_ehci1_resources),
+};
+
+/*****************************************************************************
+ * Gigabit Ethernet port
+ * (The Orion and Discovery (MV643xx) families use the same Ethernet driver)
+ ****************************************************************************/
+
+static struct resource orion_eth_shared_resources[] = {
+	{
+		.start	= ORION_ETH_REG_BASE,
+		.end	= ORION_ETH_REG_BASE + 0xffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device orion_eth_shared = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= orion_eth_shared_resources,
+};
+
+static struct resource orion_eth_resources[] = {
+	{
+		.name	= "eth irq",
+		.start	= IRQ_ORION_ETH_SUM,
+		.end	= IRQ_ORION_ETH_SUM,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device orion_eth = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= orion_eth_resources,
+};
+
+void __init orion_eth_init(struct mv643xx_eth_platform_data *eth_data)
+{
+	orion_eth.dev.platform_data = eth_data;
+	platform_device_register(&orion_eth_shared);
+	platform_device_register(&orion_eth);
+}
+
+/*****************************************************************************
+ * I2C controller
+ * (The Orion and Discovery (MV643xx) families share the same I2C controller)
+ ****************************************************************************/
+
+static struct mv64xxx_i2c_pdata orion_i2c_pdata = {
+	.freq_m		= 8, /* assumes 166 MHz TCLK */
+	.freq_n		= 3,
+	.timeout	= 1000, /* Default timeout of 1 second */
+};
+
+static struct resource orion_i2c_resources[] = {
+	{
+		.name   = "i2c base",
+		.start  = I2C_BASE,
+		.end    = I2C_BASE + 0x20 -1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.name   = "i2c irq",
+		.start  = IRQ_ORION_I2C,
+		.end    = IRQ_ORION_I2C,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device orion_i2c = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(orion_i2c_resources),
+	.resource	= orion_i2c_resources,
+	.dev		= {
+		.platform_data = &orion_i2c_pdata,
+	},
+};
+
+/*****************************************************************************
+ * General
+ ****************************************************************************/
+
+/*
+ * Identify device ID and rev from PCIE configuration header space '0'.
+ */
+static void orion_id(u32 *dev, u32 *rev, char **dev_name)
+{
+	orion_pcie_id(dev, rev);
+
+	if (*dev == MV88F5281_DEV_ID) {
+		if (*rev == MV88F5281_REV_D2) {
+			*dev_name = "MV88F5281-D2";
+		} else if (*rev == MV88F5281_REV_D1) {
+			*dev_name = "MV88F5281-D1";
+		} else {
+			*dev_name = "MV88F5281-Rev-Unsupported";
+		}
+	} else if (*dev == MV88F5182_DEV_ID) {
+		if (*rev == MV88F5182_REV_A2) {
+			*dev_name = "MV88F5182-A2";
+		} else {
+			*dev_name = "MV88F5182-Rev-Unsupported";
+		}
+	} else if (*dev == MV88F5181_DEV_ID) {
+		if (*rev == MV88F5181_REV_B1) {
+			*dev_name = "MV88F5181-Rev-B1";
+		} else {
+			*dev_name = "MV88F5181-Rev-Unsupported";
+		}
+	} else {
+		*dev_name = "Device-Unknown";
+	}
+}
+
+void __init orion_init(void)
+{
+	char *dev_name;
+	u32 dev, rev;
+
+	orion_id(&dev, &rev, &dev_name);
+	printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, ORION_TCLK);
+
+	/*
+	 * Setup Orion address map
+	 */
+	orion_setup_cpu_wins();
+	orion_setup_usb_wins();
+	orion_setup_eth_wins();
+	orion_setup_pci_wins();
+	orion_setup_pcie_wins();
+	if (dev == MV88F5182_DEV_ID)
+		orion_setup_sata_wins();
+
+	/*
+	 * REgister devices
+	 */
+	platform_device_register(&orion_uart);
+	platform_device_register(&orion_ehci0);
+	if (dev == MV88F5182_DEV_ID)
+		platform_device_register(&orion_ehci1);
+	platform_device_register(&orion_i2c);
+}
diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h
new file mode 100644
index 0000000..06c10c0
--- /dev/null
+++ b/arch/arm/mach-orion/common.h
@@ -0,0 +1,78 @@
+#ifndef __ARCH_ORION_COMMON_H__
+#define __ARCH_ORION_COMMON_H__
+
+/*
+ * Basic Orion init functions used early by machine-setup.
+ */
+
+void __init orion_map_io(void);
+void __init orion_init_irq(void);
+void __init orion_init(void);
+
+/*
+ * Enumerations and functions for Orion windows mapping. Used by Orion core
+ * functions to map its interfaces and by the machine-setup to map its on-
+ * board devices. Details in /mach-orion/addr-map.c
+ */
+
+enum orion_target {
+	ORION_DEV_BOOT = 0,
+	ORION_DEV0,
+	ORION_DEV1,
+	ORION_DEV2,
+	ORION_PCIE_MEM,
+	ORION_PCIE_IO,
+	ORION_PCI_MEM,
+	ORION_PCI_IO,
+	ORION_DDR,
+	ORION_REGS,
+	ORION_MAX_TARGETS
+};
+
+void orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap);
+void orion_setup_cpu_wins(void);
+void orion_setup_eth_wins(void);
+void orion_setup_usb_wins(void);
+void orion_setup_pci_wins(void);
+void orion_setup_pcie_wins(void);
+void orion_setup_sata_wins(void);
+
+/*
+ * Shared code used internally by other Orion core functions.
+ * (/mach-orion/pci.c)
+ */
+
+struct pci_sys_data;
+struct pci_bus;
+
+void orion_pcie_id(u32 *dev, u32 *rev);
+u32 orion_pcie_local_bus_nr(void);
+u32 orion_pci_local_bus_nr(void);
+u32 orion_pci_local_dev_nr(void);
+int orion_pci_sys_setup(int nr, struct pci_sys_data *sys);
+struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
+int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 *val);
+int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 val);
+
+/*
+ * Valid GPIO pins according to MPP setup, used by machine-setup.
+ * (/mach-orion/gpio.c).
+ */
+
+void __init orion_gpio_set_valid_pins(u32 pins);
+void gpio_display(void);	/* debug */
+
+/*
+ * Orion system timer (clocksource + clockevnt, /mach-orion/time.c)
+ */
+extern struct sys_timer orion_timer;
+
+/*
+ * Pull in Orion Ethernet platform_data, used by machine-setup
+ */
+
+struct mv643xx_eth_platform_data;
+
+void __init orion_eth_init(struct mv643xx_eth_platform_data *eth_data);
+
+#endif /* __ARCH_ORION_COMMON_H__ */
diff --git a/arch/arm/mach-orion/db88f5281-setup.c b/arch/arm/mach-orion/db88f5281-setup.c
new file mode 100644
index 0000000..cb2a95c
--- /dev/null
+++ b/arch/arm/mach-orion/db88f5281-setup.c
@@ -0,0 +1,364 @@
+/*
+ * arch/arm/mach-orion/db88f5281-setup.c
+ *
+ * Marvell Orion-2 Development Board Setup
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/timer.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+/*****************************************************************************
+ * DB-88F5281 on board devices
+ ****************************************************************************/
+
+/*
+ * 512K NOR flash Device bus boot chip select
+ */
+
+#define DB88F5281_NOR_BOOT_BASE		0xf4000000
+#define DB88F5281_NOR_BOOT_SIZE		SZ_512K
+
+/*
+ * 7-Segment on Device bus chip select 0
+ */
+
+#define DB88F5281_7SEG_BASE		0xfa000000
+#define DB88F5281_7SEG_SIZE		SZ_1K
+
+/*
+ * 32M NOR flash on Device bus chip select 1
+ */
+
+#define DB88F5281_NOR_BASE		0xfc000000
+#define DB88F5281_NOR_SIZE		SZ_32M
+
+/*
+ * 32M NAND flash on Device bus chip select 2
+ */
+
+#define DB88F5281_NAND_BASE		0xfa800000
+#define DB88F5281_NAND_SIZE		SZ_1K
+
+/*
+ * PCI
+ */
+
+#define DB88F5281_PCI_SLOT0_OFFS		7
+#define DB88F5281_PCI_SLOT0_IRQ_PIN		12
+#define DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN	13
+
+/*****************************************************************************
+ * 512M NOR Flash on Device bus Boot CS
+ ****************************************************************************/
+
+static struct physmap_flash_data db88f5281_boot_flash_data = {
+	.width		= 1,	/* 8 bit bus width */
+};
+
+static struct resource db88f5281_boot_flash_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= DB88F5281_NOR_BOOT_BASE,
+	.end		= DB88F5281_NOR_BOOT_BASE + DB88F5281_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device db88f5281_boot_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &db88f5281_boot_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &db88f5281_boot_flash_resource,
+};
+
+/*****************************************************************************
+ * 32M NOR Flash on Device bus CS1
+ ****************************************************************************/
+
+static struct physmap_flash_data db88f5281_nor_flash_data = {
+	.width		= 4,	/* 32 bit bus width */
+};
+
+static struct resource db88f5281_nor_flash_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= DB88F5281_NOR_BASE,
+	.end		= DB88F5281_NOR_BASE + DB88F5281_NOR_SIZE - 1,
+};
+
+static struct platform_device db88f5281_nor_flash = {
+	.name		= "physmap-flash",
+	.id		= 1,
+	.dev		= {
+		.platform_data = &db88f5281_nor_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &db88f5281_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * 32M NAND Flash on Device bus CS2
+ ****************************************************************************/
+
+static struct mtd_partition db88f5281_nand_parts[] = {
+	{
+		.name = "kernel",
+		.offset = 0,
+		.size = SZ_2M,
+	},
+	{
+		.name = "root",
+		.offset = SZ_2M,
+		.size = (SZ_16M - SZ_2M),
+	},
+	{
+		.name = "user",
+		.offset = SZ_16M,
+		.size = SZ_8M,
+	},
+	{
+		.name = "recovery",
+		.offset = (SZ_16M + SZ_8M),
+		.size = SZ_8M,
+	},
+};
+
+static struct resource db88f5281_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= DB88F5281_NAND_BASE,
+	.end		= DB88F5281_NAND_BASE + DB88F5281_NAND_SIZE - 1,
+};
+
+static struct orion_nand_data db88f5281_nand_data = {
+	.parts		= db88f5281_nand_parts,
+	.nr_parts	= ARRAY_SIZE(db88f5281_nand_parts),
+	.cle		= 0,
+	.ale		= 1,
+	.width		= 8,
+};
+
+static struct platform_device db88f5281_nand_flash = {
+	.name		= "orion_nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &db88f5281_nand_data,
+	},
+	.resource	= &db88f5281_nand_resource,
+	.num_resources	= 1,
+};
+
+/*****************************************************************************
+ * 7-Segment on Device bus CS0
+ * Dummy counter every 2 sec
+ ****************************************************************************/
+
+static void __iomem *db88f5281_7seg;
+static struct timer_list db88f5281_timer;
+
+static void db88f5281_7seg_event(unsigned long data)
+{
+	static int count = 0;
+	writel(0, db88f5281_7seg + (count << 4));
+	count = (count + 1) & 7;
+	mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
+}
+
+static int __init db88f5281_7seg_init(void)
+{
+	if (machine_is_db88f5281()) {
+		db88f5281_7seg = ioremap(DB88F5281_7SEG_BASE,
+					DB88F5281_7SEG_SIZE);
+		if (!db88f5281_7seg) {
+			printk(KERN_ERR "Failed to ioremap db88f5281_7seg\n");
+			return -EIO;
+		}
+		setup_timer(&db88f5281_timer, db88f5281_7seg_event, 0);
+		mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
+	}
+
+	return 0;
+}
+
+__initcall(db88f5281_7seg_init);
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+void __init db88f5281_pci_preinit(void)
+{
+	int pin;
+
+	/*
+	 * Configure PCI GPIO IRQ pins
+	 */
+	pin = DB88F5281_PCI_SLOT0_IRQ_PIN;
+	if (gpio_request(pin, "PCI Int1") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "db88f5281_pci_preinit faield to "
+					"set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
+	}
+
+	pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN;
+	if (gpio_request(pin, "PCI Int2") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "db88f5281_pci_preinit faield "
+					"to set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
+	}
+}
+
+static int __init db88f5281_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/*
+	 * PCIE IRQ is connected internally (not GPIO)
+	 */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+
+	/*
+	 * PCI IRQs are connected via GPIOs
+	 */
+	switch (slot - DB88F5281_PCI_SLOT0_OFFS) {
+	case 0:
+		return gpio_to_irq(DB88F5281_PCI_SLOT0_IRQ_PIN);
+	case 1:
+	case 2:
+		return gpio_to_irq(DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN);
+	default:
+		return -1;
+	}
+}
+
+static struct hw_pci db88f5281_pci __initdata = {
+	.nr_controllers	= 2,
+	.preinit	= db88f5281_pci_preinit,
+	.swizzle	= pci_std_swizzle,
+	.setup		= orion_pci_sys_setup,
+	.scan		= orion_pci_sys_scan_bus,
+	.map_irq	= db88f5281_pci_map_irq,
+};
+
+static int __init db88f5281_pci_init(void)
+{
+	if (machine_is_db88f5281())
+		pci_common_init(&db88f5281_pci);
+
+	return 0;
+}
+
+subsys_initcall(db88f5281_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+static struct mv643xx_eth_platform_data db88f5281_eth_data = {
+	.phy_addr	= 8,
+	.force_phy_addr = 1,
+};
+
+/*****************************************************************************
+ * RTC DS1339 on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata db88f5281_i2c_rtc = {
+	.driver_name	= "rtc-ds1307",
+	.type		= "ds1339",
+	.addr		= 0x68,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct platform_device *db88f5281_devs[] __initdata = {
+	&db88f5281_boot_flash,
+	&db88f5281_nor_flash,
+	&db88f5281_nand_flash,
+};
+
+static void __init db88f5281_init(void)
+{
+	/*
+	 * Basic Orion setup. Need to be called early.
+	 */
+	orion_init();
+
+	/*
+	 * Setup the CPU address decode windows for our on-board devices
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, DB88F5281_NOR_BOOT_BASE,
+				DB88F5281_NOR_BOOT_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV0,	DB88F5281_7SEG_BASE,
+				DB88F5281_7SEG_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV1, DB88F5281_NOR_BASE,
+				DB88F5281_NOR_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV2,	DB88F5281_NAND_BASE,
+				DB88F5281_NAND_SIZE, -1);
+
+	/*
+	 * Setup Multiplexing Pins:
+	 * MPP0: GPIO (USB Over Current)	MPP1: GPIO (USB Vbat input)
+	 * MPP2: PCI_REQn[2]			MPP3: PCI_GNTn[2]
+	 * MPP4: PCI_REQn[3]			MPP5: PCI_GNTn[3]
+	 * MPP6: GPIO (JP0, CON17.2)		MPP7: GPIO (JP1, CON17.1)
+	 * MPP8: GPIO (JP2, CON11.2)		MPP9: GPIO (JP3, CON11.3)
+	 * MPP10: GPIO (RTC int)		MPP11: GPIO (Baud Rate Generator)
+	 * MPP12: GPIO (PCI int 1)		MPP13: GPIO (PCI int 2)
+	 * MPP14: NAND_REn[2]			MPP15: NAND_WEn[2]
+	 * MPP16: UART1_RX			MPP17: UART1_TX
+	 * MPP18: UART1_CTS			MPP19: UART1_RTS
+	 * MPP-DEV: DEV_D[16:31]
+	 */
+	orion_write(MPP_0_7_CTRL, 0x00222203);
+	orion_write(MPP_8_15_CTRL, 0x44000000);
+	orion_write(MPP_16_19_CTRL, 0);
+	orion_write(MPP_DEV_CTRL, 0);
+
+	orion_gpio_set_valid_pins(0x00003fc3);
+
+	platform_add_devices(db88f5281_devs, ARRAY_SIZE(db88f5281_devs));
+	i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
+	orion_eth_init(&db88f5281_eth_data);
+}
+
+MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")
+	/* Maintainer: Tzachi Perelstein <tzachi@marvell.com> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= db88f5281_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion/dns323-setup.c b/arch/arm/mach-orion/dns323-setup.c
new file mode 100644
index 0000000..c8a806f
--- /dev/null
+++ b/arch/arm/mach-orion/dns323-setup.c
@@ -0,0 +1,322 @@
+/*
+ * arch/arm/mach-orion/dns323-setup.c
+ *
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+#define DNS323_GPIO_LED_RIGHT_AMBER	1
+#define DNS323_GPIO_LED_LEFT_AMBER	2
+#define DNS323_GPIO_LED_POWER		5
+#define DNS323_GPIO_OVERTEMP		6
+#define DNS323_GPIO_RTC			7
+#define DNS323_GPIO_POWER_OFF		8
+#define DNS323_GPIO_KEY_POWER		9
+#define DNS323_GPIO_KEY_RESET		10
+
+/****************************************************************************
+ * PCI setup
+ */
+
+static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/* PCI-E */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+
+	pr_err("%s: requested mapping for unknown bus\n", __func__);
+
+	return -1;
+}
+
+static struct hw_pci dns323_pci __initdata = {
+	.nr_controllers = 1,
+	.swizzle	= pci_std_swizzle,
+	.setup		= orion_pci_sys_setup,
+	.scan		= orion_pci_sys_scan_bus,
+	.map_irq	= dns323_pci_map_irq,
+};
+
+static int __init dns323_pci_init(void)
+{
+	if (machine_is_dns323())
+		pci_common_init(&dns323_pci);
+
+	return 0;
+}
+
+subsys_initcall(dns323_pci_init);
+
+/****************************************************************************
+ * Ethernet
+ */
+
+static struct mv643xx_eth_platform_data dns323_eth_data = {
+	.phy_addr = 8,
+	.force_phy_addr = 1,
+};
+
+/****************************************************************************
+ * 8MiB NOR flash (Spansion S29GL064M90TFIR4)
+ *
+ * Layout as used by D-Link:
+ *  0x00000000-0x00010000 : "MTD1"
+ *  0x00010000-0x00020000 : "MTD2"
+ *  0x00020000-0x001a0000 : "Linux Kernel"
+ *  0x001a0000-0x007d0000 : "File System"
+ *  0x007d0000-0x00800000 : "u-boot"
+ */
+
+#define DNS323_NOR_BOOT_BASE 0xf4000000
+#define DNS323_NOR_BOOT_SIZE SZ_8M
+
+static struct mtd_partition dns323_partitions[] = {
+	{
+		.name	= "MTD1",
+		.size	= 0x00010000,
+		.offset	= 0,
+	}, {
+		.name	= "MTD2",
+		.size	= 0x00010000,
+		.offset = 0x00010000,
+	}, {
+		.name	= "Linux Kernel",
+		.size	= 0x00180000,
+		.offset	= 0x00020000,
+	}, {
+		.name	= "File System",
+		.size	= 0x00630000,
+		.offset	= 0x001A0000,
+	}, {
+		.name	= "u-boot",
+		.size	= 0x00030000,
+		.offset	= 0x007d0000,
+	}
+};
+
+static struct physmap_flash_data dns323_nor_flash_data = {
+	.width		= 1,
+	.parts		= dns323_partitions,
+	.nr_parts	= ARRAY_SIZE(dns323_partitions)
+};
+
+static struct resource dns323_nor_flash_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= DNS323_NOR_BOOT_BASE,
+	.end		= DNS323_NOR_BOOT_BASE + DNS323_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device dns323_nor_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= { .platform_data = &dns323_nor_flash_data, },
+	.resource	= &dns323_nor_flash_resource,
+	.num_resources	= 1,
+};
+
+/****************************************************************************
+ * GPIO LEDs (simple - doesn't use hardware blinking support)
+ */
+
+static struct gpio_led dns323_leds[] = {
+	{
+		.name = "power:blue",
+		.gpio = DNS323_GPIO_LED_POWER,
+		.active_low = 1,
+	}, {
+		.name = "right:amber",
+		.gpio = DNS323_GPIO_LED_RIGHT_AMBER,
+		.active_low = 1,
+	}, {
+		.name = "left:amber",
+		.gpio = DNS323_GPIO_LED_LEFT_AMBER,
+		.active_low = 1,
+	},
+};
+
+static struct gpio_led_platform_data dns323_led_data = {
+	.num_leds	= ARRAY_SIZE(dns323_leds),
+	.leds		= dns323_leds,
+};
+
+static struct platform_device dns323_gpio_leds = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev		= { .platform_data = &dns323_led_data, },
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ */
+
+static struct gpio_keys_button dns323_buttons[] = {
+	{
+		.code		= KEY_RESTART,
+		.gpio		= DNS323_GPIO_KEY_RESET,
+		.desc		= "Reset Button",
+		.active_low	= 1,
+	},
+	{
+		.code		= KEY_POWER,
+		.gpio		= DNS323_GPIO_KEY_POWER,
+		.desc		= "Power Button",
+		.active_low	= 1,
+	}
+};
+
+static struct gpio_keys_platform_data dns323_button_data = {
+	.buttons	= dns323_buttons,
+	.nbuttons       = ARRAY_SIZE(dns323_buttons),
+};
+
+static struct platform_device dns323_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= { .platform_data  = &dns323_button_data, },
+};
+
+/****************************************************************************
+ * General Setup
+ */
+
+static struct platform_device *dns323_plat_devices[] __initdata = {
+	&dns323_nor_flash,
+	&dns323_gpio_leds,
+	&dns323_button_device,
+};
+
+/*
+ * On the DNS-323 the following devices are attached via I2C:
+ *
+ *  i2c addr | chip        | description
+ *  0x3e     | GMT G760Af  | fan speed PWM controller
+ *  0x48     | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible)
+ *  0x68     | ST M41T80   | RTC w/ alarm
+ */
+static struct i2c_board_info __initdata dns323_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("g760a", 0x3e),
+		.type = "g760a",
+	},
+#if 0
+	/* this entry requires the new-style driver model lm75 driver,
+	 * for the meantime "insmod lm75.ko force_lm75=0,0x48" is needed */
+	{
+		I2C_BOARD_INFO("lm75", 0x48),
+		.type = "g751",
+	},
+#endif
+	{
+		I2C_BOARD_INFO("rtc-m41t80", 0x68),
+		.type = "m41t80",
+	}
+};
+
+/* DNS-323 specific power off method */
+static void dns323_power_off(void)
+{
+	pr_info("%s: triggering power-off...\n", __func__);
+	gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
+}
+
+static void __init dns323_init(void)
+{
+	/* Setup basic Orion functions. Need to be called early. */
+	orion_init();
+
+	/* setup flash mapping
+	 * CS3 holds a 8 MB Spansion S29GL064M90TFIR4
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, DNS323_NOR_BOOT_BASE,
+			    DNS323_NOR_BOOT_SIZE, -1);
+
+	/* DNS-323 has a Marvell 88X7042 SATA controller attached via PCIE
+	 *
+	 * Open a special address decode windows for the PCIE WA.
+	 */
+	orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
+	orion_write(ORION_REGS_BASE | 0x20070,
+		    (0x7941 | (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
+
+	/* set MPP to 0 as D-Link's 2.6.12.6 kernel did */
+	orion_write(MPP_0_7_CTRL, 0);
+	orion_write(MPP_8_15_CTRL, 0);
+	orion_write(MPP_16_19_CTRL, 0);
+	orion_write(MPP_DEV_CTRL, 0);
+
+	/* Define used GPIO pins
+
+	  GPIO Map:
+
+	  |  0 |     | PEX_RST_OUT (not controlled by GPIO)
+	  |  1 | Out | right amber LED (= sata ch0 LED)  (low-active)
+	  |  2 | Out | left  amber LED (= sata ch1 LED)  (low-active)
+	  |  3 | Out | //unknown//
+	  |  4 | Out | power button LED (low-active, together with pin #5)
+	  |  5 | Out | power button LED (low-active, together with pin #4)
+	  |  6 | In  | GMT G751-2f overtemp. shutdown signal (low-active)
+	  |  7 | In  | M41T80 nIRQ/OUT/SQW signal
+	  |  8 | Out | triggers power off (high-active)
+	  |  9 | In  | power button switch (low-active)
+	  | 10 | In  | reset button switch (low-active)
+	  | 11 | Out | //unknown//
+	  | 12 | Out | //unknown//
+	  | 13 | Out | //unknown//
+	  | 14 | Out | //unknown//
+	  | 15 | Out | //unknown//
+	*/
+	orion_gpio_set_valid_pins(0x07f6);
+
+	/* register dns323 specific power-off method */
+	if ((gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0)
+	    || (gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0))
+		pr_err("DNS323: failed to setup power-off GPIO\n");
+
+	pm_power_off = dns323_power_off;
+
+	/* register flash and other platform devices */
+	platform_add_devices(dns323_plat_devices,
+			     ARRAY_SIZE(dns323_plat_devices));
+
+	i2c_register_board_info(0, dns323_i2c_devices,
+				ARRAY_SIZE(dns323_i2c_devices));
+
+	orion_eth_init(&dns323_eth_data);
+}
+
+/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */
+MACHINE_START(DNS323, "D-Link DNS-323")
+	/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= dns323_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion/gpio.c b/arch/arm/mach-orion/gpio.c
new file mode 100644
index 0000000..d5f00c8
--- /dev/null
+++ b/arch/arm/mach-orion/gpio.c
@@ -0,0 +1,225 @@
+/*
+ * arch/arm/mach-orion/gpio.c
+ *
+ * GPIO functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <asm/gpio.h>
+#include <asm/arch/orion.h>
+#include "common.h"
+
+static DEFINE_SPINLOCK(gpio_lock);
+static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)];
+static const char *gpio_label[GPIO_MAX];  /* non null for allocated GPIOs */
+
+void __init orion_gpio_set_valid_pins(u32 pins)
+{
+	gpio_valid[0] = pins;
+}
+
+/*
+ * GENERIC_GPIO primitives
+ */
+int gpio_direction_input(unsigned pin)
+{
+	unsigned long flags;
+
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+		pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	/*
+	 * Some callers might have not used the gpio_request(),
+	 * so flag this pin as requested now.
+	 */
+	if (!gpio_label[pin])
+		gpio_label[pin] = "?";
+
+	orion_setbits(GPIO_IO_CONF, 1 << pin);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned pin, int value)
+{
+	unsigned long flags;
+	int mask;
+
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+		pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	/*
+	 * Some callers might have not used the gpio_request(),
+	 * so flag this pin as requested now.
+	 */
+	if (!gpio_label[pin])
+		gpio_label[pin] = "?";
+
+	mask = 1 << pin;
+	orion_clrbits(GPIO_BLINK_EN, mask);
+	if (value)
+		orion_setbits(GPIO_OUT, mask);
+	else
+		orion_clrbits(GPIO_OUT, mask);
+	orion_clrbits(GPIO_IO_CONF, mask);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+int gpio_get_value(unsigned pin)
+{
+	int val, mask = 1 << pin;
+
+	if (orion_read(GPIO_IO_CONF) & mask)
+		val = orion_read(GPIO_DATA_IN) ^ orion_read(GPIO_IN_POL);
+	else
+		val = orion_read(GPIO_OUT);
+
+	return val & mask;
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned pin, int value)
+{
+	unsigned long flags;
+	int mask = 1 << pin;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	orion_clrbits(GPIO_BLINK_EN, mask);
+	if (value)
+		orion_setbits(GPIO_OUT, mask);
+	else
+		orion_clrbits(GPIO_OUT, mask);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+void orion_gpio_set_blink(unsigned pin, int blink)
+{
+	unsigned long flags;
+	int mask = 1 << pin;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	orion_clrbits(GPIO_OUT, mask);
+	if (blink)
+		orion_setbits(GPIO_BLINK_EN, mask);
+	else
+		orion_clrbits(GPIO_BLINK_EN, mask);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(orion_gpio_set_blink);
+
+int gpio_request(unsigned pin, const char *label)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+		pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	if (gpio_label[pin]) {
+		pr_debug("%s: GPIO %d already used as %s\n",
+			 __FUNCTION__, pin, gpio_label[pin]);
+		ret = -EBUSY;
+	} else
+		gpio_label[pin] = label ? label : "?";
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned pin)
+{
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+		pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin);
+		return;
+	}
+
+	if (!gpio_label[pin])
+		pr_warning("%s: GPIO %d already freed\n", __FUNCTION__, pin);
+	else
+		gpio_label[pin] = NULL;
+}
+EXPORT_SYMBOL(gpio_free);
+
+/* Debug helper */
+void gpio_display(void)
+{
+	int i;
+
+	for (i = 0; i < GPIO_MAX; i++) {
+		printk(KERN_DEBUG "Pin-%d: ", i);
+
+		if (!test_bit(i, gpio_valid)) {
+			printk("non-GPIO\n");
+		} else if (!gpio_label[i]) {
+			printk("GPIO, free\n");
+		} else {
+			printk("GPIO, used by %s, ", gpio_label[i]);
+			if (orion_read(GPIO_IO_CONF) & (1 << i)) {
+				printk("input, active %s, level %s, edge %s\n",
+				((orion_read(GPIO_IN_POL) >> i) & 1) ? "low" : "high",
+				((orion_read(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked",
+				((orion_read(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked");
+			} else {
+				printk("output, val=%d\n", (orion_read(GPIO_OUT) >> i) & 1);
+			}
+		}
+	}
+
+	printk(KERN_DEBUG "MPP_0_7_CTRL (0x%08x) = 0x%08x\n",
+				MPP_0_7_CTRL, orion_read(MPP_0_7_CTRL));
+	printk(KERN_DEBUG "MPP_8_15_CTRL (0x%08x) = 0x%08x\n",
+				MPP_8_15_CTRL, orion_read(MPP_8_15_CTRL));
+	printk(KERN_DEBUG "MPP_16_19_CTRL (0x%08x) = 0x%08x\n",
+				MPP_16_19_CTRL, orion_read(MPP_16_19_CTRL));
+	printk(KERN_DEBUG "MPP_DEV_CTRL (0x%08x) = 0x%08x\n",
+				MPP_DEV_CTRL, orion_read(MPP_DEV_CTRL));
+	printk(KERN_DEBUG "GPIO_OUT (0x%08x) = 0x%08x\n",
+				GPIO_OUT, orion_read(GPIO_OUT));
+	printk(KERN_DEBUG "GPIO_IO_CONF (0x%08x) = 0x%08x\n",
+				GPIO_IO_CONF, orion_read(GPIO_IO_CONF));
+	printk(KERN_DEBUG "GPIO_BLINK_EN (0x%08x) = 0x%08x\n",
+				GPIO_BLINK_EN, orion_read(GPIO_BLINK_EN));
+	printk(KERN_DEBUG "GPIO_IN_POL (0x%08x) = 0x%08x\n",
+				GPIO_IN_POL, orion_read(GPIO_IN_POL));
+	printk(KERN_DEBUG "GPIO_DATA_IN (0x%08x) = 0x%08x\n",
+				GPIO_DATA_IN, orion_read(GPIO_DATA_IN));
+	printk(KERN_DEBUG "GPIO_LEVEL_MASK (0x%08x) = 0x%08x\n",
+				GPIO_LEVEL_MASK, orion_read(GPIO_LEVEL_MASK));
+	printk(KERN_DEBUG "GPIO_EDGE_CAUSE (0x%08x) = 0x%08x\n",
+				GPIO_EDGE_CAUSE, orion_read(GPIO_EDGE_CAUSE));
+	printk(KERN_DEBUG "GPIO_EDGE_MASK (0x%08x) = 0x%08x\n",
+				GPIO_EDGE_MASK, orion_read(GPIO_EDGE_MASK));
+}
diff --git a/arch/arm/mach-orion/irq.c b/arch/arm/mach-orion/irq.c
new file mode 100644
index 0000000..df7e12a
--- /dev/null
+++ b/arch/arm/mach-orion/irq.c
@@ -0,0 +1,241 @@
+/*
+ * arch/arm/mach-orion/irq.c
+ *
+ * Core IRQ functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/gpio.h>
+#include <asm/arch/orion.h>
+#include "common.h"
+
+/*****************************************************************************
+ * Orion GPIO IRQ
+ *
+ * GPIO_IN_POL register controlls whether GPIO_DATA_IN will hold the same
+ * value of the line or the opposite value.
+ *
+ * Level IRQ handlers: DATA_IN is used directly as cause register.
+ *                     Interrupt are masked by LEVEL_MASK registers.
+ * Edge IRQ handlers:  Change in DATA_IN are latched in EDGE_CAUSE.
+ *                     Interrupt are masked by EDGE_MASK registers.
+ * Both-edge handlers: Similar to regular Edge handlers, but also swaps
+ *                     the polarity to catch the next line transaction.
+ *                     This is a race condition that might not perfectly
+ *                     work on some use cases.
+ *
+ * Every eight GPIO lines are grouped (OR'ed) before going up to main
+ * cause register.
+ *
+ *                    EDGE  cause    mask
+ *        data-in   /--------| |-----| |----\
+ *     -----| |-----                         ---- to main cause reg
+ *           X      \----------------| |----/
+ *        polarity    LEVEL          mask
+ *
+ ****************************************************************************/
+static void orion_gpio_irq_ack(u32 irq)
+{
+	int pin = irq_to_gpio(irq);
+	if (irq_desc[irq].status & IRQ_LEVEL)
+		/*
+		 * Mask bit for level interrupt
+		 */
+		orion_clrbits(GPIO_LEVEL_MASK, 1 << pin);
+	else
+		/*
+		 * Clear casue bit for egde interrupt
+		 */
+		orion_clrbits(GPIO_EDGE_CAUSE, 1 << pin);
+}
+
+static void orion_gpio_irq_mask(u32 irq)
+{
+	int pin = irq_to_gpio(irq);
+	if (irq_desc[irq].status & IRQ_LEVEL)
+		orion_clrbits(GPIO_LEVEL_MASK, 1 << pin);
+	else
+		orion_clrbits(GPIO_EDGE_MASK, 1 << pin);
+}
+
+static void orion_gpio_irq_unmask(u32 irq)
+{
+	int pin = irq_to_gpio(irq);
+	if (irq_desc[irq].status & IRQ_LEVEL)
+		orion_setbits(GPIO_LEVEL_MASK, 1 << pin);
+	else
+		orion_setbits(GPIO_EDGE_MASK, 1 << pin);
+}
+
+static int orion_gpio_set_irq_type(u32 irq, u32 type)
+{
+	int pin = irq_to_gpio(irq);
+	struct irq_desc *desc;
+
+	if ((orion_read(GPIO_IO_CONF) & (1 << pin)) == 0) {
+		printk(KERN_ERR "orion_gpio_set_irq_type failed "
+				"(irq %d, pin %d).\n", irq, pin);
+		return -EINVAL;
+	}
+
+	desc = irq_desc + irq;
+
+	switch (type) {
+	case IRQT_HIGH:
+		desc->handle_irq = handle_level_irq;
+		desc->status |= IRQ_LEVEL;
+		orion_clrbits(GPIO_IN_POL, (1 << pin));
+		break;
+	case IRQT_LOW:
+		desc->handle_irq = handle_level_irq;
+		desc->status |= IRQ_LEVEL;
+		orion_setbits(GPIO_IN_POL, (1 << pin));
+		break;
+	case IRQT_RISING:
+		desc->handle_irq = handle_edge_irq;
+		desc->status &= ~IRQ_LEVEL;
+		orion_clrbits(GPIO_IN_POL, (1 << pin));
+		break;
+	case IRQT_FALLING:
+		desc->handle_irq = handle_edge_irq;
+		desc->status &= ~IRQ_LEVEL;
+		orion_setbits(GPIO_IN_POL, (1 << pin));
+		break;
+	case IRQT_BOTHEDGE:
+		desc->handle_irq = handle_edge_irq;
+		desc->status &= ~IRQ_LEVEL;
+		/*
+		 * set initial polarity based on current input level
+		 */
+		if ((orion_read(GPIO_IN_POL) ^ orion_read(GPIO_DATA_IN))
+		    & (1 << pin))
+			orion_setbits(GPIO_IN_POL, (1 << pin)); /* falling */
+		else
+			orion_clrbits(GPIO_IN_POL, (1 << pin)); /* rising */
+
+		break;
+	default:
+		printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type);
+		return -EINVAL;
+	}
+
+	desc->status &= ~IRQ_TYPE_SENSE_MASK;
+	desc->status |= type & IRQ_TYPE_SENSE_MASK;
+
+	return 0;
+}
+
+static struct irq_chip orion_gpio_irq_chip = {
+	.name		= "Orion-IRQ-GPIO",
+	.ack		= orion_gpio_irq_ack,
+	.mask		= orion_gpio_irq_mask,
+	.unmask		= orion_gpio_irq_unmask,
+	.set_type	= orion_gpio_set_irq_type,
+};
+
+static void orion_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	u32 cause, offs, pin;
+
+	BUG_ON(irq < IRQ_ORION_GPIO_0_7 || irq > IRQ_ORION_GPIO_24_31);
+	offs = (irq - IRQ_ORION_GPIO_0_7) * 8;
+	cause = (orion_read(GPIO_DATA_IN) & orion_read(GPIO_LEVEL_MASK)) |
+		(orion_read(GPIO_EDGE_CAUSE) & orion_read(GPIO_EDGE_MASK));
+
+	for (pin = offs; pin < offs + 8; pin++) {
+		if (cause & (1 << pin)) {
+			irq = gpio_to_irq(pin);
+			desc = irq_desc + irq;
+			if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) {
+				/* Swap polarity (race with GPIO line) */
+				u32 polarity = orion_read(GPIO_IN_POL);
+				polarity ^= 1 << pin;
+				orion_write(GPIO_IN_POL, polarity);
+			}
+			desc_handle_irq(irq, desc);
+		}
+	}
+}
+
+static void __init orion_init_gpio_irq(void)
+{
+	int i;
+	struct irq_desc *desc;
+
+	/*
+	 * Mask and clear GPIO IRQ interrupts
+	 */
+	orion_write(GPIO_LEVEL_MASK, 0x0);
+	orion_write(GPIO_EDGE_MASK, 0x0);
+	orion_write(GPIO_EDGE_CAUSE, 0x0);
+
+	/*
+	 * Register chained level handlers for GPIO IRQs by default.
+	 * User can use set_type() if he wants to use edge types handlers.
+	 */
+	for (i = IRQ_ORION_GPIO_START; i < NR_IRQS; i++) {
+		set_irq_chip(i, &orion_gpio_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		desc = irq_desc + i;
+		desc->status |= IRQ_LEVEL;
+		set_irq_flags(i, IRQF_VALID);
+	}
+	set_irq_chained_handler(IRQ_ORION_GPIO_0_7, orion_gpio_irq_handler);
+	set_irq_chained_handler(IRQ_ORION_GPIO_8_15, orion_gpio_irq_handler);
+	set_irq_chained_handler(IRQ_ORION_GPIO_16_23, orion_gpio_irq_handler);
+	set_irq_chained_handler(IRQ_ORION_GPIO_24_31, orion_gpio_irq_handler);
+}
+
+/*****************************************************************************
+ * Orion Main IRQ
+ ****************************************************************************/
+static void orion_main_irq_mask(u32 irq)
+{
+	orion_clrbits(MAIN_IRQ_MASK, 1 << irq);
+}
+
+static void orion_main_irq_unmask(u32 irq)
+{
+	orion_setbits(MAIN_IRQ_MASK, 1 << irq);
+}
+
+static struct irq_chip orion_main_irq_chip = {
+	.name		= "Orion-IRQ-Main",
+	.ack		= orion_main_irq_mask,
+	.mask		= orion_main_irq_mask,
+	.unmask		= orion_main_irq_unmask,
+};
+
+static void __init orion_init_main_irq(void)
+{
+	int i;
+
+	/*
+	 * Mask and clear Main IRQ interrupts
+	 */
+	orion_write(MAIN_IRQ_MASK, 0x0);
+	orion_write(MAIN_IRQ_CAUSE, 0x0);
+
+	/*
+	 * Register level handler for Main IRQs
+	 */
+	for (i = 0; i < IRQ_ORION_GPIO_START; i++) {
+		set_irq_chip(i, &orion_main_irq_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+}
+
+void __init orion_init_irq(void)
+{
+	orion_init_main_irq();
+	orion_init_gpio_irq();
+}
diff --git a/arch/arm/mach-orion/kurobox_pro-setup.c b/arch/arm/mach-orion/kurobox_pro-setup.c
new file mode 100644
index 0000000..2d812ed
--- /dev/null
+++ b/arch/arm/mach-orion/kurobox_pro-setup.c
@@ -0,0 +1,234 @@
+/*
+ * arch/arm/mach-orion/kurobox_pro-setup.c
+ *
+ * Maintainer: Ronen Shitrit <rshitrit@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+/*****************************************************************************
+ * KUROBOX-PRO Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define KUROBOX_PRO_NOR_BOOT_BASE	0xf4000000
+#define KUROBOX_PRO_NOR_BOOT_SIZE	SZ_256K
+
+/*
+ * 256M NAND flash on Device bus chip select 1
+ */
+
+#define KUROBOX_PRO_NAND_BASE		0xfc000000
+#define KUROBOX_PRO_NAND_SIZE		SZ_2M
+
+/*****************************************************************************
+ * 256MB NAND Flash on Device bus CS0
+ ****************************************************************************/
+
+static struct mtd_partition kurobox_pro_nand_parts[] = {
+	{
+		.name	= "uImage",
+		.offset	= 0,
+		.size	= SZ_4M,
+	},
+	{
+		.name	= "rootfs",
+		.offset	= SZ_4M,
+		.size	= SZ_64M,
+	},
+	{
+		.name	= "extra",
+		.offset	= SZ_4M + SZ_64M,
+		.size	= SZ_256M - (SZ_4M + SZ_64M),
+	},
+};
+
+static struct resource kurobox_pro_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= KUROBOX_PRO_NAND_BASE,
+	.end		= KUROBOX_PRO_NAND_BASE + KUROBOX_PRO_NAND_SIZE - 1,
+};
+
+static struct orion_nand_data kurobox_pro_nand_data = {
+	.parts		= kurobox_pro_nand_parts,
+	.nr_parts	= ARRAY_SIZE(kurobox_pro_nand_parts),
+	.cle		= 0,
+	.ale		= 1,
+	.width		= 8,
+};
+
+static struct platform_device kurobox_pro_nand_flash = {
+	.name		= "orion_nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &kurobox_pro_nand_data,
+	},
+	.resource	= &kurobox_pro_nand_resource,
+	.num_resources	= 1,
+};
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data kurobox_pro_nor_flash_data = {
+	.width		= 1,
+};
+
+static struct resource kurobox_pro_nor_flash_resource = {
+	.flags			= IORESOURCE_MEM,
+	.start			= KUROBOX_PRO_NOR_BOOT_BASE,
+	.end			= KUROBOX_PRO_NOR_BOOT_BASE + KUROBOX_PRO_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device kurobox_pro_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= 0,
+	.dev		= {
+		.platform_data	= &kurobox_pro_nor_flash_data,
+	},
+	.num_resources		= 1,
+	.resource		= &kurobox_pro_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/*
+	 * PCI isn't used on the Kuro
+	 */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+	else
+		printk(KERN_ERR "kurobox_pro_pci_map_irq failed, unknown bus\n");
+
+	return -1;
+}
+
+static struct hw_pci kurobox_pro_pci __initdata = {
+	.nr_controllers	= 1,
+	.swizzle	= pci_std_swizzle,
+	.setup		= orion_pci_sys_setup,
+	.scan		= orion_pci_sys_scan_bus,
+	.map_irq	= kurobox_pro_pci_map_irq,
+};
+
+static int __init kurobox_pro_pci_init(void)
+{
+	if (machine_is_kurobox_pro())
+		pci_common_init(&kurobox_pro_pci);
+
+	return 0;
+}
+
+subsys_initcall(kurobox_pro_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data kurobox_pro_eth_data = {
+	.phy_addr	= 8,
+	.force_phy_addr = 1,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = {
+       .driver_name    = "rtc-rs5c372",
+       .type           = "rs5c372a",
+       .addr           = 0x32,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct platform_device *kurobox_pro_devices[] __initdata = {
+	&kurobox_pro_nor_flash,
+	&kurobox_pro_nand_flash,
+};
+
+static void __init kurobox_pro_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion_init();
+
+	/*
+	 * Setup the CPU address decode windows for our devices
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, KUROBOX_PRO_NOR_BOOT_BASE,
+				KUROBOX_PRO_NOR_BOOT_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV0,	KUROBOX_PRO_NAND_BASE,
+				KUROBOX_PRO_NAND_SIZE, -1);
+	/*
+	 * Open a special address decode windows for the PCIE WA.
+	 */
+	orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
+	orion_write(ORION_REGS_BASE | 0x20070, (0x7941 |
+		(((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
+
+	/*
+	 * Setup Multiplexing Pins --
+	 * MPP[0-1] Not used
+	 * MPP[2] GPIO Micon
+	 * MPP[3] GPIO RTC
+	 * MPP[4-5] Not used
+	 * MPP[6] Nand Flash REn
+	 * MPP[7] Nand Flash WEn
+	 * MPP[8-11] Not used
+	 * MPP[12] SATA 0 presence Indication
+	 * MPP[13] SATA 1 presence Indication
+	 * MPP[14] SATA 0 active Indication
+	 * MPP[15] SATA 1 active indication
+	 * MPP[16-19] Not used
+	 */
+	orion_write(MPP_0_7_CTRL, 0x44220003);
+	orion_write(MPP_8_15_CTRL, 0x55550000);
+	orion_write(MPP_16_19_CTRL, 0x0);
+
+	orion_gpio_set_valid_pins(0x0000000c);
+
+	platform_add_devices(kurobox_pro_devices, ARRAY_SIZE(kurobox_pro_devices));
+	i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);
+	orion_eth_init(&kurobox_pro_eth_data);
+}
+
+MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")
+	/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= kurobox_pro_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion/pci.c b/arch/arm/mach-orion/pci.c
new file mode 100644
index 0000000..0498d7c
--- /dev/null
+++ b/arch/arm/mach-orion/pci.c
@@ -0,0 +1,557 @@
+/*
+ * arch/arm/mach-orion/pci.c
+ *
+ * PCI and PCIE functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/mach/pci.h>
+#include "common.h"
+
+/*****************************************************************************
+ * Orion has one PCIE controller and one PCI controller.
+ *
+ * Note1: The local PCIE bus number is '0'. The local PCI bus number
+ * follows the scanned PCIE bridged busses, if any.
+ *
+ * Note2: It is possible for PCI/PCIE agents to access many subsystem's
+ * space, by configuring BARs and Address Decode Windows, e.g. flashes on
+ * device bus, Orion registers, etc. However this code only enable the
+ * access to DDR banks.
+ ****************************************************************************/
+
+
+/*****************************************************************************
+ * PCIE controller
+ ****************************************************************************/
+#define PCIE_CTRL		ORION_PCIE_REG(0x1a00)
+#define PCIE_STAT		ORION_PCIE_REG(0x1a04)
+#define PCIE_DEV_ID		ORION_PCIE_REG(0x0000)
+#define PCIE_CMD_STAT		ORION_PCIE_REG(0x0004)
+#define PCIE_DEV_REV		ORION_PCIE_REG(0x0008)
+#define PCIE_MASK		ORION_PCIE_REG(0x1910)
+#define PCIE_CONF_ADDR		ORION_PCIE_REG(0x18f8)
+#define PCIE_CONF_DATA		ORION_PCIE_REG(0x18fc)
+
+/*
+ * PCIE_STAT bits
+ */
+#define PCIE_STAT_LINK_DOWN		1
+#define PCIE_STAT_BUS_OFFS		8
+#define PCIE_STAT_BUS_MASK		(0xff << PCIE_STAT_BUS_OFFS)
+#define PCIE_STAT_DEV_OFFS		20
+#define PCIE_STAT_DEV_MASK		(0x1f << PCIE_STAT_DEV_OFFS)
+
+/*
+ * PCIE_CONF_ADDR bits
+ */
+#define PCIE_CONF_REG(r)		((((r) & 0xf00) << 24) | ((r) & 0xfc))
+#define PCIE_CONF_FUNC(f)		(((f) & 0x3) << 8)
+#define PCIE_CONF_DEV(d)		(((d) & 0x1f) << 11)
+#define PCIE_CONF_BUS(b)		(((b) & 0xff) << 16)
+#define PCIE_CONF_ADDR_EN		(1 << 31)
+
+/*
+ * PCIE config cycles are done by programming the PCIE_CONF_ADDR register
+ * and then reading the PCIE_CONF_DATA register. Need to make sure these
+ * transactions are atomic.
+ */
+static DEFINE_SPINLOCK(orion_pcie_lock);
+
+void orion_pcie_id(u32 *dev, u32 *rev)
+{
+	*dev = orion_read(PCIE_DEV_ID) >> 16;
+	*rev = orion_read(PCIE_DEV_REV) & 0xff;
+}
+
+u32 orion_pcie_local_bus_nr(void)
+{
+	u32 stat = orion_read(PCIE_STAT);
+	return((stat & PCIE_STAT_BUS_MASK) >> PCIE_STAT_BUS_OFFS);
+}
+
+static u32 orion_pcie_local_dev_nr(void)
+{
+	u32 stat = orion_read(PCIE_STAT);
+	return((stat & PCIE_STAT_DEV_MASK) >> PCIE_STAT_DEV_OFFS);
+}
+
+static u32 orion_pcie_no_link(void)
+{
+	u32 stat = orion_read(PCIE_STAT);
+	return(stat & PCIE_STAT_LINK_DOWN);
+}
+
+static void orion_pcie_set_bus_nr(int nr)
+{
+	orion_clrbits(PCIE_STAT, PCIE_STAT_BUS_MASK);
+	orion_setbits(PCIE_STAT, nr << PCIE_STAT_BUS_OFFS);
+}
+
+static void orion_pcie_master_slave_enable(void)
+{
+	orion_setbits(PCIE_CMD_STAT, PCI_COMMAND_MASTER |
+					  PCI_COMMAND_IO |
+					  PCI_COMMAND_MEMORY);
+}
+
+static void orion_pcie_enable_interrupts(void)
+{
+	/*
+	 * Enable interrupts lines
+	 * INTA[24] INTB[25] INTC[26] INTD[27]
+	 */
+	orion_setbits(PCIE_MASK, 0xf<<24);
+}
+
+static int orion_pcie_valid_config(u32 bus, u32 dev)
+{
+	/*
+	 * Don't go out when trying to access --
+	 * 1. our own device
+	 * 2. where there's no device connected (no link)
+	 * 3. nonexisting devices on local bus
+	 */
+
+	if ((orion_pcie_local_bus_nr() == bus) &&
+	   (orion_pcie_local_dev_nr() == dev))
+		return 0;
+
+	if (orion_pcie_no_link())
+		return 0;
+
+	if (bus == orion_pcie_local_bus_nr())
+		if (((orion_pcie_local_dev_nr() == 0) && (dev != 1)) ||
+		   ((orion_pcie_local_dev_nr() != 0) && (dev != 0)))
+		return 0;
+
+	return 1;
+}
+
+static int orion_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+						int size, u32 *val)
+{
+	unsigned long flags;
+	unsigned int dev, rev, pcie_addr;
+
+	if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	spin_lock_irqsave(&orion_pcie_lock, flags);
+
+	orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) |
+			PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+			PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+			PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN);
+
+	orion_pcie_id(&dev, &rev);
+	if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
+		/* extended register space */
+		pcie_addr = ORION_PCIE_WA_BASE;
+		pcie_addr |= PCIE_CONF_BUS(bus->number) |
+			PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+			PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+			PCIE_CONF_REG(where);
+		*val = orion_read(pcie_addr);
+	} else
+		*val = orion_read(PCIE_CONF_DATA);
+
+	if (size == 1)
+		*val = (*val >> (8*(where & 0x3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8*(where & 0x3))) & 0xffff;
+
+	spin_unlock_irqrestore(&orion_pcie_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int orion_pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where,
+						int size, u32 val)
+{
+	unsigned long flags;
+	int ret;
+
+	if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&orion_pcie_lock, flags);
+
+	ret = PCIBIOS_SUCCESSFUL;
+
+	orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) |
+			PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+			PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+			PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN);
+
+	if (size == 4) {
+		__raw_writel(val, PCIE_CONF_DATA);
+	} else if (size == 2) {
+		__raw_writew(val, PCIE_CONF_DATA + (where & 0x3));
+	} else if (size == 1) {
+		__raw_writeb(val, PCIE_CONF_DATA + (where & 0x3));
+	} else {
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	spin_unlock_irqrestore(&orion_pcie_lock, flags);
+
+	return ret;
+}
+
+struct pci_ops orion_pcie_ops = {
+	.read = orion_pcie_rd_conf,
+	.write = orion_pcie_wr_conf,
+};
+
+
+static int orion_pcie_setup(struct pci_sys_data *sys)
+{
+	struct resource *res;
+
+	/*
+	 * Master + Slave enable
+	 */
+	orion_pcie_master_slave_enable();
+
+	/*
+	 * Enable interrupts lines A-D
+	 */
+	orion_pcie_enable_interrupts();
+
+	/*
+	 * Request resource
+	 */
+	res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+	if (!res)
+		panic("orion_pci_setup unable to alloc resources");
+
+	/*
+	 * IORESOURCE_IO
+	 */
+	res[0].name = "PCI-EX I/O Space";
+	res[0].flags = IORESOURCE_IO;
+	res[0].start = ORION_PCIE_IO_REMAP;
+	res[0].end = res[0].start + ORION_PCIE_IO_SIZE - 1;
+	if (request_resource(&ioport_resource, &res[0]))
+		panic("Request PCIE IO resource failed\n");
+	sys->resource[0] = &res[0];
+
+	/*
+	 * IORESOURCE_MEM
+	 */
+	res[1].name = "PCI-EX Memory Space";
+	res[1].flags = IORESOURCE_MEM;
+	res[1].start = ORION_PCIE_MEM_BASE;
+	res[1].end = res[1].start + ORION_PCIE_MEM_SIZE - 1;
+	if (request_resource(&iomem_resource, &res[1]))
+		panic("Request PCIE Memory resource failed\n");
+	sys->resource[1] = &res[1];
+
+	sys->resource[2] = NULL;
+	sys->io_offset = 0;
+
+	return 1;
+}
+
+/*****************************************************************************
+ * PCI controller
+ ****************************************************************************/
+#define PCI_MODE		ORION_PCI_REG(0xd00)
+#define PCI_CMD			ORION_PCI_REG(0xc00)
+#define PCI_P2P_CONF		ORION_PCI_REG(0x1d14)
+#define PCI_CONF_ADDR		ORION_PCI_REG(0xc78)
+#define PCI_CONF_DATA		ORION_PCI_REG(0xc7c)
+
+/*
+ * PCI_MODE bits
+ */
+#define PCI_MODE_64BIT			(1 << 2)
+#define PCI_MODE_PCIX			((1 << 4) | (1 << 5))
+
+/*
+ * PCI_CMD bits
+ */
+#define PCI_CMD_HOST_REORDER		(1 << 29)
+
+/*
+ * PCI_P2P_CONF bits
+ */
+#define PCI_P2P_BUS_OFFS		16
+#define PCI_P2P_BUS_MASK		(0xff << PCI_P2P_BUS_OFFS)
+#define PCI_P2P_DEV_OFFS		24
+#define PCI_P2P_DEV_MASK		(0x1f << PCI_P2P_DEV_OFFS)
+
+/*
+ * PCI_CONF_ADDR bits
+ */
+#define PCI_CONF_REG(reg)		((reg) & 0xfc)
+#define PCI_CONF_FUNC(func)		(((func) & 0x3) << 8)
+#define PCI_CONF_DEV(dev)		(((dev) & 0x1f) << 11)
+#define PCI_CONF_BUS(bus)		(((bus) & 0xff) << 16)
+#define PCI_CONF_ADDR_EN		(1 << 31)
+
+/*
+ * Internal configuration space
+ */
+#define PCI_CONF_FUNC_STAT_CMD		0
+#define PCI_CONF_REG_STAT_CMD		4
+#define PCIX_STAT			0x64
+#define PCIX_STAT_BUS_OFFS		8
+#define PCIX_STAT_BUS_MASK		(0xff << PCIX_STAT_BUS_OFFS)
+
+/*
+ * PCI config cycles are done by programming the PCI_CONF_ADDR register
+ * and then reading the PCI_CONF_DATA register. Need to make sure these
+ * transactions are atomic.
+ */
+static DEFINE_SPINLOCK(orion_pci_lock);
+
+u32 orion_pci_local_bus_nr(void)
+{
+	u32 conf = orion_read(PCI_P2P_CONF);
+	return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
+}
+
+u32 orion_pci_local_dev_nr(void)
+{
+	u32 conf = orion_read(PCI_P2P_CONF);
+	return((conf & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS);
+}
+
+int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func,
+					u32 where, u32 size, u32 *val)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&orion_pci_lock, flags);
+
+	orion_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) |
+			PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
+			PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN);
+
+	*val = orion_read(PCI_CONF_DATA);
+
+	if (size == 1)
+		*val = (*val >> (8*(where & 0x3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8*(where & 0x3))) & 0xffff;
+
+	spin_unlock_irqrestore(&orion_pci_lock, flags);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func,
+					u32 where, u32 size, u32 val)
+{
+	unsigned long flags;
+	int ret = PCIBIOS_SUCCESSFUL;
+
+	spin_lock_irqsave(&orion_pci_lock, flags);
+
+	orion_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) |
+			PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
+			PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN);
+
+	if (size == 4) {
+		__raw_writel(val, PCI_CONF_DATA);
+	} else if (size == 2) {
+		__raw_writew(val, PCI_CONF_DATA + (where & 0x3));
+	} else if (size == 1) {
+		__raw_writeb(val, PCI_CONF_DATA + (where & 0x3));
+	} else {
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	spin_unlock_irqrestore(&orion_pci_lock, flags);
+
+	return ret;
+}
+
+static int orion_pci_rd_conf(struct pci_bus *bus, u32 devfn,
+				int where, int size, u32 *val)
+{
+	/*
+	 * Don't go out for local device
+	 */
+	if ((orion_pci_local_bus_nr() == bus->number) &&
+	   (orion_pci_local_dev_nr() == PCI_SLOT(devfn))) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	return orion_pci_hw_rd_conf(bus->number, PCI_SLOT(devfn),
+					PCI_FUNC(devfn), where, size, val);
+}
+
+static int orion_pci_wr_conf(struct pci_bus *bus, u32 devfn,
+				int where, int size, u32 val)
+{
+	/*
+	 * Don't go out for local device
+	 */
+	if ((orion_pci_local_bus_nr() == bus->number) &&
+	   (orion_pci_local_dev_nr() == PCI_SLOT(devfn)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return orion_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn),
+					PCI_FUNC(devfn), where, size, val);
+}
+
+struct pci_ops orion_pci_ops = {
+	.read = orion_pci_rd_conf,
+	.write = orion_pci_wr_conf,
+};
+
+static void orion_pci_set_bus_nr(int nr)
+{
+	u32 p2p = orion_read(PCI_P2P_CONF);
+
+	if (orion_read(PCI_MODE) & PCI_MODE_PCIX) {
+		/*
+		 * PCI-X mode
+		 */
+		u32 pcix_status, bus, dev;
+		bus = (p2p & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS;
+		dev = (p2p & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS;
+		orion_pci_hw_rd_conf(bus, dev, 0, PCIX_STAT, 4, &pcix_status);
+		pcix_status &= ~PCIX_STAT_BUS_MASK;
+		pcix_status |= (nr << PCIX_STAT_BUS_OFFS);
+		orion_pci_hw_wr_conf(bus, dev, 0, PCIX_STAT, 4, pcix_status);
+	} else {
+		/*
+		 * PCI Conventional mode
+		 */
+		p2p &= ~PCI_P2P_BUS_MASK;
+		p2p |= (nr << PCI_P2P_BUS_OFFS);
+		orion_write(PCI_P2P_CONF, p2p);
+	}
+}
+
+static void orion_pci_master_slave_enable(void)
+{
+	u32 bus_nr, dev_nr, func, reg, val;
+
+	bus_nr = orion_pci_local_bus_nr();
+	dev_nr = orion_pci_local_dev_nr();
+	func = PCI_CONF_FUNC_STAT_CMD;
+	reg = PCI_CONF_REG_STAT_CMD;
+	orion_pci_hw_rd_conf(bus_nr, dev_nr, func, reg, 4, &val);
+	val |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+	orion_pci_hw_wr_conf(bus_nr, dev_nr, func, reg, 4, val | 0x7);
+}
+
+static int orion_pci_setup(struct pci_sys_data *sys)
+{
+	struct resource *res;
+
+	/*
+	 * Master + Slave enable
+	 */
+	orion_pci_master_slave_enable();
+
+	/*
+	 * Force ordering
+	 */
+	orion_setbits(PCI_CMD, PCI_CMD_HOST_REORDER);
+
+	/*
+	 * Request resources
+	 */
+	res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+	if (!res)
+		panic("orion_pci_setup unable to alloc resources");
+
+	/*
+	 * IORESOURCE_IO
+	 */
+	res[0].name = "PCI I/O Space";
+	res[0].flags = IORESOURCE_IO;
+	res[0].start = ORION_PCI_IO_REMAP;
+	res[0].end = res[0].start + ORION_PCI_IO_SIZE - 1;
+	if (request_resource(&ioport_resource, &res[0]))
+		panic("Request PCI IO resource failed\n");
+	sys->resource[0] = &res[0];
+
+	/*
+	 * IORESOURCE_MEM
+	 */
+	res[1].name = "PCI Memory Space";
+	res[1].flags = IORESOURCE_MEM;
+	res[1].start = ORION_PCI_MEM_BASE;
+	res[1].end = res[1].start + ORION_PCI_MEM_SIZE - 1;
+	if (request_resource(&iomem_resource, &res[1]))
+		panic("Request PCI Memory resource failed\n");
+	sys->resource[1] = &res[1];
+
+	sys->resource[2] = NULL;
+	sys->io_offset = 0;
+
+	return 1;
+}
+
+
+/*****************************************************************************
+ * General PCIE + PCI
+ ****************************************************************************/
+int orion_pci_sys_setup(int nr, struct pci_sys_data *sys)
+{
+	int ret = 0;
+
+	if (nr == 0) {
+		/*
+		 * PCIE setup
+		 */
+		orion_pcie_set_bus_nr(0);
+		ret = orion_pcie_setup(sys);
+	} else if (nr == 1) {
+		/*
+		 * PCI setup
+		 */
+		ret = orion_pci_setup(sys);
+	}
+
+	return ret;
+}
+
+struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	struct pci_ops *ops;
+	struct pci_bus *bus;
+
+
+	if (nr == 0) {
+		u32 pci_bus;
+		/*
+		 * PCIE scan
+		 */
+		ops = &orion_pcie_ops;
+		bus = pci_scan_bus(sys->busnr, ops, sys);
+		/*
+		 * Set local PCI bus number to follow PCIE bridges (if any)
+		 */
+		pci_bus	= bus->number + bus->subordinate - bus->secondary + 1;
+		orion_pci_set_bus_nr(pci_bus);
+	} else if (nr == 1) {
+		/*
+		 * PCI scan
+		 */
+		ops = &orion_pci_ops;
+		bus = pci_scan_bus(sys->busnr, ops, sys);
+	} else {
+		BUG();
+		bus = NULL;
+	}
+
+	return bus;
+}
diff --git a/arch/arm/mach-orion/rd88f5182-setup.c b/arch/arm/mach-orion/rd88f5182-setup.c
new file mode 100644
index 0000000..026d743
--- /dev/null
+++ b/arch/arm/mach-orion/rd88f5182-setup.c
@@ -0,0 +1,306 @@
+/*
+ * arch/arm/mach-orion/rd88f5182-setup.c
+ *
+ * Marvell Orion-NAS Reference Design Setup
+ *
+ * Maintainer: Ronen Shitrit <rshitrit@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+/*****************************************************************************
+ * RD-88F5182 Info
+ ****************************************************************************/
+
+/*
+ * 512K NOR flash Device bus boot chip select
+ */
+
+#define RD88F5182_NOR_BOOT_BASE		0xf4000000
+#define RD88F5182_NOR_BOOT_SIZE		SZ_512K
+
+/*
+ * 16M NOR flash on Device bus chip select 1
+ */
+
+#define RD88F5182_NOR_BASE		0xfc000000
+#define RD88F5182_NOR_SIZE		SZ_16M
+
+/*
+ * PCI
+ */
+
+#define RD88F5182_PCI_SLOT0_OFFS	7
+#define RD88F5182_PCI_SLOT0_IRQ_A_PIN	7
+#define RD88F5182_PCI_SLOT0_IRQ_B_PIN	6
+
+/*
+ * GPIO Debug LED
+ */
+
+#define RD88F5182_GPIO_DBG_LED		0
+
+/*****************************************************************************
+ * 16M NOR Flash on Device bus CS1
+ ****************************************************************************/
+
+static struct physmap_flash_data rd88f5182_nor_flash_data = {
+	.width		= 1,
+};
+
+static struct resource rd88f5182_nor_flash_resource = {
+	.flags			= IORESOURCE_MEM,
+	.start			= RD88F5182_NOR_BASE,
+	.end			= RD88F5182_NOR_BASE + RD88F5182_NOR_SIZE - 1,
+};
+
+static struct platform_device rd88f5182_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= 0,
+	.dev		= {
+		.platform_data	= &rd88f5182_nor_flash_data,
+	},
+	.num_resources		= 1,
+	.resource		= &rd88f5182_nor_flash_resource,
+};
+
+#ifdef CONFIG_LEDS
+
+/*****************************************************************************
+ * Use GPIO debug led as CPU active indication
+ ****************************************************************************/
+
+static void rd88f5182_dbgled_event(led_event_t evt)
+{
+	int val;
+
+	if (evt == led_idle_end)
+		val = 1;
+	else if (evt == led_idle_start)
+		val = 0;
+	else
+		return;
+
+	gpio_set_value(RD88F5182_GPIO_DBG_LED, val);
+}
+
+static int __init rd88f5182_dbgled_init(void)
+{
+	int pin;
+
+	if (machine_is_rd88f5182()) {
+		pin = RD88F5182_GPIO_DBG_LED;
+
+		if (gpio_request(pin, "DBGLED") == 0) {
+			if (gpio_direction_output(pin, 0) != 0) {
+				printk(KERN_ERR "rd88f5182_dbgled_init failed "
+						"to set output pin %d\n", pin);
+				gpio_free(pin);
+				return 0;
+			}
+		} else {
+			printk(KERN_ERR "rd88f5182_dbgled_init failed "
+					"to request gpio %d\n", pin);
+			return 0;
+		}
+
+		leds_event = rd88f5182_dbgled_event;
+	}
+	return 0;
+}
+
+__initcall(rd88f5182_dbgled_init);
+
+#endif
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+void __init rd88f5182_pci_preinit(void)
+{
+	int pin;
+
+	/*
+	 * Configure PCI GPIO IRQ pins
+	 */
+	pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN;
+	if (gpio_request(pin, "PCI IntA") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "rd88f5182_pci_preinit faield to "
+					"set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "rd88f5182_pci_preinit failed to request gpio %d\n", pin);
+	}
+
+	pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN;
+	if (gpio_request(pin, "PCI IntB") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "rd88f5182_pci_preinit faield to "
+					"set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "rd88f5182_pci_preinit failed to gpio_request %d\n", pin);
+	}
+}
+
+static int __init rd88f5182_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/*
+	 * PCI-E isn't used on the RD2
+	 */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+
+	/*
+	 * PCI IRQs are connected via GPIOs
+	 */
+	switch (slot - RD88F5182_PCI_SLOT0_OFFS) {
+	case 0:
+		if (pin == 1)
+			return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_A_PIN);
+		else
+			return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_B_PIN);
+	default:
+		return -1;
+	}
+}
+
+static struct hw_pci rd88f5182_pci __initdata = {
+	.nr_controllers	= 2,
+	.preinit	= rd88f5182_pci_preinit,
+	.swizzle	= pci_std_swizzle,
+	.setup		= orion_pci_sys_setup,
+	.scan		= orion_pci_sys_scan_bus,
+	.map_irq	= rd88f5182_pci_map_irq,
+};
+
+static int __init rd88f5182_pci_init(void)
+{
+	if (machine_is_rd88f5182())
+		pci_common_init(&rd88f5182_pci);
+
+	return 0;
+}
+
+subsys_initcall(rd88f5182_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data rd88f5182_eth_data = {
+	.phy_addr	= 8,
+	.force_phy_addr = 1,
+};
+
+/*****************************************************************************
+ * RTC DS1338 on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata rd88f5182_i2c_rtc = {
+	.driver_name	= "rtc-ds1307",
+	.type		= "ds1338",
+	.addr		= 0x68,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct platform_device *rd88f5182_devices[] __initdata = {
+	&rd88f5182_nor_flash,
+};
+
+static void __init rd88f5182_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion_init();
+
+	/*
+	 * Setup the CPU address decode windows for our devices
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, RD88F5182_NOR_BOOT_BASE,
+				RD88F5182_NOR_BOOT_SIZE, -1);
+	orion_setup_cpu_win(ORION_DEV1, RD88F5182_NOR_BASE,
+				RD88F5182_NOR_SIZE, -1);
+
+	/*
+	 * Open a special address decode windows for the PCIE WA.
+	 */
+	orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
+	orion_write(ORION_REGS_BASE | 0x20070, (0x7941 |
+		(((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
+
+	/*
+	 * Setup Multiplexing Pins --
+	 * MPP[0] Debug Led (GPIO - Out)
+	 * MPP[1] Debug Led (GPIO - Out)
+	 * MPP[2] N/A
+	 * MPP[3] RTC_Int (GPIO - In)
+	 * MPP[4] GPIO
+	 * MPP[5] GPIO
+	 * MPP[6] PCI_intA (GPIO - In)
+	 * MPP[7] PCI_intB (GPIO - In)
+	 * MPP[8-11] N/A
+	 * MPP[12] SATA 0 presence Indication
+	 * MPP[13] SATA 1 presence Indication
+	 * MPP[14] SATA 0 active Indication
+	 * MPP[15] SATA 1 active indication
+	 * MPP[16-19] Not used
+	 * MPP[20] PCI Clock to MV88F5182
+	 * MPP[21] PCI Clock to mini PCI CON11
+	 * MPP[22] USB 0 over current indication
+	 * MPP[23] USB 1 over current indication
+	 * MPP[24] USB 1 over current enable
+	 * MPP[25] USB 0 over current enable
+	 */
+
+	orion_write(MPP_0_7_CTRL, 0x00000003);
+	orion_write(MPP_8_15_CTRL, 0x55550000);
+	orion_write(MPP_16_19_CTRL, 0x5555);
+
+	orion_gpio_set_valid_pins(0x000000fb);
+
+	platform_add_devices(rd88f5182_devices, ARRAY_SIZE(rd88f5182_devices));
+	i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1);
+	orion_eth_init(&rd88f5182_eth_data);
+}
+
+MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
+	/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= rd88f5182_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion/time.c b/arch/arm/mach-orion/time.c
new file mode 100644
index 0000000..bd4262d
--- /dev/null
+++ b/arch/arm/mach-orion/time.c
@@ -0,0 +1,181 @@
+/*
+ * arch/arm/mach-orion/time.c
+ *
+ * Core time functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/mach/time.h>
+#include <asm/arch/orion.h>
+#include "common.h"
+
+/*
+ * Timer0: clock_event_device, Tick.
+ * Timer1: clocksource, Free running.
+ * WatchDog: Not used.
+ *
+ * Timers are counting down.
+ */
+#define CLOCKEVENT	0
+#define CLOCKSOURCE	1
+
+/*
+ * Timers bits
+ */
+#define BRIDGE_INT_TIMER(x)	(1 << ((x) + 1))
+#define TIMER_EN(x)		(1 << ((x) * 2))
+#define TIMER_RELOAD_EN(x)	(1 << (((x) * 2) + 1))
+#define BRIDGE_INT_TIMER_WD	(1 << 3)
+#define TIMER_WD_EN		(1 << 4)
+#define TIMER_WD_RELOAD_EN	(1 << 5)
+
+static cycle_t orion_clksrc_read(void)
+{
+	return (0xffffffff - orion_read(TIMER_VAL(CLOCKSOURCE)));
+}
+
+static struct clocksource orion_clksrc = {
+	.name		= "orion_clocksource",
+	.shift		= 20,
+	.rating		= 300,
+	.read		= orion_clksrc_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int
+orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev)
+{
+	unsigned long flags;
+
+	if (delta == 0)
+		return -ETIME;
+
+	local_irq_save(flags);
+
+	/*
+	 * Clear and enable timer interrupt bit
+	 */
+	orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT));
+	orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT));
+
+	/*
+	 * Setup new timer value
+	 */
+	orion_write(TIMER_VAL(CLOCKEVENT), delta);
+
+	/*
+	 * Disable auto reload and kickoff the timer
+	 */
+	orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT));
+	orion_setbits(TIMER_CTRL, TIMER_EN(CLOCKEVENT));
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static void
+orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	if (mode == CLOCK_EVT_MODE_PERIODIC) {
+		/*
+		 * Setup latch cycles in timer and enable reload interrupt.
+		 */
+		orion_write(TIMER_VAL_RELOAD(CLOCKEVENT), LATCH);
+		orion_write(TIMER_VAL(CLOCKEVENT), LATCH);
+		orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT));
+		orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) |
+					  TIMER_EN(CLOCKEVENT));
+	} else {
+		/*
+		 * Disable timer and interrupt
+		 */
+		orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT));
+		orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT));
+		orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) |
+					  TIMER_EN(CLOCKEVENT));
+	}
+
+	local_irq_restore(flags);
+}
+
+static struct clock_event_device orion_clkevt = {
+	.name		= "orion_tick",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.rating		= 300,
+	.cpumask	= CPU_MASK_CPU0,
+	.set_next_event	= orion_clkevt_next_event,
+	.set_mode	= orion_clkevt_mode,
+};
+
+static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
+{
+	/*
+	 * Clear cause bit and do event
+	 */
+	orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT));
+	orion_clkevt.event_handler(&orion_clkevt);
+	return IRQ_HANDLED;
+}
+
+static struct irqaction orion_timer_irq = {
+	.name		= "orion_tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER,
+	.handler	= orion_timer_interrupt
+};
+
+static void orion_timer_init(void)
+{
+	/*
+	 * Setup clocksource free running timer (no interrupt on reload)
+	 */
+	orion_write(TIMER_VAL(CLOCKSOURCE), 0xffffffff);
+	orion_write(TIMER_VAL_RELOAD(CLOCKSOURCE), 0xffffffff);
+	orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKSOURCE));
+	orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKSOURCE) |
+				  TIMER_EN(CLOCKSOURCE));
+
+	/*
+	 * Register clocksource
+	 */
+	orion_clksrc.mult =
+		clocksource_hz2mult(CLOCK_TICK_RATE, orion_clksrc.shift);
+
+	clocksource_register(&orion_clksrc);
+
+	/*
+	 * Connect and enable tick handler
+	 */
+	setup_irq(IRQ_ORION_BRIDGE, &orion_timer_irq);
+
+	/*
+	 * Register clockevent
+	 */
+	orion_clkevt.mult =
+		div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, orion_clkevt.shift);
+	orion_clkevt.max_delta_ns =
+		clockevent_delta2ns(0xfffffffe, &orion_clkevt);
+	orion_clkevt.min_delta_ns =
+		clockevent_delta2ns(1, &orion_clkevt);
+
+	clockevents_register_device(&orion_clkevt);
+}
+
+struct sys_timer orion_timer = {
+	.init = orion_timer_init,
+};
diff --git a/arch/arm/mach-orion/ts209-setup.c b/arch/arm/mach-orion/ts209-setup.c
new file mode 100644
index 0000000..e3e930e
--- /dev/null
+++ b/arch/arm/mach-orion/ts209-setup.c
@@ -0,0 +1,335 @@
+/*
+ * QNAP TS-109/TS-209 Board Setup
+ *
+ * Maintainer: Byron Bradley <byron.bbradley@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/serial_reg.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <asm/arch/orion.h>
+#include <asm/arch/platform.h>
+#include "common.h"
+
+#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
+#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M
+
+/****************************************************************************
+ * 8MiB NOR flash. The struct mtd_partition is not in the same order as the
+ *     partitions on the device because we want to keep compatability with
+ *     existing QNAP firmware.
+ *
+ * Layout as used by QNAP:
+ *  [2] 0x00000000-0x00200000 : "Kernel"
+ *  [3] 0x00200000-0x00600000 : "RootFS1"
+ *  [4] 0x00600000-0x00700000 : "RootFS2"
+ *  [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
+ *  [5] 0x00760000-0x00780000 : "U-Boot Config"
+ *  [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
+ ***************************************************************************/
+static struct mtd_partition qnap_ts209_partitions[] = {
+	{
+		.name       = "U-Boot",
+		.size       = 0x00080000,
+		.offset     = 0x00780000,
+		.mask_flags = MTD_WRITEABLE,
+	}, {
+		.name   = "Kernel",
+		.size   = 0x00200000,
+		.offset = 0,
+	}, {
+		.name   = "RootFS1",
+		.size   = 0x00400000,
+		.offset = 0x00200000,
+	}, {
+		.name   = "RootFS2",
+		.size   = 0x00100000,
+		.offset = 0x00600000,
+	}, {
+		.name   = "U-Boot Config",
+		.size   = 0x00020000,
+		.offset = 0x00760000,
+	}, {
+		.name       = "NAS Config",
+		.size       = 0x00060000,
+		.offset     = 0x00700000,
+		.mask_flags = MTD_WRITEABLE,
+	}
+};
+
+static struct physmap_flash_data qnap_ts209_nor_flash_data = {
+	.width    = 1,
+	.parts    = qnap_ts209_partitions,
+	.nr_parts = ARRAY_SIZE(qnap_ts209_partitions)
+};
+
+static struct resource qnap_ts209_nor_flash_resource = {
+	.flags = IORESOURCE_MEM,
+	.start = QNAP_TS209_NOR_BOOT_BASE,
+	.end   = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device qnap_ts209_nor_flash = {
+	.name          = "physmap-flash",
+	.id            = 0,
+	.dev           = { .platform_data = &qnap_ts209_nor_flash_data, },
+	.resource      = &qnap_ts209_nor_flash_resource,
+	.num_resources = 1,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+#define QNAP_TS209_PCI_SLOT0_OFFS	7
+#define QNAP_TS209_PCI_SLOT0_IRQ_PIN	6
+#define QNAP_TS209_PCI_SLOT1_IRQ_PIN	7
+
+void __init qnap_ts209_pci_preinit(void)
+{
+	int pin;
+
+	/*
+	 * Configure PCI GPIO IRQ pins
+	 */
+	pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN;
+	if (gpio_request(pin, "PCI Int1") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "qnap_ts209_pci_preinit failed to "
+					"set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
+				"%d\n", pin);
+	}
+
+	pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN;
+	if (gpio_request(pin, "PCI Int2") == 0) {
+		if (gpio_direction_input(pin) == 0) {
+			set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+		} else {
+			printk(KERN_ERR "qnap_ts209_pci_preinit failed "
+					"to set_irq_type pin %d\n", pin);
+			gpio_free(pin);
+		}
+	} else {
+		printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
+				"%d\n", pin);
+	}
+}
+
+static int __init qnap_ts209_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/*
+	 * PCIE IRQ is connected internally (not GPIO)
+	 */
+	if (dev->bus->number == orion_pcie_local_bus_nr())
+		return IRQ_ORION_PCIE0_INT;
+
+	/*
+	 * PCI IRQs are connected via GPIOs
+	 */
+	switch (slot - QNAP_TS209_PCI_SLOT0_OFFS) {
+	case 0:
+		return gpio_to_irq(QNAP_TS209_PCI_SLOT0_IRQ_PIN);
+	case 1:
+		return gpio_to_irq(QNAP_TS209_PCI_SLOT1_IRQ_PIN);
+	default:
+		return -1;
+	}
+}
+
+static struct hw_pci qnap_ts209_pci __initdata = {
+	.nr_controllers = 2,
+	.preinit        = qnap_ts209_pci_preinit,
+	.swizzle        = pci_std_swizzle,
+	.setup          = orion_pci_sys_setup,
+	.scan           = orion_pci_sys_scan_bus,
+	.map_irq        = qnap_ts209_pci_map_irq,
+};
+
+static int __init qnap_ts209_pci_init(void)
+{
+	if (machine_is_ts_x09())
+		pci_common_init(&qnap_ts209_pci);
+
+	return 0;
+}
+
+subsys_initcall(qnap_ts209_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data qnap_ts209_eth_data = {
+	.phy_addr       = 8,
+	.force_phy_addr = 1,
+};
+
+/*****************************************************************************
+ * RTC S35390A on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
+       .driver_name = "rtc-s35390a",
+       .addr        = 0x30,
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ *     Power button is attached to the PIC microcontroller
+ ****************************************************************************/
+
+#define QNAP_TS209_GPIO_KEY_MEDIA	1
+#define QNAP_TS209_GPIO_KEY_RESET	2
+
+static struct gpio_keys_button qnap_ts209_buttons[] = {
+	{
+		.code		= KEY_RESTART,
+		.gpio		= QNAP_TS209_GPIO_KEY_MEDIA,
+		.desc		= "USB Copy Button",
+		.active_low	= 1,
+	},
+	{
+		.code		= KEY_POWER,
+		.gpio		= QNAP_TS209_GPIO_KEY_RESET,
+		.desc		= "Reset Button",
+		.active_low	= 1,
+	}
+};
+
+static struct gpio_keys_platform_data qnap_ts209_button_data = {
+	.buttons	= qnap_ts209_buttons,
+	.nbuttons       = ARRAY_SIZE(qnap_ts209_buttons),
+};
+
+static struct platform_device qnap_ts209_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= { .platform_data  = &qnap_ts209_button_data, },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct platform_device *qnap_ts209_devices[] __initdata = {
+	&qnap_ts209_nor_flash,
+	&qnap_ts209_button_device,
+};
+
+/*
+ * QNAP TS-[12]09 specific power off method via UART1-attached PIC
+ */
+
+#define UART1_REG(x)  (UART1_BASE + ((UART_##x) << 2))
+
+static void qnap_ts209_power_off(void)
+{
+	/* 19200 baud divisor */
+	const unsigned divisor = ((ORION_TCLK + (8 * 19200)) / (16 * 19200));
+
+	pr_info("%s: triggering power-off...\n", __func__);
+
+	/* hijack uart1 and reset into sane state (19200,8n1) */
+	orion_write(UART1_REG(LCR), 0x83);
+	orion_write(UART1_REG(DLL), divisor & 0xff);
+	orion_write(UART1_REG(DLM), (divisor >> 8) & 0xff);
+	orion_write(UART1_REG(LCR), 0x03);
+	orion_write(UART1_REG(IER), 0x00);
+	orion_write(UART1_REG(FCR), 0x00);
+	orion_write(UART1_REG(MCR), 0x00);
+
+	/* send the power-off command 'A' to PIC */
+	orion_write(UART1_REG(TX), 'A');
+}
+
+static void __init qnap_ts209_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion_init();
+
+	/*
+	 * Setup flash mapping
+	 */
+	orion_setup_cpu_win(ORION_DEV_BOOT, QNAP_TS209_NOR_BOOT_BASE,
+			    QNAP_TS209_NOR_BOOT_SIZE, -1);
+
+	/*
+	 * Open a special address decode windows for the PCIE WA.
+	 */
+	orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE);
+	orion_write(ORION_REGS_BASE | 0x20070, (0x7941 |
+		(((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16));
+
+	/*
+	 * Setup Multiplexing Pins --
+	 * MPP[0] Reserved
+	 * MPP[1] USB copy button (0 active)
+	 * MPP[2] Load defaults button (0 active)
+	 * MPP[3] GPIO RTC
+	 * MPP[4-5] Reserved
+	 * MPP[6] PCI Int A
+	 * MPP[7] PCI Int B
+	 * MPP[8-11] Reserved
+	 * MPP[12] SATA 0 presence
+	 * MPP[13] SATA 1 presence
+	 * MPP[14] SATA 0 active
+	 * MPP[15] SATA 1 active
+	 * MPP[16] UART1 RXD
+	 * MPP[17] UART1 TXD
+	 * MPP[18] SW_RST (0 active)
+	 * MPP[19] Reserved
+	 * MPP[20] PCI clock 0
+	 * MPP[21] PCI clock 1
+	 * MPP[22] USB 0 over current
+	 * MPP[23-25] Reserved
+	 */
+	orion_write(MPP_0_7_CTRL, 0x3);
+	orion_write(MPP_8_15_CTRL, 0x55550000);
+	orion_write(MPP_16_19_CTRL, 0x5500);
+	orion_gpio_set_valid_pins(0x3cc0fff);
+
+	/* register ts209 specific power-off method */
+	pm_power_off = qnap_ts209_power_off;
+
+	platform_add_devices(qnap_ts209_devices,
+				ARRAY_SIZE(qnap_ts209_devices));
+	i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
+	orion_eth_init(&qnap_ts209_eth_data);
+}
+
+MACHINE_START(TS209, "QNAP TS-109/TS-209")
+	/* Maintainer:  Byron Bradley <byron.bbradley@gmail.com> */
+	.phys_io	= ORION_REGS_BASE,
+	.io_pg_offst	= ((ORION_REGS_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= qnap_ts209_init,
+	.map_io		= orion_map_io,
+	.init_irq	= orion_init_irq,
+	.timer		= &orion_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c
index 67e05f0..6d4ca8f 100644
--- a/arch/arm/mach-pnx4008/time.c
+++ b/arch/arm/mach-pnx4008/time.c
@@ -51,8 +51,6 @@
 {
 	if (__raw_readl(HSTIM_INT) & MATCH0_INT) {
 
-		write_seqlock(&xtime_lock);
-
 		do {
 			timer_tick();
 
@@ -73,8 +71,6 @@
 		} while ((signed)
 			 (__raw_readl(HSTIM_MATCH0) -
 			  __raw_readl(HSTIM_COUNTER)) < 0);
-
-		write_sequnlock(&xtime_lock);
 	}
 
 	return IRQ_HANDLED;
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 656d496..0908bea 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -51,6 +51,50 @@
 	  SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
 	  handheld computer.
 
+config ARCH_PXA_ESERIES
+	bool "PXA based Toshiba e-series PDAs"
+	select PXA25x
+
+config MACH_E330
+	bool "Toshiba e330"
+	default y
+	depends on ARCH_PXA_ESERIES
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e330 family PDA.
+
+config MACH_E740
+	bool "Toshiba e740"
+	default y
+	depends on ARCH_PXA_ESERIES
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e740 family PDA.
+
+config MACH_E750
+	bool "Toshiba e750"
+	default y
+	depends on ARCH_PXA_ESERIES
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e750 family PDA.
+
+config MACH_E400
+	bool "Toshiba e400"
+	default y
+	depends on ARCH_PXA_ESERIES
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e400 family PDA.
+
+config MACH_E800
+	bool "Toshiba e800"
+	default y
+	depends on ARCH_PXA_ESERIES
+	help
+	  Say Y here if you intend to run this kernel on a Toshiba
+	  e800 family PDA.
+
 config MACH_TRIZEPS4
 	bool "Keith und Koep Trizeps4 DIMM-Module"
 	select PXA27x
@@ -59,15 +103,44 @@
 	bool "CompuLab EM-x270 platform"
 	select PXA27x
 
+config MACH_COLIBRI
+	bool "Toradex Colibri PX27x"
+	select PXA27x
+
 config MACH_ZYLONITE
 	bool "PXA3xx Development Platform"
 	select PXA3xx
 
+config MACH_LITTLETON
+	bool "PXA3xx Form Factor Platform (aka Littleton)"
+	select PXA3xx
+	select PXA_SSP
+
 config MACH_ARMCORE
 	bool "CompuLab CM-X270 modules"
 	select PXA27x
 	select IWMMXT
 
+config MACH_MAGICIAN
+	bool "Enable HTC Magician Support"
+	depends on ARCH_PXA
+	select PXA27x
+	select IWMMXT
+
+config MACH_PCM027
+	bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
+	select PXA27x
+	select IWMMXT
+
+endchoice
+
+choice
+	prompt "Used baseboard"
+	depends on MACH_PCM027
+
+config MACH_PCM990_BASEBOARD
+	bool "PHYTEC PCM-990 development board"
+
 endchoice
 
 if PXA_SHARPSL
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 4263527..b5c916c 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common support (must be linked before board specific support)
-obj-y				+= clock.o generic.o irq.o dma.o time.o
+obj-y				+= clock.o devices.o generic.o irq.o dma.o time.o
 obj-$(CONFIG_PXA25x)		+= pxa25x.o
 obj-$(CONFIG_PXA27x)		+= pxa27x.o
 obj-$(CONFIG_PXA3xx)		+= pxa3xx.o mfp.o
@@ -16,18 +16,24 @@
 obj-$(CONFIG_MACH_MAINSTONE)	+= mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP)	+= idp.o
 obj-$(CONFIG_MACH_TRIZEPS4)	+= trizeps4.o
+obj-$(CONFIG_MACH_COLIBRI)	+= colibri.o
 obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
 obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
 obj-$(CONFIG_MACH_AKITA)	+= akita-ioexp.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o corgi_ssp.o
+obj-$(CONFIG_MACH_PCM027)	+= pcm027.o
+obj-$(CONFIG_MACH_PCM990_BASEBOARD)	+= pcm990-baseboard.o
 obj-$(CONFIG_MACH_TOSA)		+= tosa.o
 obj-$(CONFIG_MACH_EM_X270)	+= em-x270.o
+obj-$(CONFIG_MACH_MAGICIAN)	+= magician.o
+obj-$(CONFIG_ARCH_PXA_ESERIES)	+= eseries.o
 
 ifeq ($(CONFIG_MACH_ZYLONITE),y)
   obj-y				+= zylonite.o
   obj-$(CONFIG_CPU_PXA300)	+= zylonite_pxa300.o
   obj-$(CONFIG_CPU_PXA320)	+= zylonite_pxa320.o
 endif
+obj-$(CONFIG_MACH_LITTLETON)	+= littleton.o
 
 obj-$(CONFIG_MACH_ARMCORE)      += cm-x270.o
 
@@ -41,13 +47,10 @@
 obj-$(CONFIG_LEDS)		+= $(led-y)
 
 # Misc features
-obj-$(CONFIG_PM)		+= pm.o sleep.o
+obj-$(CONFIG_PM)		+= pm.o sleep.o standby.o
+obj-$(CONFIG_CPU_FREQ)		+= cpu-pxa.o
 obj-$(CONFIG_PXA_SSP)		+= ssp.o
 
-ifeq ($(CONFIG_PXA27x),y)
-obj-$(CONFIG_PM)		+= standby.o
-endif
-
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
 endif
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index a163492..28cfd71 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -487,18 +487,15 @@
 
 	/* card detect IRQ on GPIO 83 */
 	pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ));
-	set_irq_type(CMX270_MMC_IRQ, IRQT_FALLING);
 
 	err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int,
 			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
 			  "MMC card detect", data);
-	if (err) {
+	if (err)
 		printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't"
 		       " request MMC card detect IRQ\n");
-		return -1;
-	}
 
-	return 0;
+	return err;
 }
 
 static void cmx270_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/colibri.c b/arch/arm/mach-pxa/colibri.c
new file mode 100644
index 0000000..6db54e3
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri.c
@@ -0,0 +1,134 @@
+/*
+ *  linux/arch/arm/mach-pxa/colibri.c
+ *
+ *  Support for Toradex PXA27x based Colibri module
+ *  Daniel Mack <daniel@caiaq.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/colibri.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/*
+ * Flash
+ */
+static struct mtd_partition colibri_partitions[] = {
+	{
+		.name =		"Bootloader",
+		.offset =	0x00000000,
+		.size =		0x00040000,
+		.mask_flags =	MTD_WRITEABLE  /* force read-only */
+	}, {
+		.name =		"Kernel",
+		.offset =	0x00040000,
+		.size =		0x00400000,
+		.mask_flags =	0
+	}, {
+		.name =		"Rootfs",
+		.offset =	0x00440000,
+		.size =		MTDPART_SIZ_FULL,
+		.mask_flags =	0
+	}
+};
+
+static struct physmap_flash_data colibri_flash_data[] = {
+	{
+		.width		= 4,			/* bankwidth in bytes */
+		.parts		= colibri_partitions,
+		.nr_parts	= ARRAY_SIZE(colibri_partitions)
+	}
+};
+
+static struct resource flash_resource = {
+	.start	= PXA_CS0_PHYS,
+	.end	= PXA_CS0_PHYS + SZ_32M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev 	= {
+		.platform_data = colibri_flash_data,
+	},
+	.resource = &flash_resource,
+	.num_resources = 1,
+};
+
+/*
+ * DM9000 Ethernet
+ */
+static struct resource dm9000_resources[] = {
+	[0] = {
+		.start	= COLIBRI_ETH_PHYS,
+		.end	= COLIBRI_ETH_PHYS + 3,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= COLIBRI_ETH_PHYS + 4,
+		.end	= COLIBRI_ETH_PHYS + 4 + 500,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= COLIBRI_ETH_IRQ,
+		.end	= COLIBRI_ETH_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dm9000_device = {
+	.name		= "dm9000",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(dm9000_resources),
+	.resource	= dm9000_resources,
+};
+
+static struct platform_device *colibri_devices[] __initdata = {
+	&flash_device,
+	&dm9000_device,
+};
+
+static void __init colibri_init(void)
+{
+	/* DM9000 LAN */
+	pxa_gpio_mode(GPIO78_nCS_2_MD);
+	pxa_gpio_mode(GPIO_DM9000 | GPIO_IN);
+	set_irq_type(COLIBRI_ETH_IRQ, IRQT_FALLING);
+
+	platform_add_devices(colibri_devices, ARRAY_SIZE(colibri_devices));
+}
+
+MACHINE_START(COLIBRI, "Toradex Colibri PXA27x")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= COLIBRI_SDRAM_BASE + 0x100,
+	.init_machine	= colibri_init,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 2363cc6..9292576 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -21,6 +21,7 @@
 #include <linux/mmc/host.h>
 #include <linux/pm.h>
 #include <linux/backlight.h>
+#include <video/w100fb.h>
 
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -141,6 +142,136 @@
 
 
 /*
+ * LCD/Framebuffer
+ */
+static void w100_lcdtg_suspend(struct w100fb_par *par)
+{
+	corgi_lcdtg_suspend();
+}
+
+static void w100_lcdtg_init(struct w100fb_par *par)
+{
+	corgi_lcdtg_hw_init(par->xres);
+}
+
+
+static struct w100_tg_info corgi_lcdtg_info = {
+	.change  = w100_lcdtg_init,
+	.suspend = w100_lcdtg_suspend,
+	.resume  = w100_lcdtg_init,
+};
+
+static struct w100_mem_info corgi_fb_mem = {
+	.ext_cntl          = 0x00040003,
+	.sdram_mode_reg    = 0x00650021,
+	.ext_timing_cntl   = 0x10002a4a,
+	.io_cntl           = 0x7ff87012,
+	.size              = 0x1fffff,
+};
+
+static struct w100_gen_regs corgi_fb_regs = {
+	.lcd_format    = 0x00000003,
+	.lcdd_cntl1    = 0x01CC0000,
+	.lcdd_cntl2    = 0x0003FFFF,
+	.genlcd_cntl1  = 0x00FFFF0D,
+	.genlcd_cntl2  = 0x003F3003,
+	.genlcd_cntl3  = 0x000102aa,
+};
+
+static struct w100_gpio_regs corgi_fb_gpio = {
+	.init_data1   = 0x000000bf,
+	.init_data2   = 0x00000000,
+	.gpio_dir1    = 0x00000000,
+	.gpio_oe1     = 0x03c0feff,
+	.gpio_dir2    = 0x00000000,
+	.gpio_oe2     = 0x00000000,
+};
+
+static struct w100_mode corgi_fb_modes[] = {
+{
+	.xres            = 480,
+	.yres            = 640,
+	.left_margin     = 0x56,
+	.right_margin    = 0x55,
+	.upper_margin    = 0x03,
+	.lower_margin    = 0x00,
+	.crtc_ss         = 0x82360056,
+	.crtc_ls         = 0xA0280000,
+	.crtc_gs         = 0x80280028,
+	.crtc_vpos_gs    = 0x02830002,
+	.crtc_rev        = 0x00400008,
+	.crtc_dclk       = 0xA0000000,
+	.crtc_gclk       = 0x8015010F,
+	.crtc_goe        = 0x80100110,
+	.crtc_ps1_active = 0x41060010,
+	.pll_freq        = 75,
+	.fast_pll_freq   = 100,
+	.sysclk_src      = CLK_SRC_PLL,
+	.sysclk_divider  = 0,
+	.pixclk_src      = CLK_SRC_PLL,
+	.pixclk_divider  = 2,
+	.pixclk_divider_rotated = 6,
+},{
+	.xres            = 240,
+	.yres            = 320,
+	.left_margin     = 0x27,
+	.right_margin    = 0x2e,
+	.upper_margin    = 0x01,
+	.lower_margin    = 0x00,
+	.crtc_ss         = 0x81170027,
+	.crtc_ls         = 0xA0140000,
+	.crtc_gs         = 0xC0140014,
+	.crtc_vpos_gs    = 0x00010141,
+	.crtc_rev        = 0x00400008,
+	.crtc_dclk       = 0xA0000000,
+	.crtc_gclk       = 0x8015010F,
+	.crtc_goe        = 0x80100110,
+	.crtc_ps1_active = 0x41060010,
+	.pll_freq        = 0,
+	.fast_pll_freq   = 0,
+	.sysclk_src      = CLK_SRC_XTAL,
+	.sysclk_divider  = 0,
+	.pixclk_src      = CLK_SRC_XTAL,
+	.pixclk_divider  = 1,
+	.pixclk_divider_rotated = 1,
+},
+
+};
+
+static struct w100fb_mach_info corgi_fb_info = {
+	.tg         = &corgi_lcdtg_info,
+	.init_mode  = INIT_MODE_ROTATED,
+	.mem        = &corgi_fb_mem,
+	.regs       = &corgi_fb_regs,
+	.modelist   = &corgi_fb_modes[0],
+	.num_modes  = 2,
+	.gpio       = &corgi_fb_gpio,
+	.xtal_freq  = 12500000,
+	.xtal_dbl   = 0,
+};
+
+static struct resource corgi_fb_resources[] = {
+	[0] = {
+		.start   = 0x08000000,
+		.end     = 0x08ffffff,
+		.flags   = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device corgifb_device = {
+	.name           = "w100fb",
+	.id             = -1,
+	.num_resources	= ARRAY_SIZE(corgi_fb_resources),
+	.resource	= corgi_fb_resources,
+	.dev            = {
+		.platform_data = &corgi_fb_info,
+		.parent = &corgissp_device.dev,
+	},
+
+};
+
+
+/*
  * Corgi Backlight Device
  */
 static void corgi_bl_kick_battery(void)
@@ -154,6 +285,21 @@
 	}
 }
 
+static void corgi_bl_set_intensity(int intensity)
+{
+	if (intensity > 0x10)
+		intensity += 0x10;
+
+	/* Bits 0-4 are accessed via the SSP interface */
+	corgi_ssp_blduty_set(intensity & 0x1f);
+
+	/* Bit 5 is via SCOOP */
+	if (intensity & 0x0020)
+		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
+	else
+		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
+}
+
 static struct generic_bl_info corgi_bl_machinfo = {
 	.name = "corgi-bl",
 	.max_intensity = 0x2f,
@@ -190,9 +336,40 @@
 	.id		= -1,
 };
 
+
 /*
  * Corgi Touch Screen Device
  */
+static unsigned long (*get_hsync_invperiod)(struct device *dev);
+
+static void inline sharpsl_wait_sync(int gpio)
+{
+	while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
+	while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
+}
+
+static unsigned long corgi_get_hsync_invperiod(void)
+{
+	if (!get_hsync_invperiod)
+		get_hsync_invperiod = symbol_get(w100fb_get_hsynclen);
+	if (!get_hsync_invperiod)
+		return 0;
+
+	return get_hsync_invperiod(&corgifb_device.dev);
+}
+
+static void corgi_put_hsync(void)
+{
+	if (get_hsync_invperiod)
+		symbol_put(w100fb_get_hsynclen);
+	get_hsync_invperiod = NULL;
+}
+
+static void corgi_wait_hsync(void)
+{
+	sharpsl_wait_sync(CORGI_GPIO_HSYNC);
+}
+
 static struct resource corgits_resources[] = {
 	[0] = {
 		.start		= CORGI_IRQ_GPIO_TP_INT,
@@ -202,9 +379,9 @@
 };
 
 static struct corgits_machinfo  corgi_ts_machinfo = {
-	.get_hsync_len   = corgi_get_hsync_len,
-	.put_hsync       = corgi_put_hsync,
-	.wait_hsync      = corgi_wait_hsync,
+	.get_hsync_invperiod = corgi_get_hsync_invperiod,
+	.put_hsync           = corgi_put_hsync,
+	.wait_hsync          = corgi_wait_hsync,
 };
 
 static struct platform_device corgits_device = {
@@ -242,12 +419,10 @@
 	err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int,
 			  IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 			  "MMC card detect", data);
-	if (err) {
+	if (err)
 		printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
-		return -1;
-	}
 
-	return 0;
+	return err;
 }
 
 static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 365b943..9328df3 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -173,7 +173,7 @@
 
 static int lcd_inited;
 
-static void lcdtg_hw_init(int mode)
+void corgi_lcdtg_hw_init(int mode)
 {
 	if (!lcd_inited) {
 		int comadj;
@@ -254,7 +254,7 @@
 	}
 }
 
-static void lcdtg_suspend(void)
+void corgi_lcdtg_suspend(void)
 {
 	/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
 	mdelay(34);
@@ -288,298 +288,3 @@
 	lcd_inited = 0;
 }
 
-
-/*
- * Corgi w100 Frame Buffer Device
- */
-#ifdef CONFIG_PXA_SHARP_C7xx
-
-#include <video/w100fb.h>
-
-static void w100_lcdtg_suspend(struct w100fb_par *par)
-{
-	lcdtg_suspend();
-}
-
-static void w100_lcdtg_init(struct w100fb_par *par)
-{
-	lcdtg_hw_init(par->xres);
-}
-
-
-static struct w100_tg_info corgi_lcdtg_info = {
-	.change  = w100_lcdtg_init,
-	.suspend = w100_lcdtg_suspend,
-	.resume  = w100_lcdtg_init,
-};
-
-static struct w100_mem_info corgi_fb_mem = {
-	.ext_cntl          = 0x00040003,
-	.sdram_mode_reg    = 0x00650021,
-	.ext_timing_cntl   = 0x10002a4a,
-	.io_cntl           = 0x7ff87012,
-	.size              = 0x1fffff,
-};
-
-static struct w100_gen_regs corgi_fb_regs = {
-	.lcd_format    = 0x00000003,
-	.lcdd_cntl1    = 0x01CC0000,
-	.lcdd_cntl2    = 0x0003FFFF,
-	.genlcd_cntl1  = 0x00FFFF0D,
-	.genlcd_cntl2  = 0x003F3003,
-	.genlcd_cntl3  = 0x000102aa,
-};
-
-static struct w100_gpio_regs corgi_fb_gpio = {
-	.init_data1   = 0x000000bf,
-	.init_data2   = 0x00000000,
-	.gpio_dir1    = 0x00000000,
-	.gpio_oe1     = 0x03c0feff,
-	.gpio_dir2    = 0x00000000,
-	.gpio_oe2     = 0x00000000,
-};
-
-static struct w100_mode corgi_fb_modes[] = {
-{
-	.xres            = 480,
-	.yres            = 640,
-	.left_margin     = 0x56,
-	.right_margin    = 0x55,
-	.upper_margin    = 0x03,
-	.lower_margin    = 0x00,
-	.crtc_ss         = 0x82360056,
-	.crtc_ls         = 0xA0280000,
-	.crtc_gs         = 0x80280028,
-	.crtc_vpos_gs    = 0x02830002,
-	.crtc_rev        = 0x00400008,
-	.crtc_dclk       = 0xA0000000,
-	.crtc_gclk       = 0x8015010F,
-	.crtc_goe        = 0x80100110,
-	.crtc_ps1_active = 0x41060010,
-	.pll_freq        = 75,
-	.fast_pll_freq   = 100,
-	.sysclk_src      = CLK_SRC_PLL,
-	.sysclk_divider  = 0,
-	.pixclk_src      = CLK_SRC_PLL,
-	.pixclk_divider  = 2,
-	.pixclk_divider_rotated = 6,
-},{
-	.xres            = 240,
-	.yres            = 320,
-	.left_margin     = 0x27,
-	.right_margin    = 0x2e,
-	.upper_margin    = 0x01,
-	.lower_margin    = 0x00,
-	.crtc_ss         = 0x81170027,
-	.crtc_ls         = 0xA0140000,
-	.crtc_gs         = 0xC0140014,
-	.crtc_vpos_gs    = 0x00010141,
-	.crtc_rev        = 0x00400008,
-	.crtc_dclk       = 0xA0000000,
-	.crtc_gclk       = 0x8015010F,
-	.crtc_goe        = 0x80100110,
-	.crtc_ps1_active = 0x41060010,
-	.pll_freq        = 0,
-	.fast_pll_freq   = 0,
-	.sysclk_src      = CLK_SRC_XTAL,
-	.sysclk_divider  = 0,
-	.pixclk_src      = CLK_SRC_XTAL,
-	.pixclk_divider  = 1,
-	.pixclk_divider_rotated = 1,
-},
-
-};
-
-static struct w100fb_mach_info corgi_fb_info = {
-	.tg         = &corgi_lcdtg_info,
-	.init_mode  = INIT_MODE_ROTATED,
-	.mem        = &corgi_fb_mem,
-	.regs       = &corgi_fb_regs,
-	.modelist   = &corgi_fb_modes[0],
-	.num_modes  = 2,
-	.gpio       = &corgi_fb_gpio,
-	.xtal_freq  = 12500000,
-	.xtal_dbl   = 0,
-};
-
-static struct resource corgi_fb_resources[] = {
-	[0] = {
-		.start   = 0x08000000,
-		.end     = 0x08ffffff,
-		.flags   = IORESOURCE_MEM,
-	},
-};
-
-struct platform_device corgifb_device = {
-	.name           = "w100fb",
-	.id             = -1,
-	.num_resources	= ARRAY_SIZE(corgi_fb_resources),
-	.resource	= corgi_fb_resources,
-	.dev            = {
- 		.platform_data = &corgi_fb_info,
- 		.parent = &corgissp_device.dev,
-	},
-
-};
-#endif
-
-
-/*
- * Spitz PXA Frame Buffer Device
- */
-#ifdef CONFIG_PXA_SHARP_Cxx00
-
-#include <asm/arch/pxafb.h>
-
-void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
-{
-	if (on)
-		lcdtg_hw_init(var->xres);
-	else
-		lcdtg_suspend();
-}
-
-#endif
-
-
-/*
- * Corgi/Spitz Touchscreen to LCD interface
- */
-static unsigned long (*get_hsync_time)(struct device *dev);
-
-static void inline sharpsl_wait_sync(int gpio)
-{
-	while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
-	while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
-}
-
-#ifdef CONFIG_PXA_SHARP_C7xx
-unsigned long corgi_get_hsync_len(void)
-{
-	if (!get_hsync_time)
-		get_hsync_time = symbol_get(w100fb_get_hsynclen);
-	if (!get_hsync_time)
-		return 0;
-
-	return get_hsync_time(&corgifb_device.dev);
-}
-
-void corgi_put_hsync(void)
-{
-	if (get_hsync_time)
-		symbol_put(w100fb_get_hsynclen);
-	get_hsync_time = NULL;
-}
-
-void corgi_wait_hsync(void)
-{
-	sharpsl_wait_sync(CORGI_GPIO_HSYNC);
-}
-#endif
-
-#ifdef CONFIG_PXA_SHARP_Cxx00
-static struct device *spitz_pxafb_dev;
-
-static int is_pxafb_device(struct device * dev, void * data)
-{
-	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
-
-	return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0);
-}
-
-unsigned long spitz_get_hsync_len(void)
-{
-#ifdef CONFIG_FB_PXA
-	if (!spitz_pxafb_dev) {
-		spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device);
-		if (!spitz_pxafb_dev)
-			return 0;
-	}
-	if (!get_hsync_time)
-		get_hsync_time = symbol_get(pxafb_get_hsync_time);
-	if (!get_hsync_time)
-#endif
-		return 0;
-
-	return pxafb_get_hsync_time(spitz_pxafb_dev);
-}
-
-void spitz_put_hsync(void)
-{
-	put_device(spitz_pxafb_dev);
-	if (get_hsync_time)
-		symbol_put(pxafb_get_hsync_time);
-	spitz_pxafb_dev = NULL;
-	get_hsync_time = NULL;
-}
-
-void spitz_wait_hsync(void)
-{
-	sharpsl_wait_sync(SPITZ_GPIO_HSYNC);
-}
-#endif
-
-/*
- * Corgi/Spitz Backlight Power
- */
-#ifdef CONFIG_PXA_SHARP_C7xx
-void corgi_bl_set_intensity(int intensity)
-{
-	if (intensity > 0x10)
-		intensity += 0x10;
-
-	/* Bits 0-4 are accessed via the SSP interface */
-	corgi_ssp_blduty_set(intensity & 0x1f);
-
-	/* Bit 5 is via SCOOP */
-	if (intensity & 0x0020)
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
-	else
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
-}
-#endif
-
-
-#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
-void spitz_bl_set_intensity(int intensity)
-{
-	if (intensity > 0x10)
-		intensity += 0x10;
-
-	/* Bits 0-4 are accessed via the SSP interface */
-	corgi_ssp_blduty_set(intensity & 0x1f);
-
-	/* Bit 5 is via SCOOP */
-	if (intensity & 0x0020)
-		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
-	else
-		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
-
-	if (intensity)
-		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
-	else
-		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
-}
-#endif
-
-#ifdef CONFIG_MACH_AKITA
-void akita_bl_set_intensity(int intensity)
-{
-	if (intensity > 0x10)
-		intensity += 0x10;
-
-	/* Bits 0-4 are accessed via the SSP interface */
-	corgi_ssp_blduty_set(intensity & 0x1f);
-
-	/* Bit 5 is via IO-Expander */
-	if (intensity & 0x0020)
-		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
-	else
-		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
-
-	if (intensity)
-		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
-	else
-		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
-}
-#endif
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 40dea3d5..efba65e 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -21,6 +21,7 @@
 
 #include <asm/arch/ssp.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/regs-ssp.h>
 #include "sharpsl.h"
 
 static DEFINE_SPINLOCK(corgi_ssp_lock);
diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c
new file mode 100644
index 0000000..cbc583b
--- /dev/null
+++ b/arch/arm/mach-pxa/cpu-pxa.c
@@ -0,0 +1,294 @@
+/*
+ *  linux/arch/arm/mach-pxa/cpu-pxa.c
+ *
+ *  Copyright (C) 2002,2003 Intrinsyc Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History:
+ *   31-Jul-2002 : Initial version [FB]
+ *   29-Jan-2003 : added PXA255 support [FB]
+ *   20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
+ *
+ * Note:
+ *   This driver may change the memory bus clock rate, but will not do any
+ *   platform specific access timing changes... for example if you have flash
+ *   memory connected to CS0, you will need to register a platform specific
+ *   notifier which will adjust the memory access strobes to maintain a
+ *   minimum strobe width.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
+
+#ifdef DEBUG
+static unsigned int freq_debug;
+MODULE_PARM(freq_debug, "i");
+MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
+#else
+#define freq_debug  0
+#endif
+
+typedef struct {
+	unsigned int khz;
+	unsigned int membus;
+	unsigned int cccr;
+	unsigned int div2;
+} pxa_freqs_t;
+
+/* Define the refresh period in mSec for the SDRAM and the number of rows */
+#define SDRAM_TREF          64      /* standard 64ms SDRAM */
+#define SDRAM_ROWS          4096    /* 64MB=8192 32MB=4096 */
+#define MDREFR_DRI(x)       (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32))
+
+#define CCLKCFG_TURBO       0x1
+#define CCLKCFG_FCS         0x2
+#define PXA25x_MIN_FREQ     99500
+#define PXA25x_MAX_FREQ     398100
+#define MDREFR_DB2_MASK     (MDREFR_K2DB2 | MDREFR_K1DB2)
+#define MDREFR_DRI_MASK     0xFFF
+
+
+/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
+static pxa_freqs_t pxa255_run_freqs[] =
+{
+    /* CPU   MEMBUS  CCCR  DIV2*/
+    { 99500,  99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50,  SDRAM=50 */
+    {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66,  SDRAM=66 */
+    {199100,  99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99,  SDRAM=99 */
+    {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
+    {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
+    {398100,  99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
+    {0,}
+};
+#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
+
+static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
+
+/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
+static pxa_freqs_t pxa255_turbo_freqs[] =
+{
+    /* CPU   MEMBUS  CCCR  DIV2*/
+    { 99500, 99500,  0x121, 1}, /* run=99,  turbo= 99, PXbus=50, SDRAM=50 */
+    {199100, 99500,  0x221, 0}, /* run=99,  turbo=199, PXbus=50, SDRAM=99 */
+    {298500, 99500,  0x321, 0}, /* run=99,  turbo=287, PXbus=50, SDRAM=99 */
+    {298600, 99500,  0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
+    {398100, 99500,  0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
+    {0,}
+};
+#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
+
+static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
+
+extern unsigned get_clk_frequency_khz(int info);
+
+/* find a valid frequency point */
+static int pxa_verify_policy(struct cpufreq_policy *policy)
+{
+	struct cpufreq_frequency_table *pxa_freqs_table;
+	int ret;
+
+	if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
+		pxa_freqs_table = pxa255_run_freq_table;
+	} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
+		pxa_freqs_table = pxa255_turbo_freq_table;
+	} else {
+		printk("CPU PXA: Unknown policy found. "
+		       "Using CPUFREQ_POLICY_PERFORMANCE\n");
+		pxa_freqs_table = pxa255_run_freq_table;
+	}
+
+	ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table);
+
+	if (freq_debug)
+		pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n",
+		       policy->min, policy->max);
+
+	return ret;
+}
+
+static int pxa_set_target(struct cpufreq_policy *policy,
+			   unsigned int target_freq,
+			   unsigned int relation)
+{
+	struct cpufreq_frequency_table *pxa_freqs_table;
+	pxa_freqs_t *pxa_freq_settings;
+	struct cpufreq_freqs freqs;
+	int idx;
+	unsigned long flags;
+	unsigned int unused, preset_mdrefr, postset_mdrefr;
+	void *ramstart = phys_to_virt(0xa0000000);
+
+	/* Get the current policy */
+	if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
+		pxa_freq_settings = pxa255_run_freqs;
+		pxa_freqs_table   = pxa255_run_freq_table;
+	} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
+		pxa_freq_settings = pxa255_turbo_freqs;
+		pxa_freqs_table   = pxa255_turbo_freq_table;
+	} else {
+		printk("CPU PXA: Unknown policy found. "
+		       "Using CPUFREQ_POLICY_PERFORMANCE\n");
+		pxa_freq_settings = pxa255_run_freqs;
+		pxa_freqs_table   = pxa255_run_freq_table;
+	}
+
+	/* Lookup the next frequency */
+	if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
+	                                   target_freq, relation, &idx)) {
+		return -EINVAL;
+	}
+
+	freqs.old = policy->cur;
+	freqs.new = pxa_freq_settings[idx].khz;
+	freqs.cpu = policy->cpu;
+
+	if (freq_debug)
+		pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
+		       freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
+		       (pxa_freq_settings[idx].membus / 2000) :
+		       (pxa_freq_settings[idx].membus / 1000));
+
+	/*
+	 * Tell everyone what we're about to do...
+	 * you should add a notify client with any platform specific
+	 * Vcc changing capability
+	 */
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* Calculate the next MDREFR.  If we're slowing down the SDRAM clock
+	 * we need to preset the smaller DRI before the change.  If we're speeding
+	 * up we need to set the larger DRI value after the change.
+	 */
+	preset_mdrefr = postset_mdrefr = MDREFR;
+	if ((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
+		preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
+		                MDREFR_DRI(pxa_freq_settings[idx].membus);
+	}
+	postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
+		            MDREFR_DRI(pxa_freq_settings[idx].membus);
+
+	/* If we're dividing the memory clock by two for the SDRAM clock, this
+	 * must be set prior to the change.  Clearing the divide must be done
+	 * after the change.
+	 */
+	if (pxa_freq_settings[idx].div2) {
+		preset_mdrefr  |= MDREFR_DB2_MASK;
+		postset_mdrefr |= MDREFR_DB2_MASK;
+	} else {
+		postset_mdrefr &= ~MDREFR_DB2_MASK;
+	}
+
+	local_irq_save(flags);
+
+	/* Set new the CCCR */
+	CCCR = pxa_freq_settings[idx].cccr;
+
+	asm volatile("							\n\
+		ldr	r4, [%1]		/* load MDREFR */	\n\
+		b	2f						\n\
+		.align	5 						\n\
+1:									\n\
+		str	%4, [%1]		/* preset the MDREFR */	\n\
+		mcr	p14, 0, %2, c6, c0, 0	/* set CCLKCFG[FCS] */	\n\
+		str	%5, [%1]		/* postset the MDREFR */ \n\
+									\n\
+		b	3f						\n\
+2:		b	1b						\n\
+3:		nop							\n\
+	  "
+	  : "=&r" (unused)
+	  : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart),
+	    "r" (preset_mdrefr), "r" (postset_mdrefr)
+	  : "r4", "r5");
+	local_irq_restore(flags);
+
+	/*
+	 * Tell everyone what we've just done...
+	 * you should add a notify client with any platform specific
+	 * SDRAM refresh timer adjustments
+	 */
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return 0;
+}
+
+static int pxa_cpufreq_init(struct cpufreq_policy *policy)
+{
+	int i;
+
+	/* set default policy and cpuinfo */
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
+	policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
+	policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
+	policy->cur = get_clk_frequency_khz(0);    /* current freq */
+	policy->min = policy->max = policy->cur;
+
+	/* Generate the run cpufreq_frequency_table struct */
+	for (i = 0; i < NUM_RUN_FREQS; i++) {
+		pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
+		pxa255_run_freq_table[i].index = i;
+	}
+
+	pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
+	/* Generate the turbo cpufreq_frequency_table struct */
+	for (i = 0; i < NUM_TURBO_FREQS; i++) {
+		pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
+		pxa255_turbo_freq_table[i].index = i;
+	}
+	pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+	printk(KERN_INFO "PXA CPU frequency change support initialized\n");
+
+	return 0;
+}
+
+static struct cpufreq_driver pxa_cpufreq_driver = {
+	.verify	= pxa_verify_policy,
+	.target	= pxa_set_target,
+	.init	= pxa_cpufreq_init,
+	.name	= "PXA25x",
+};
+
+static int __init pxa_cpu_init(void)
+{
+	int ret = -ENODEV;
+	if (cpu_is_pxa25x())
+		ret = cpufreq_register_driver(&pxa_cpufreq_driver);
+	return ret;
+}
+
+static void __exit pxa_cpu_exit(void)
+{
+	if (cpu_is_pxa25x())
+		cpufreq_unregister_driver(&pxa_cpufreq_driver);
+}
+
+
+MODULE_AUTHOR ("Intrinsyc Software Inc.");
+MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
+MODULE_LICENSE("GPL");
+module_init(pxa_cpu_init);
+module_exit(pxa_cpu_exit);
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
new file mode 100644
index 0000000..50ff453
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.c
@@ -0,0 +1,662 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/i2c.h>
+
+#include "devices.h"
+
+void __init pxa_register_device(struct platform_device *dev, void *data)
+{
+	int ret;
+
+	dev->dev.platform_data = data;
+
+	ret = platform_device_register(dev);
+	if (ret)
+		dev_err(&dev->dev, "unable to register device: %d\n", ret);
+}
+
+static struct resource pxamci_resources[] = {
+	[0] = {
+		.start	= 0x41100000,
+		.end	= 0x41100fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_MMC,
+		.end	= IRQ_MMC,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= 21,
+		.end	= 21,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		.start	= 22,
+		.end	= 22,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static u64 pxamci_dmamask = 0xffffffffUL;
+
+struct platform_device pxa_device_mci = {
+	.name		= "pxa2xx-mci",
+	.id		= 0,
+	.dev		= {
+		.dma_mask = &pxamci_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(pxamci_resources),
+	.resource	= pxamci_resources,
+};
+
+void __init pxa_set_mci_info(struct pxamci_platform_data *info)
+{
+	pxa_register_device(&pxa_device_mci, info);
+}
+
+
+static struct pxa2xx_udc_mach_info pxa_udc_info;
+
+void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
+{
+	memcpy(&pxa_udc_info, info, sizeof *info);
+}
+
+static struct resource pxa2xx_udc_resources[] = {
+	[0] = {
+		.start	= 0x40600000,
+		.end	= 0x4060ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_USB,
+		.end	= IRQ_USB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 udc_dma_mask = ~(u32)0;
+
+struct platform_device pxa_device_udc = {
+	.name		= "pxa2xx-udc",
+	.id		= -1,
+	.resource	= pxa2xx_udc_resources,
+	.num_resources	= ARRAY_SIZE(pxa2xx_udc_resources),
+	.dev		=  {
+		.platform_data	= &pxa_udc_info,
+		.dma_mask	= &udc_dma_mask,
+	}
+};
+
+static struct resource pxafb_resources[] = {
+	[0] = {
+		.start	= 0x44000000,
+		.end	= 0x4400ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_LCD,
+		.end	= IRQ_LCD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 fb_dma_mask = ~(u64)0;
+
+struct platform_device pxa_device_fb = {
+	.name		= "pxa2xx-fb",
+	.id		= -1,
+	.dev		= {
+		.dma_mask	= &fb_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(pxafb_resources),
+	.resource	= pxafb_resources,
+};
+
+void __init set_pxa_fb_info(struct pxafb_mach_info *info)
+{
+	pxa_register_device(&pxa_device_fb, info);
+}
+
+void __init set_pxa_fb_parent(struct device *parent_dev)
+{
+	pxa_device_fb.dev.parent = parent_dev;
+}
+
+static struct resource pxa_resource_ffuart[] = {
+	{
+		.start	= __PREG(FFUART),
+		.end	= __PREG(FFUART) + 35,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_FFUART,
+		.end	= IRQ_FFUART,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device pxa_device_ffuart= {
+	.name		= "pxa2xx-uart",
+	.id		= 0,
+	.resource	= pxa_resource_ffuart,
+	.num_resources	= ARRAY_SIZE(pxa_resource_ffuart),
+};
+
+static struct resource pxa_resource_btuart[] = {
+	{
+		.start	= __PREG(BTUART),
+		.end	= __PREG(BTUART) + 35,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_BTUART,
+		.end	= IRQ_BTUART,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device pxa_device_btuart = {
+	.name		= "pxa2xx-uart",
+	.id		= 1,
+	.resource	= pxa_resource_btuart,
+	.num_resources	= ARRAY_SIZE(pxa_resource_btuart),
+};
+
+static struct resource pxa_resource_stuart[] = {
+	{
+		.start	= __PREG(STUART),
+		.end	= __PREG(STUART) + 35,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_STUART,
+		.end	= IRQ_STUART,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device pxa_device_stuart = {
+	.name		= "pxa2xx-uart",
+	.id		= 2,
+	.resource	= pxa_resource_stuart,
+	.num_resources	= ARRAY_SIZE(pxa_resource_stuart),
+};
+
+static struct resource pxa_resource_hwuart[] = {
+	{
+		.start	= __PREG(HWUART),
+		.end	= __PREG(HWUART) + 47,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_HWUART,
+		.end	= IRQ_HWUART,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device pxa_device_hwuart = {
+	.name		= "pxa2xx-uart",
+	.id		= 3,
+	.resource	= pxa_resource_hwuart,
+	.num_resources	= ARRAY_SIZE(pxa_resource_hwuart),
+};
+
+static struct resource pxai2c_resources[] = {
+	{
+		.start	= 0x40301680,
+		.end	= 0x403016a3,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_I2C,
+		.end	= IRQ_I2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device pxa_device_i2c = {
+	.name		= "pxa2xx-i2c",
+	.id		= 0,
+	.resource	= pxai2c_resources,
+	.num_resources	= ARRAY_SIZE(pxai2c_resources),
+};
+
+void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
+{
+	pxa_register_device(&pxa_device_i2c, info);
+}
+
+static struct resource pxai2s_resources[] = {
+	{
+		.start	= 0x40400000,
+		.end	= 0x40400083,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_I2S,
+		.end	= IRQ_I2S,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device pxa_device_i2s = {
+	.name		= "pxa2xx-i2s",
+	.id		= -1,
+	.resource	= pxai2s_resources,
+	.num_resources	= ARRAY_SIZE(pxai2s_resources),
+};
+
+static u64 pxaficp_dmamask = ~(u32)0;
+
+struct platform_device pxa_device_ficp = {
+	.name		= "pxa2xx-ir",
+	.id		= -1,
+	.dev		= {
+		.dma_mask = &pxaficp_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+};
+
+void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
+{
+	pxa_register_device(&pxa_device_ficp, info);
+}
+
+struct platform_device pxa_device_rtc = {
+	.name		= "sa1100-rtc",
+	.id		= -1,
+};
+
+#ifdef CONFIG_PXA25x
+
+static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa25x_resource_ssp[] = {
+	[0] = {
+		.start	= 0x41000000,
+		.end	= 0x4100001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_SSP,
+		.end	= IRQ_SSP,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* DRCMR for RX */
+		.start	= 13,
+		.end	= 13,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		/* DRCMR for TX */
+		.start	= 14,
+		.end	= 14,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa25x_device_ssp = {
+	.name		= "pxa25x-ssp",
+	.id		= 0,
+	.dev		= {
+		.dma_mask = &pxa25x_ssp_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.resource	= pxa25x_resource_ssp,
+	.num_resources	= ARRAY_SIZE(pxa25x_resource_ssp),
+};
+
+static u64 pxa25x_nssp_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa25x_resource_nssp[] = {
+	[0] = {
+		.start	= 0x41400000,
+		.end	= 0x4140002f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_NSSP,
+		.end	= IRQ_NSSP,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* DRCMR for RX */
+		.start	= 15,
+		.end	= 15,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		/* DRCMR for TX */
+		.start	= 16,
+		.end	= 16,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa25x_device_nssp = {
+	.name		= "pxa25x-nssp",
+	.id		= 1,
+	.dev		= {
+		.dma_mask = &pxa25x_nssp_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.resource	= pxa25x_resource_nssp,
+	.num_resources	= ARRAY_SIZE(pxa25x_resource_nssp),
+};
+
+static u64 pxa25x_assp_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa25x_resource_assp[] = {
+	[0] = {
+		.start	= 0x41500000,
+		.end	= 0x4150002f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_ASSP,
+		.end	= IRQ_ASSP,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* DRCMR for RX */
+		.start	= 23,
+		.end	= 23,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		/* DRCMR for TX */
+		.start	= 24,
+		.end	= 24,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa25x_device_assp = {
+	/* ASSP is basically equivalent to NSSP */
+	.name		= "pxa25x-nssp",
+	.id		= 2,
+	.dev		= {
+		.dma_mask = &pxa25x_assp_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.resource	= pxa25x_resource_assp,
+	.num_resources	= ARRAY_SIZE(pxa25x_resource_assp),
+};
+#endif /* CONFIG_PXA25x */
+
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
+
+static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa27x_resource_ohci[] = {
+	[0] = {
+		.start  = 0x4C000000,
+		.end    = 0x4C00ff6f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = IRQ_USBH1,
+		.end    = IRQ_USBH1,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device pxa27x_device_ohci = {
+	.name		= "pxa27x-ohci",
+	.id		= -1,
+	.dev		= {
+		.dma_mask = &pxa27x_ohci_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.num_resources  = ARRAY_SIZE(pxa27x_resource_ohci),
+	.resource       = pxa27x_resource_ohci,
+};
+
+void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
+{
+	pxa_register_device(&pxa27x_device_ohci, info);
+}
+
+static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa27x_resource_ssp1[] = {
+	[0] = {
+		.start	= 0x41000000,
+		.end	= 0x4100003f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_SSP,
+		.end	= IRQ_SSP,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* DRCMR for RX */
+		.start	= 13,
+		.end	= 13,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		/* DRCMR for TX */
+		.start	= 14,
+		.end	= 14,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa27x_device_ssp1 = {
+	.name		= "pxa27x-ssp",
+	.id		= 0,
+	.dev		= {
+		.dma_mask = &pxa27x_ssp1_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.resource	= pxa27x_resource_ssp1,
+	.num_resources	= ARRAY_SIZE(pxa27x_resource_ssp1),
+};
+
+static u64 pxa27x_ssp2_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa27x_resource_ssp2[] = {
+	[0] = {
+		.start	= 0x41700000,
+		.end	= 0x4170003f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_SSP2,
+		.end	= IRQ_SSP2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* DRCMR for RX */
+		.start	= 15,
+		.end	= 15,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		/* DRCMR for TX */
+		.start	= 16,
+		.end	= 16,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa27x_device_ssp2 = {
+	.name		= "pxa27x-ssp",
+	.id		= 1,
+	.dev		= {
+		.dma_mask = &pxa27x_ssp2_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.resource	= pxa27x_resource_ssp2,
+	.num_resources	= ARRAY_SIZE(pxa27x_resource_ssp2),
+};
+
+static u64 pxa27x_ssp3_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa27x_resource_ssp3[] = {
+	[0] = {
+		.start	= 0x41900000,
+		.end	= 0x4190003f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_SSP3,
+		.end	= IRQ_SSP3,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* DRCMR for RX */
+		.start	= 66,
+		.end	= 66,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		/* DRCMR for TX */
+		.start	= 67,
+		.end	= 67,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa27x_device_ssp3 = {
+	.name		= "pxa27x-ssp",
+	.id		= 2,
+	.dev		= {
+		.dma_mask = &pxa27x_ssp3_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.resource	= pxa27x_resource_ssp3,
+	.num_resources	= ARRAY_SIZE(pxa27x_resource_ssp3),
+};
+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
+
+#ifdef CONFIG_PXA3xx
+static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa3xx_resource_ssp4[] = {
+	[0] = {
+		.start	= 0x41a00000,
+		.end	= 0x41a0003f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_SSP4,
+		.end	= IRQ_SSP4,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* DRCMR for RX */
+		.start	= 2,
+		.end	= 2,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		/* DRCMR for TX */
+		.start	= 3,
+		.end	= 3,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa3xx_device_ssp4 = {
+	/* PXA3xx SSP is basically equivalent to PXA27x */
+	.name		= "pxa27x-ssp",
+	.id		= 3,
+	.dev		= {
+		.dma_mask = &pxa3xx_ssp4_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.resource	= pxa3xx_resource_ssp4,
+	.num_resources	= ARRAY_SIZE(pxa3xx_resource_ssp4),
+};
+
+static struct resource pxa3xx_resources_mci2[] = {
+	[0] = {
+		.start	= 0x42000000,
+		.end	= 0x42000fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_MMC2,
+		.end	= IRQ_MMC2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= 93,
+		.end	= 93,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		.start	= 94,
+		.end	= 94,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa3xx_device_mci2 = {
+	.name		= "pxa2xx-mci",
+	.id		= 1,
+	.dev		= {
+		.dma_mask = &pxamci_dmamask,
+		.coherent_dma_mask =	0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(pxa3xx_resources_mci2),
+	.resource	= pxa3xx_resources_mci2,
+};
+
+void __init pxa3xx_set_mci2_info(struct pxamci_platform_data *info)
+{
+	pxa_register_device(&pxa3xx_device_mci2, info);
+}
+
+static struct resource pxa3xx_resources_mci3[] = {
+	[0] = {
+		.start	= 0x42500000,
+		.end	= 0x42500fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_MMC3,
+		.end	= IRQ_MMC3,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= 100,
+		.end	= 100,
+		.flags	= IORESOURCE_DMA,
+	},
+	[3] = {
+		.start	= 101,
+		.end	= 101,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device pxa3xx_device_mci3 = {
+	.name		= "pxa2xx-mci",
+	.id		= 2,
+	.dev		= {
+		.dma_mask = &pxamci_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(pxa3xx_resources_mci3),
+	.resource	= pxa3xx_resources_mci3,
+};
+
+void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info)
+{
+	pxa_register_device(&pxa3xx_device_mci3, info);
+}
+
+#endif /* CONFIG_PXA3xx */
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 94c8d5c..96c7c89 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -1,4 +1,6 @@
 extern struct platform_device pxa_device_mci;
+extern struct platform_device pxa3xx_device_mci2;
+extern struct platform_device pxa3xx_device_mci3;
 extern struct platform_device pxa_device_udc;
 extern struct platform_device pxa_device_fb;
 extern struct platform_device pxa_device_ffuart;
@@ -12,3 +14,13 @@
 
 extern struct platform_device pxa27x_device_i2c_power;
 extern struct platform_device pxa27x_device_ohci;
+
+extern struct platform_device pxa25x_device_ssp;
+extern struct platform_device pxa25x_device_nssp;
+extern struct platform_device pxa25x_device_assp;
+extern struct platform_device pxa27x_device_ssp1;
+extern struct platform_device pxa27x_device_ssp2;
+extern struct platform_device pxa27x_device_ssp3;
+extern struct platform_device pxa3xx_device_ssp4;
+
+void __init pxa_register_device(struct platform_device *dev, void *data);
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
new file mode 100644
index 0000000..ee0ae93
--- /dev/null
+++ b/arch/arm/mach-pxa/eseries.c
@@ -0,0 +1,101 @@
+/*
+ * Hardware definitions for the Toshiba eseries PDAs
+ *
+ * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
+ *
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ */
+
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/hardware.h>
+#include <asm/mach-types.h>
+
+#include <generic.h>
+
+/* Only e800 has 128MB RAM */
+static void __init eseries_fixup(struct machine_desc *desc,
+                      struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+	mi->nr_banks=1;
+	mi->bank[0].start = 0xa0000000;
+	mi->bank[0].node = 0;
+	if (machine_is_e800())
+		mi->bank[0].size = (128*1024*1024);
+	else
+		mi->bank[0].size = (64*1024*1024);
+}
+
+/* e-series machine definitions */
+
+#ifdef CONFIG_MACH_E330
+MACHINE_START(E330, "Toshiba e330")
+        /* Maintainer: Ian Molton (spyro@f2s.com) */
+        .phys_io        = 0x40000000,
+        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+        .boot_params    = 0xa0000100,
+        .map_io         = pxa_map_io,
+        .init_irq       = pxa25x_init_irq,
+        .fixup          = eseries_fixup,
+        .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_E740
+MACHINE_START(E740, "Toshiba e740")
+        /* Maintainer: Ian Molton (spyro@f2s.com) */
+        .phys_io        = 0x40000000,
+        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+        .boot_params    = 0xa0000100,
+        .map_io         = pxa_map_io,
+        .init_irq       = pxa25x_init_irq,
+        .fixup          = eseries_fixup,
+        .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_E750
+MACHINE_START(E750, "Toshiba e750")
+        /* Maintainer: Ian Molton (spyro@f2s.com) */
+        .phys_io        = 0x40000000,
+        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+        .boot_params    = 0xa0000100,
+        .map_io         = pxa_map_io,
+        .init_irq       = pxa25x_init_irq,
+        .fixup          = eseries_fixup,
+        .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_E400
+MACHINE_START(E400, "Toshiba e400")
+        /* Maintainer: Ian Molton (spyro@f2s.com) */
+        .phys_io        = 0x40000000,
+        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+        .boot_params    = 0xa0000100,
+        .map_io         = pxa_map_io,
+        .init_irq       = pxa25x_init_irq,
+        .fixup          = eseries_fixup,
+        .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_E800
+MACHINE_START(E800, "Toshiba e800")
+        /* Maintainer: Ian Molton (spyro@f2s.com) */
+        .phys_io        = 0x40000000,
+        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+        .boot_params    = 0xa0000100,
+        .map_io         = pxa_map_io,
+        .init_irq       = pxa25x_init_irq,
+        .fixup          = eseries_fixup,
+        .timer = &pxa_timer,
+MACHINE_END
+#endif
+
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 1c34946..698aeec 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -20,7 +20,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <linux/pm.h>
 #include <linux/string.h>
@@ -33,13 +32,7 @@
 
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/gpio.h>
-#include <asm/arch/udc.h>
-#include <asm/arch/pxafb.h>
-#include <asm/arch/mmc.h>
-#include <asm/arch/irda.h>
-#include <asm/arch/i2c.h>
 
-#include "devices.h"
 #include "generic.h"
 
 /*
@@ -203,7 +196,7 @@
 	}, {	/* Mem Ctl */
 		.virtual	=  0xf6000000,
 		.pfn		= __phys_to_pfn(0x48000000),
-		.length		= 0x00100000,
+		.length		= 0x00200000,
 		.type		= MT_DEVICE
 	}, {	/* USB host */
 		.virtual	=  0xf8000000,
@@ -233,245 +226,3 @@
 	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
 	get_clk_frequency_khz(1);
 }
-
-
-static struct resource pxamci_resources[] = {
-	[0] = {
-		.start	= 0x41100000,
-		.end	= 0x41100fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_MMC,
-		.end	= IRQ_MMC,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static u64 pxamci_dmamask = 0xffffffffUL;
-
-struct platform_device pxa_device_mci = {
-	.name		= "pxa2xx-mci",
-	.id		= -1,
-	.dev		= {
-		.dma_mask = &pxamci_dmamask,
-		.coherent_dma_mask = 0xffffffff,
-	},
-	.num_resources	= ARRAY_SIZE(pxamci_resources),
-	.resource	= pxamci_resources,
-};
-
-void __init pxa_set_mci_info(struct pxamci_platform_data *info)
-{
-	pxa_device_mci.dev.platform_data = info;
-}
-
-
-static struct pxa2xx_udc_mach_info pxa_udc_info;
-
-void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
-{
-	memcpy(&pxa_udc_info, info, sizeof *info);
-}
-
-static struct resource pxa2xx_udc_resources[] = {
-	[0] = {
-		.start	= 0x40600000,
-		.end	= 0x4060ffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_USB,
-		.end	= IRQ_USB,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static u64 udc_dma_mask = ~(u32)0;
-
-struct platform_device pxa_device_udc = {
-	.name		= "pxa2xx-udc",
-	.id		= -1,
-	.resource	= pxa2xx_udc_resources,
-	.num_resources	= ARRAY_SIZE(pxa2xx_udc_resources),
-	.dev		=  {
-		.platform_data	= &pxa_udc_info,
-		.dma_mask	= &udc_dma_mask,
-	}
-};
-
-static struct resource pxafb_resources[] = {
-	[0] = {
-		.start	= 0x44000000,
-		.end	= 0x4400ffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_LCD,
-		.end	= IRQ_LCD,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static u64 fb_dma_mask = ~(u64)0;
-
-struct platform_device pxa_device_fb = {
-	.name		= "pxa2xx-fb",
-	.id		= -1,
-	.dev		= {
-		.dma_mask	= &fb_dma_mask,
-		.coherent_dma_mask = 0xffffffff,
-	},
-	.num_resources	= ARRAY_SIZE(pxafb_resources),
-	.resource	= pxafb_resources,
-};
-
-void __init set_pxa_fb_info(struct pxafb_mach_info *info)
-{
-	pxa_device_fb.dev.platform_data = info;
-}
-
-void __init set_pxa_fb_parent(struct device *parent_dev)
-{
-	pxa_device_fb.dev.parent = parent_dev;
-}
-
-static struct resource pxa_resource_ffuart[] = {
-	{
-		.start	= __PREG(FFUART),
-		.end	= __PREG(FFUART) + 35,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_FFUART,
-		.end	= IRQ_FFUART,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-struct platform_device pxa_device_ffuart= {
-	.name		= "pxa2xx-uart",
-	.id		= 0,
-	.resource	= pxa_resource_ffuart,
-	.num_resources	= ARRAY_SIZE(pxa_resource_ffuart),
-};
-
-static struct resource pxa_resource_btuart[] = {
-	{
-		.start	= __PREG(BTUART),
-		.end	= __PREG(BTUART) + 35,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_BTUART,
-		.end	= IRQ_BTUART,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-struct platform_device pxa_device_btuart = {
-	.name		= "pxa2xx-uart",
-	.id		= 1,
-	.resource	= pxa_resource_btuart,
-	.num_resources	= ARRAY_SIZE(pxa_resource_btuart),
-};
-
-static struct resource pxa_resource_stuart[] = {
-	{
-		.start	= __PREG(STUART),
-		.end	= __PREG(STUART) + 35,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_STUART,
-		.end	= IRQ_STUART,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-struct platform_device pxa_device_stuart = {
-	.name		= "pxa2xx-uart",
-	.id		= 2,
-	.resource	= pxa_resource_stuart,
-	.num_resources	= ARRAY_SIZE(pxa_resource_stuart),
-};
-
-static struct resource pxa_resource_hwuart[] = {
-	{
-		.start	= __PREG(HWUART),
-		.end	= __PREG(HWUART) + 47,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_HWUART,
-		.end	= IRQ_HWUART,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-struct platform_device pxa_device_hwuart = {
-	.name		= "pxa2xx-uart",
-	.id		= 3,
-	.resource	= pxa_resource_hwuart,
-	.num_resources	= ARRAY_SIZE(pxa_resource_hwuart),
-};
-
-static struct resource pxai2c_resources[] = {
-	{
-		.start	= 0x40301680,
-		.end	= 0x403016a3,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_I2C,
-		.end	= IRQ_I2C,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device pxa_device_i2c = {
-	.name		= "pxa2xx-i2c",
-	.id		= 0,
-	.resource	= pxai2c_resources,
-	.num_resources	= ARRAY_SIZE(pxai2c_resources),
-};
-
-void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
-{
-	pxa_device_i2c.dev.platform_data = info;
-}
-
-static struct resource pxai2s_resources[] = {
-	{
-		.start	= 0x40400000,
-		.end	= 0x40400083,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_I2S,
-		.end	= IRQ_I2S,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device pxa_device_i2s = {
-	.name		= "pxa2xx-i2s",
-	.id		= -1,
-	.resource	= pxai2s_resources,
-	.num_resources	= ARRAY_SIZE(pxai2s_resources),
-};
-
-static u64 pxaficp_dmamask = ~(u32)0;
-
-struct platform_device pxa_device_ficp = {
-	.name		= "pxa2xx-ir",
-	.id		= -1,
-	.dev		= {
-		.dma_mask = &pxaficp_dmamask,
-		.coherent_dma_mask = 0xffffffff,
-	},
-};
-
-void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
-{
-	pxa_device_ficp.dev.platform_data = info;
-}
-
-struct platform_device pxa_device_rtc = {
-	.name		= "sa1100-rtc",
-	.id		= -1,
-};
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 465108d..0a94344 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -54,7 +54,7 @@
 	[1] = {
 		.start	= IRQ_GPIO(4),
 		.end	= IRQ_GPIO(4),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	}
 };
 
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
new file mode 100644
index 0000000..0a4b54c
--- /dev/null
+++ b/arch/arm/mach-pxa/littleton.c
@@ -0,0 +1,325 @@
+/*
+ *  linux/arch/arm/mach-pxa/littleton.c
+ *
+ *  Support for the Marvell Littleton Development Platform.
+ *
+ *  Author:	Jason Chagas (largely modified code)
+ *  Created:	Nov 20, 2006
+ *  Copyright:	(C) Copyright 2006 Marvell International Ltd.
+ *
+ *  2007-11-22  modified to align with latest kernel
+ *              eric miao <eric.miao@marvell.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/mfp-pxa300.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/ssp.h>
+#include <asm/arch/littleton.h>
+
+#include "generic.h"
+
+#define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
+
+/* Littleton MFP configurations */
+static mfp_cfg_t littleton_mfp_cfg[] __initdata = {
+	/* LCD */
+	GPIO54_LCD_LDD_0,
+	GPIO55_LCD_LDD_1,
+	GPIO56_LCD_LDD_2,
+	GPIO57_LCD_LDD_3,
+	GPIO58_LCD_LDD_4,
+	GPIO59_LCD_LDD_5,
+	GPIO60_LCD_LDD_6,
+	GPIO61_LCD_LDD_7,
+	GPIO62_LCD_LDD_8,
+	GPIO63_LCD_LDD_9,
+	GPIO64_LCD_LDD_10,
+	GPIO65_LCD_LDD_11,
+	GPIO66_LCD_LDD_12,
+	GPIO67_LCD_LDD_13,
+	GPIO68_LCD_LDD_14,
+	GPIO69_LCD_LDD_15,
+	GPIO70_LCD_LDD_16,
+	GPIO71_LCD_LDD_17,
+	GPIO72_LCD_FCLK,
+	GPIO73_LCD_LCLK,
+	GPIO74_LCD_PCLK,
+	GPIO75_LCD_BIAS,
+
+	/* SSP2 */
+	GPIO25_SSP2_SCLK,
+	GPIO17_SSP2_FRM,
+	GPIO27_SSP2_TXD,
+
+	/* Debug Ethernet */
+	GPIO90_GPIO,
+};
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= (LITTLETON_ETH_PHYS + 0x300),
+		.end	= (LITTLETON_ETH_PHYS + 0xfffff),
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
+		.end	= IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+	}
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULES)
+/* use bit 30, 31 as the indicator of command parameter number */
+#define CMD0(x)		((0x00000000) | ((x) << 9))
+#define CMD1(x, x1)	((0x40000000) | ((x) << 9) | 0x100 | (x1))
+#define CMD2(x, x1, x2)	((0x80000000) | ((x) << 18) | 0x20000 |\
+			 ((x1) << 9) | 0x100 | (x2))
+
+static uint32_t lcd_panel_reset[] = {
+	CMD0(0x1), /* reset */
+	CMD0(0x0), /* nop */
+	CMD0(0x0), /* nop */
+	CMD0(0x0), /* nop */
+};
+
+static uint32_t lcd_panel_on[] = {
+	CMD0(0x29),		/* Display ON */
+	CMD2(0xB8, 0xFF, 0xF9),	/* Output Control */
+	CMD0(0x11),		/* Sleep out */
+	CMD1(0xB0, 0x16),	/* Wake */
+};
+
+static uint32_t lcd_panel_off[] = {
+	CMD0(0x28),		/* Display OFF */
+	CMD2(0xB8, 0x80, 0x02),	/* Output Control */
+	CMD0(0x10),		/* Sleep in */
+	CMD1(0xB0, 0x00),	/* Deep stand by in */
+};
+
+static uint32_t lcd_vga_pass_through[] = {
+	CMD1(0xB0, 0x16),
+	CMD1(0xBC, 0x80),
+	CMD1(0xE1, 0x00),
+	CMD1(0x36, 0x50),
+	CMD1(0x3B, 0x00),
+};
+
+static uint32_t lcd_qvga_pass_through[] = {
+	CMD1(0xB0, 0x16),
+	CMD1(0xBC, 0x81),
+	CMD1(0xE1, 0x00),
+	CMD1(0x36, 0x50),
+	CMD1(0x3B, 0x22),
+};
+
+static uint32_t lcd_vga_transfer[] = {
+	CMD1(0xcf, 0x02), 	/* Blanking period control (1) */
+	CMD2(0xd0, 0x08, 0x04),	/* Blanking period control (2) */
+	CMD1(0xd1, 0x01),	/* CKV timing control on/off */
+	CMD2(0xd2, 0x14, 0x00),	/* CKV 1,2 timing control */
+	CMD2(0xd3, 0x1a, 0x0f),	/* OEV timing control */
+	CMD2(0xd4, 0x1f, 0xaf),	/* ASW timing control (1) */
+	CMD1(0xd5, 0x14),	/* ASW timing control (2) */
+	CMD0(0x21),		/* Invert for normally black display */
+	CMD0(0x29),		/* Display on */
+};
+
+static uint32_t lcd_qvga_transfer[] = {
+	CMD1(0xd6, 0x02),	/* Blanking period control (1) */
+	CMD2(0xd7, 0x08, 0x04),	/* Blanking period control (2) */
+	CMD1(0xd8, 0x01),	/* CKV timing control on/off */
+	CMD2(0xd9, 0x00, 0x08),	/* CKV 1,2 timing control */
+	CMD2(0xde, 0x05, 0x0a),	/* OEV timing control */
+	CMD2(0xdf, 0x0a, 0x19),	/* ASW timing control (1) */
+	CMD1(0xe0, 0x0a),	/* ASW timing control (2) */
+	CMD0(0x21),		/* Invert for normally black display */
+	CMD0(0x29),		/* Display on */
+};
+
+static uint32_t lcd_panel_config[] = {
+	CMD2(0xb8, 0xff, 0xf9),	/* Output control */
+	CMD0(0x11),		/* sleep out */
+	CMD1(0xba, 0x01),	/* Display mode (1) */
+	CMD1(0xbb, 0x00),	/* Display mode (2) */
+	CMD1(0x3a, 0x60),	/* Display mode 18-bit RGB */
+	CMD1(0xbf, 0x10),	/* Drive system change control */
+	CMD1(0xb1, 0x56),	/* Booster operation setup */
+	CMD1(0xb2, 0x33),	/* Booster mode setup */
+	CMD1(0xb3, 0x11),	/* Booster frequency setup */
+	CMD1(0xb4, 0x02),	/* Op amp/system clock */
+	CMD1(0xb5, 0x35),	/* VCS voltage */
+	CMD1(0xb6, 0x40),	/* VCOM voltage */
+	CMD1(0xb7, 0x03),	/* External display signal */
+	CMD1(0xbd, 0x00),	/* ASW slew rate */
+	CMD1(0xbe, 0x00),	/* Dummy data for QuadData operation */
+	CMD1(0xc0, 0x11),	/* Sleep out FR count (A) */
+	CMD1(0xc1, 0x11),	/* Sleep out FR count (B) */
+	CMD1(0xc2, 0x11),	/* Sleep out FR count (C) */
+	CMD2(0xc3, 0x20, 0x40),	/* Sleep out FR count (D) */
+	CMD2(0xc4, 0x60, 0xc0),	/* Sleep out FR count (E) */
+	CMD2(0xc5, 0x10, 0x20),	/* Sleep out FR count (F) */
+	CMD1(0xc6, 0xc0),	/* Sleep out FR count (G) */
+	CMD2(0xc7, 0x33, 0x43),	/* Gamma 1 fine tuning (1) */
+	CMD1(0xc8, 0x44),	/* Gamma 1 fine tuning (2) */
+	CMD1(0xc9, 0x33),	/* Gamma 1 inclination adjustment */
+	CMD1(0xca, 0x00),	/* Gamma 1 blue offset adjustment */
+	CMD2(0xec, 0x01, 0xf0),	/* Horizontal clock cycles */
+};
+
+static void ssp_reconfig(struct ssp_dev *dev, int nparam)
+{
+	static int last_nparam = -1;
+
+	/* check if it is necessary to re-config SSP */
+	if (nparam == last_nparam)
+		return;
+
+	ssp_disable(dev);
+	ssp_config(dev, (nparam == 2) ? 0x0010058a : 0x00100581, 0x18, 0, 0);
+
+	last_nparam = nparam;
+}
+
+static void ssp_send_cmd(uint32_t *cmd, int num)
+{
+	static int ssp_initialized;
+	static struct ssp_dev ssp2;
+
+	int i;
+
+	if (!ssp_initialized) {
+		ssp_init(&ssp2, 2, SSP_NO_IRQ);
+		ssp_initialized = 1;
+	}
+
+	clk_enable(ssp2.ssp->clk);
+	for (i = 0; i < num; i++, cmd++) {
+		ssp_reconfig(&ssp2, (*cmd >> 30) & 0x3);
+		ssp_write_word(&ssp2, *cmd & 0x3fffffff);
+
+		/* FIXME: ssp_flush() is mandatory here to work */
+		ssp_flush(&ssp2);
+	}
+	clk_disable(ssp2.ssp->clk);
+}
+
+static void littleton_lcd_power(int on, struct fb_var_screeninfo *var)
+{
+	if (on) {
+		ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_on));
+		ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_reset));
+		if (var->xres > 240) {
+			/* VGA */
+			ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_pass_through));
+			ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config));
+			ssp_send_cmd(ARRAY_AND_SIZE(lcd_vga_transfer));
+		} else {
+			/* QVGA */
+			ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_pass_through));
+			ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_config));
+			ssp_send_cmd(ARRAY_AND_SIZE(lcd_qvga_transfer));
+		}
+	} else
+		ssp_send_cmd(ARRAY_AND_SIZE(lcd_panel_off));
+}
+
+static struct pxafb_mode_info tpo_tdo24mtea1_modes[] = {
+	[0] = {
+		/* VGA */
+		.pixclock	= 38250,
+		.xres		= 480,
+		.yres		= 640,
+		.bpp		= 16,
+		.hsync_len	= 8,
+		.left_margin	= 8,
+		.right_margin	= 24,
+		.vsync_len	= 2,
+		.upper_margin	= 2,
+		.lower_margin	= 4,
+		.sync		= 0,
+	},
+	[1] = {
+		/* QVGA */
+		.pixclock	= 153000,
+		.xres		= 240,
+		.yres		= 320,
+		.bpp		= 16,
+		.hsync_len	= 8,
+		.left_margin	= 8,
+		.right_margin	= 88,
+		.vsync_len	= 2,
+		.upper_margin	= 2,
+		.lower_margin	= 2,
+		.sync		= 0,
+	},
+};
+
+static struct pxafb_mach_info littleton_lcd_info = {
+	.modes			= tpo_tdo24mtea1_modes,
+	.num_modes		= 2,
+	.lccr0			= LCCR0_Act,
+	.lccr3			= LCCR3_HSP | LCCR3_VSP,
+	.pxafb_lcd_power	= littleton_lcd_power,
+};
+
+static void littleton_init_lcd(void)
+{
+	set_pxa_fb_info(&littleton_lcd_info);
+}
+#else
+static inline void littleton_init_lcd(void) {};
+#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULES */
+
+static void __init littleton_init(void)
+{
+	/* initialize MFP configurations */
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(littleton_mfp_cfg));
+
+	/*
+	 * Note: we depend bootloader set the correct
+	 * value to MSC register for SMC91x.
+	 */
+	platform_device_register(&smc91x_device);
+
+	littleton_init_lcd();
+}
+
+MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)")
+	.phys_io	= 0x40000000,
+	.boot_params	= 0xa0000100,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa3xx_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= littleton_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 78ebad0..afa62ff 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -38,6 +38,7 @@
 #include <asm/mach/flash.h>
 
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
 #include <asm/arch/lpd270.h>
 #include <asm/arch/audio.h>
 #include <asm/arch/pxafb.h>
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 1d3112d..e7ae4bb 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -41,6 +41,7 @@
 #include <asm/hardware/sa1111.h>
 
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
 #include <asm/arch/lubbock.h>
 #include <asm/arch/udc.h>
 #include <asm/arch/irda.h>
@@ -136,9 +137,13 @@
 
 static int __init lubbock_irq_device_init(void)
 {
-	int ret = sysdev_class_register(&lubbock_irq_sysclass);
-	if (ret == 0)
-		ret = sysdev_register(&lubbock_irq_device);
+	int ret = -ENODEV;
+
+	if (machine_is_lubbock()) {
+		ret = sysdev_class_register(&lubbock_irq_sysclass);
+		if (ret == 0)
+			ret = sysdev_register(&lubbock_irq_device);
+	}
 	return ret;
 }
 
@@ -191,7 +196,7 @@
 	[1] = {
 		.start	= LUBBOCK_ETH_IRQ,
 		.end	= LUBBOCK_ETH_IRQ,
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	},
 	[2] = {
 		.name	= "smc91x-attrib",
@@ -206,30 +211,13 @@
  * (to J5) and poking board registers (as done below).  Else it's only useful
  * for the temperature sensors.
  */
-static struct resource pxa_ssp_resources[] = {
-	[0] = {
-		.start	= __PREG(SSCR0_P(1)),
-		.end	= __PREG(SSCR0_P(1)) + 0x14,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_SSP,
-		.end	= IRQ_SSP,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
 static struct pxa2xx_spi_master pxa_ssp_master_info = {
-	.ssp_type	= PXA25x_SSP,
-	.clock_enable	= CKEN_SSP,
 	.num_chipselect	= 0,
 };
 
 static struct platform_device pxa_ssp = {
 	.name		= "pxa2xx-spi",
 	.id		= 1,
-	.resource	= pxa_ssp_resources,
-	.num_resources	= ARRAY_SIZE(pxa_ssp_resources),
 	.dev = {
 		.platform_data	= &pxa_ssp_master_info,
 	},
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
new file mode 100644
index 0000000..d98ef7a
--- /dev/null
+++ b/arch/arm/mach-pxa/magician.c
@@ -0,0 +1,218 @@
+/*
+ * Support for HTC Magician PDA phones:
+ * i-mate JAM, O2 Xda mini, Orange SPV M500, Qtek s100, Qtek s110
+ * and T-Mobile MDA Compact.
+ *
+ * Copyright (c) 2006-2007 Philipp Zabel
+ *
+ * Based on hx4700.c, spitz.c and others.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/gpio.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/magician.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/ohci.h>
+
+#include "generic.h"
+
+/*
+ * IRDA
+ */
+
+static void magician_irda_transceiver_mode(struct device *dev, int mode)
+{
+	gpio_set_value(GPIO83_MAGICIAN_nIR_EN, mode & IR_OFF);
+}
+
+static struct pxaficp_platform_data magician_ficp_info = {
+	.transceiver_cap  = IR_SIRMODE | IR_OFF,
+	.transceiver_mode = magician_irda_transceiver_mode,
+};
+
+/*
+ * GPIO Keys
+ */
+
+static struct gpio_keys_button magician_button_table[] = {
+	{KEY_POWER,      GPIO0_MAGICIAN_KEY_POWER,      0, "Power button"},
+	{KEY_ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    0, "Hangup button"},
+	{KEY_F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  0, "Contacts button"},
+	{KEY_CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  0, "Calendar button"},
+	{KEY_CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    0, "Camera button"},
+	{KEY_UP,         GPIO93_MAGICIAN_KEY_UP,        0, "Up button"},
+	{KEY_DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      0, "Down button"},
+	{KEY_LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      0, "Left button"},
+	{KEY_RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     0, "Right button"},
+	{KEY_KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     0, "Action button"},
+	{KEY_RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    0, "Record button"},
+	{KEY_VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   0, "Volume up"},
+	{KEY_VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, 0, "Volume down"},
+	{KEY_PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    0, "Phone button"},
+	{KEY_PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  0, "Headset button"},
+};
+
+static struct gpio_keys_platform_data gpio_keys_data = {
+	.buttons  = magician_button_table,
+	.nbuttons = ARRAY_SIZE(magician_button_table),
+};
+
+static struct platform_device gpio_keys = {
+	.name = "gpio-keys",
+	.dev  = {
+		.platform_data = &gpio_keys_data,
+	},
+	.id   = -1,
+};
+
+/*
+ * LCD - Toppoly TD028STEB1
+ */
+
+static struct pxafb_mode_info toppoly_modes[] = {
+	{
+		.pixclock     = 96153,
+		.bpp          = 16,
+		.xres         = 240,
+		.yres         = 320,
+		.hsync_len    = 11,
+		.vsync_len    = 3,
+		.left_margin  = 19,
+		.upper_margin = 2,
+		.right_margin = 10,
+		.lower_margin = 2,
+		.sync         = 0,
+	},
+};
+
+static struct pxafb_mach_info toppoly_info = {
+	.modes       = toppoly_modes,
+	.num_modes   = 1,
+	.fixed_modes = 1,
+	.lccr0       = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3       = LCCR3_PixRsEdg,
+};
+
+/*
+ * Backlight
+ */
+
+static void magician_set_bl_intensity(int intensity)
+{
+	if (intensity) {
+		PWM_CTRL0 = 1;
+		PWM_PERVAL0 = 0xc8;
+		PWM_PWDUTY0 = intensity;
+		pxa_set_cken(CKEN_PWM0, 1);
+	} else {
+		pxa_set_cken(CKEN_PWM0, 0);
+	}
+}
+
+static struct generic_bl_info backlight_info = {
+	.default_intensity = 0x64,
+	.limit_mask        = 0x0b,
+	.max_intensity     = 0xc7,
+	.set_bl_intensity  = magician_set_bl_intensity,
+};
+
+static struct platform_device backlight = {
+	.name = "corgi-bl",
+	.dev  = {
+		.platform_data = &backlight_info,
+	},
+	.id   = -1,
+};
+
+
+/*
+ * USB OHCI
+ */
+
+static int magician_ohci_init(struct device *dev)
+{
+	UHCHR = (UHCHR | UHCHR_SSEP2 | UHCHR_PCPL | UHCHR_CGR) &
+	    ~(UHCHR_SSEP1 | UHCHR_SSEP3 | UHCHR_SSE);
+
+	return 0;
+}
+
+static struct pxaohci_platform_data magician_ohci_info = {
+	.port_mode    = PMM_PERPORT_MODE,
+	.init         = magician_ohci_init,
+	.power_budget = 0,
+};
+
+
+/*
+ * StrataFlash
+ */
+
+#define PXA_CS_SIZE		0x04000000
+
+static struct resource strataflash_resource = {
+	.start = PXA_CS0_PHYS,
+	.end   = PXA_CS0_PHYS + PXA_CS_SIZE - 1,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data strataflash_data = {
+	.width = 4,
+};
+
+static struct platform_device strataflash = {
+	.name          = "physmap-flash",
+	.id            = -1,
+	.num_resources = 1,
+	.resource      = &strataflash_resource,
+	.dev = {
+		.platform_data = &strataflash_data,
+	},
+};
+
+/*
+ * Platform devices
+ */
+
+static struct platform_device *devices[] __initdata = {
+	&gpio_keys,
+	&backlight,
+	&strataflash,
+};
+
+static void __init magician_init(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	pxa_set_ohci_info(&magician_ohci_info);
+	pxa_set_ficp_info(&magician_ficp_info);
+	set_pxa_fb_info(&toppoly_info);
+}
+
+
+MACHINE_START(MAGICIAN, "HTC Magician")
+	.phys_io = 0x40000000,
+	.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params = 0xa0000100,
+	.map_io = pxa_map_io,
+	.init_irq = pxa27x_init_irq,
+	.init_machine = magician_init,
+	.timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 41d8c6c..345c3de 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -23,6 +23,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/backlight.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -38,6 +39,7 @@
 #include <asm/mach/flash.h>
 
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
 #include <asm/arch/mainstone.h>
 #include <asm/arch/audio.h>
 #include <asm/arch/pxafb.h>
@@ -130,9 +132,13 @@
 
 static int __init mainstone_irq_device_init(void)
 {
-	int ret = sysdev_class_register(&mainstone_irq_sysclass);
-	if (ret == 0)
-		ret = sysdev_register(&mainstone_irq_device);
+	int ret = -ENODEV;
+
+	if (machine_is_mainstone()) {
+		ret = sysdev_class_register(&mainstone_irq_sysclass);
+		if (ret == 0)
+			ret = sysdev_register(&mainstone_irq_device);
+	}
 	return ret;
 }
 
@@ -150,7 +156,7 @@
 	[1] = {
 		.start	= MAINSTONE_IRQ(3),
 		.end	= MAINSTONE_IRQ(3),
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	}
 };
 
@@ -263,22 +269,61 @@
 	},
 };
 
-static void mainstone_backlight_power(int on)
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+static int mainstone_backlight_update_status(struct backlight_device *bl)
 {
-	if (on) {
+	int brightness = bl->props.brightness;
+
+	if (bl->props.power != FB_BLANK_UNBLANK ||
+	    bl->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (brightness != 0) {
 		pxa_gpio_mode(GPIO16_PWM0_MD);
 		pxa_set_cken(CKEN_PWM0, 1);
-		PWM_CTRL0 = 0;
-		PWM_PWDUTY0 = 0x3ff;
-		PWM_PERVAL0 = 0x3ff;
-	} else {
-		PWM_CTRL0 = 0;
-		PWM_PWDUTY0 = 0x0;
-		PWM_PERVAL0 = 0x3FF;
-		pxa_set_cken(CKEN_PWM0, 0);
 	}
+	PWM_CTRL0 = 0;
+	PWM_PWDUTY0 = brightness;
+	PWM_PERVAL0 = bl->props.max_brightness;
+	if (brightness == 0)
+		pxa_set_cken(CKEN_PWM0, 0);
+	return 0; /* pointless return value */
 }
 
+static int mainstone_backlight_get_brightness(struct backlight_device *bl)
+{
+	return PWM_PWDUTY0;
+}
+
+static /*const*/ struct backlight_ops mainstone_backlight_ops = {
+	.update_status	= mainstone_backlight_update_status,
+	.get_brightness	= mainstone_backlight_get_brightness,
+};
+
+static void __init mainstone_backlight_register(void)
+{
+	struct backlight_device *bl;
+
+	bl = backlight_device_register("mainstone-bl", &pxa_device_fb.dev,
+				       NULL, &mainstone_backlight_ops);
+	if (IS_ERR(bl)) {
+		printk(KERN_ERR "mainstone: unable to register backlight: %ld\n",
+		       PTR_ERR(bl));
+		return;
+	}
+
+	/*
+	 * broken design - register-then-setup interfaces are
+	 * utterly broken by definition.
+	 */
+	bl->props.max_brightness = 1023;
+	bl->props.brightness = 1023;
+	backlight_update_status(bl);
+}
+#else
+#define mainstone_backlight_register()	do { } while (0)
+#endif
+
 static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
 	.pixclock		= 50000,
 	.xres			= 640,
@@ -311,7 +356,6 @@
 	.num_modes      	= 1,
 	.lccr0			= LCCR0_Act,
 	.lccr3			= LCCR3_PCP,
-	.pxafb_backlight_power	= mainstone_backlight_power,
 };
 
 static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data)
@@ -335,12 +379,10 @@
 
 	err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED,
 			     "MMC card detect", data);
-	if (err) {
+	if (err)
 		printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
-		return -1;
-	}
 
-	return 0;
+	return err;
 }
 
 static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
@@ -473,6 +515,7 @@
 		mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
 
 	set_pxa_fb_info(&mainstone_pxafb_info);
+	mainstone_backlight_register();
 
 	pxa_set_mci_info(&mainstone_mci_platform_data);
 	pxa_set_ficp_info(&mainstone_ficp_platform_data);
diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c
index 436f965..ec1b2d8 100644
--- a/arch/arm/mach-pxa/mfp.c
+++ b/arch/arm/mach-pxa/mfp.c
@@ -17,9 +17,11 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/sysdev.h>
 
 #include <asm/hardware.h>
 #include <asm/arch/mfp.h>
+#include <asm/arch/mfp-pxa3xx.h>
 
 /* mfp_spin_lock is used to ensure that MFP register configuration
  * (most likely a read-modify-write operation) is atomic, and that
@@ -28,43 +30,110 @@
 static DEFINE_SPINLOCK(mfp_spin_lock);
 
 static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
+
+struct pxa3xx_mfp_pin {
+	unsigned long	config;		/* -1 for not configured */
+	unsigned long	mfpr_off;	/* MFPRxx Register offset */
+	unsigned long	mfpr_run;	/* Run-Mode Register Value */
+	unsigned long	mfpr_lpm;	/* Low Power Mode Register Value */
+};
+
 static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];
 
+/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */
+const static unsigned long mfpr_lpm[] = {
+	MFPR_LPM_INPUT,
+	MFPR_LPM_DRIVE_LOW,
+	MFPR_LPM_DRIVE_HIGH,
+	MFPR_LPM_PULL_LOW,
+	MFPR_LPM_PULL_HIGH,
+	MFPR_LPM_FLOAT,
+};
+
+/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
+const static unsigned long mfpr_pull[] = {
+	MFPR_PULL_NONE,
+	MFPR_PULL_LOW,
+	MFPR_PULL_HIGH,
+	MFPR_PULL_BOTH,
+};
+
+/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */
+const static unsigned long mfpr_edge[] = {
+	MFPR_EDGE_NONE,
+	MFPR_EDGE_RISE,
+	MFPR_EDGE_FALL,
+	MFPR_EDGE_BOTH,
+};
+
 #define mfpr_readl(off)			\
 	__raw_readl(mfpr_mmio_base + (off))
 
 #define mfpr_writel(off, val)		\
 	__raw_writel(val, mfpr_mmio_base + (off))
 
+#define mfp_configured(p)	((p)->config != -1)
+
 /*
  * perform a read-back of any MFPR register to make sure the
  * previous writings are finished
  */
 #define mfpr_sync()	(void)__raw_readl(mfpr_mmio_base + 0)
 
-static inline void __mfp_config(int pin, unsigned long val)
+static inline void __mfp_config_run(struct pxa3xx_mfp_pin *p)
 {
-	unsigned long off = mfp_table[pin].mfpr_off;
-
-	mfp_table[pin].mfpr_val = val;
-	mfpr_writel(off, val);
+	if (mfp_configured(p))
+		mfpr_writel(p->mfpr_off, p->mfpr_run);
 }
 
-void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num)
+static inline void __mfp_config_lpm(struct pxa3xx_mfp_pin *p)
 {
-	int i, pin;
-	unsigned long val, flags;
-	mfp_cfg_t *mfp_cfg = mfp_cfgs;
+	if (mfp_configured(p)) {
+		unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR;
+		if (mfpr_clr != p->mfpr_run)
+			mfpr_writel(p->mfpr_off, mfpr_clr);
+		if (p->mfpr_lpm != mfpr_clr)
+			mfpr_writel(p->mfpr_off, p->mfpr_lpm);
+	}
+}
+
+void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num)
+{
+	unsigned long flags;
+	int i;
 
 	spin_lock_irqsave(&mfp_spin_lock, flags);
 
-	for (i = 0; i < num; i++, mfp_cfg++) {
-		pin = MFP_CFG_PIN(*mfp_cfg);
-		val = MFP_CFG_VAL(*mfp_cfg);
+	for (i = 0; i < num; i++, mfp_cfgs++) {
+		unsigned long tmp, c = *mfp_cfgs;
+		struct pxa3xx_mfp_pin *p;
+		int pin, af, drv, lpm, edge, pull;
 
+		pin = MFP_PIN(c);
 		BUG_ON(pin >= MFP_PIN_MAX);
+		p = &mfp_table[pin];
 
-		__mfp_config(pin, val);
+		af  = MFP_AF(c);
+		drv = MFP_DS(c);
+		lpm = MFP_LPM_STATE(c);
+		edge = MFP_LPM_EDGE(c);
+		pull = MFP_PULL(c);
+
+		/* run-mode pull settings will conflict with MFPR bits of
+		 * low power mode state,  calculate mfpr_run and mfpr_lpm
+		 * individually if pull != MFP_PULL_NONE
+		 */
+		tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
+
+		if (likely(pull == MFP_PULL_NONE)) {
+			p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
+			p->mfpr_lpm = p->mfpr_run;
+		} else {
+			p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
+			p->mfpr_run = tmp | mfpr_pull[pull];
+		}
+
+		p->config = c; __mfp_config_run(p);
 	}
 
 	mfpr_sync();
@@ -96,117 +165,6 @@
 	spin_unlock_irqrestore(&mfp_spin_lock, flags);
 }
 
-void pxa3xx_mfp_set_afds(int mfp, int af, int ds)
-{
-	uint32_t mfpr_off, mfpr_val;
-	unsigned long flags;
-
-	BUG_ON(mfp >= MFP_PIN_MAX);
-
-	spin_lock_irqsave(&mfp_spin_lock, flags);
-	mfpr_off = mfp_table[mfp].mfpr_off;
-
-	mfpr_val = mfpr_readl(mfpr_off);
-	mfpr_val &= ~(MFPR_AF_MASK | MFPR_DRV_MASK);
-	mfpr_val |= (((af & 0x7) << MFPR_ALT_OFFSET) |
-		     ((ds & 0x7) << MFPR_DRV_OFFSET));
-
-	mfpr_writel(mfpr_off, mfpr_val);
-	mfpr_sync();
-
-	spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-void pxa3xx_mfp_set_rdh(int mfp, int rdh)
-{
-	uint32_t mfpr_off, mfpr_val;
-	unsigned long flags;
-
-	BUG_ON(mfp >= MFP_PIN_MAX);
-
-	spin_lock_irqsave(&mfp_spin_lock, flags);
-
-	mfpr_off = mfp_table[mfp].mfpr_off;
-
-	mfpr_val = mfpr_readl(mfpr_off);
-	mfpr_val &= ~MFPR_RDH_MASK;
-
-	if (likely(rdh))
-		mfpr_val |= (1u << MFPR_SS_OFFSET);
-
-	mfpr_writel(mfpr_off, mfpr_val);
-	mfpr_sync();
-
-	spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-void pxa3xx_mfp_set_lpm(int mfp, int lpm)
-{
-	uint32_t mfpr_off, mfpr_val;
-	unsigned long flags;
-
-	BUG_ON(mfp >= MFP_PIN_MAX);
-
-	spin_lock_irqsave(&mfp_spin_lock, flags);
-
-	mfpr_off = mfp_table[mfp].mfpr_off;
-	mfpr_val = mfpr_readl(mfpr_off);
-	mfpr_val &= ~MFPR_LPM_MASK;
-
-	if (lpm & 0x1) mfpr_val |= 1u << MFPR_SON_OFFSET;
-	if (lpm & 0x2) mfpr_val |= 1u << MFPR_SD_OFFSET;
-	if (lpm & 0x4) mfpr_val |= 1u << MFPR_PU_OFFSET;
-	if (lpm & 0x8) mfpr_val |= 1u << MFPR_PD_OFFSET;
-	if (lpm &0x10) mfpr_val |= 1u << MFPR_PS_OFFSET;
-
-	mfpr_writel(mfpr_off, mfpr_val);
-	mfpr_sync();
-
-	spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-void pxa3xx_mfp_set_pull(int mfp, int pull)
-{
-	uint32_t mfpr_off, mfpr_val;
-	unsigned long flags;
-
-	BUG_ON(mfp >= MFP_PIN_MAX);
-
-	spin_lock_irqsave(&mfp_spin_lock, flags);
-
-	mfpr_off = mfp_table[mfp].mfpr_off;
-	mfpr_val = mfpr_readl(mfpr_off);
-	mfpr_val &= ~MFPR_PULL_MASK;
-	mfpr_val |= ((pull & 0x7u) << MFPR_PD_OFFSET);
-
-	mfpr_writel(mfpr_off, mfpr_val);
-	mfpr_sync();
-
-	spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-void pxa3xx_mfp_set_edge(int mfp, int edge)
-{
-	uint32_t mfpr_off, mfpr_val;
-	unsigned long flags;
-
-	BUG_ON(mfp >= MFP_PIN_MAX);
-
-	spin_lock_irqsave(&mfp_spin_lock, flags);
-
-	mfpr_off = mfp_table[mfp].mfpr_off;
-	mfpr_val = mfpr_readl(mfpr_off);
-
-	mfpr_val &= ~MFPR_EDGE_MASK;
-	mfpr_val |= (edge & 0x3u) << MFPR_ERE_OFFSET;
-	mfpr_val |= (!edge & 0x1) << MFPR_EC_OFFSET;
-
-	mfpr_writel(mfpr_off, mfpr_val);
-	mfpr_sync();
-
-	spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
 void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
 {
 	struct pxa3xx_mfp_addr_map *p;
@@ -221,7 +179,8 @@
 
 		do {
 			mfp_table[i].mfpr_off = offset;
-			mfp_table[i].mfpr_val = 0;
+			mfp_table[i].mfpr_run = 0;
+			mfp_table[i].mfpr_lpm = 0;
 			offset += 4; i++;
 		} while ((i <= p->end) && (p->end != -1));
 	}
@@ -231,5 +190,57 @@
 
 void __init pxa3xx_init_mfp(void)
 {
-	memset(mfp_table, 0, sizeof(mfp_table));
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
+		mfp_table[i].config = -1;
 }
+
+#ifdef CONFIG_PM
+/*
+ * Configure the MFPs appropriately for suspend/resume.
+ * FIXME: this should probably depend on which system state we're
+ * entering - for instance, we might not want to place MFP pins in
+ * a pull-down mode if they're an active low chip select, and we're
+ * just entering standby.
+ */
+static int pxa3xx_mfp_suspend(struct sys_device *d, pm_message_t state)
+{
+	int pin;
+
+	for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
+		struct pxa3xx_mfp_pin *p = &mfp_table[pin];
+		__mfp_config_lpm(p);
+	}
+	return 0;
+}
+
+static int pxa3xx_mfp_resume(struct sys_device *d)
+{
+	int pin;
+
+	for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
+		struct pxa3xx_mfp_pin *p = &mfp_table[pin];
+		__mfp_config_run(p);
+	}
+	return 0;
+}
+
+static struct sysdev_class mfp_sysclass = {
+	set_kset_name("mfp"),
+	.suspend	= pxa3xx_mfp_suspend,
+	.resume 	= pxa3xx_mfp_resume,
+};
+
+static struct sys_device mfp_device = {
+	.id		= 0,
+	.cls		= &mfp_sysclass,
+};
+
+static int __init mfp_init_devicefs(void)
+{
+	sysdev_class_register(&mfp_sysclass);
+	return sysdev_register(&mfp_device);
+}
+device_initcall(mfp_init_devicefs);
+#endif
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
new file mode 100644
index 0000000..540c3bb
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -0,0 +1,216 @@
+/*
+ *  linux/arch/arm/mach-pxa/pcm027.c
+ *  Support for the Phytec phyCORE-PXA270 CPU card (aka PCM-027).
+ *
+ *  Refer
+ *   http://www.phytec.com/products/sbc/ARM-XScale/phyCORE-XScale-PXA270.html
+ *  for additional hardware info
+ *
+ *  Author:	Juergen Kilb
+ *  Created:	April 05, 2005
+ *  Copyright:	Phytec Messtechnik GmbH
+ *  e-Mail:	armlinux@phytec.de
+ *
+ *  based on Intel Mainstone Board
+ *
+ *  Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx_spi.h>
+#include <asm/arch/pcm027.h>
+#include "generic.h"
+
+/*
+ * ABSTRACT:
+ *
+ * The PXA270 processor comes with a bunch of hardware on its silicon.
+ * Not all of this hardware can be used at the same time and not all
+ * is routed to module's connectors. Also it depends on the baseboard, what
+ * kind of hardware can be used in which way.
+ * -> So this file supports the main devices on the CPU card only!
+ * Refer pcm990-baseboard.c how to extend this features to get a full
+ * blown system with many common interfaces.
+ *
+ * The PCM-027 supports the following interfaces through its connectors and
+ * will be used in pcm990-baseboard.c:
+ *
+ * - LCD support
+ * - MMC support
+ * - IDE/CF card
+ * - FFUART
+ * - BTUART
+ * - IRUART
+ * - AC97
+ * - SSP
+ * - SSP3
+ *
+ * Claimed GPIOs:
+ * GPIO0 -> IRQ input from RTC
+ * GPIO2 -> SYS_ENA*)
+ * GPIO3 -> PWR_SCL
+ * GPIO4 -> PWR_SDA
+ * GPIO5 -> PowerCap0*)
+ * GPIO6 -> PowerCap1*)
+ * GPIO7 -> PowerCap2*)
+ * GPIO8 -> PowerCap3*)
+ * GPIO15 -> /CS1
+ * GPIO20 -> /CS2
+ * GPIO21 -> /CS3
+ * GPIO33 -> /CS5 network controller select
+ * GPIO52 -> IRQ from network controller
+ * GPIO78 -> /CS2
+ * GPIO80 -> /CS4
+ * GPIO90 -> LED0
+ * GPIO91 -> LED1
+ * GPIO114 -> IRQ from CAN controller
+ * GPIO117 -> SCL
+ * GPIO118 -> SDA
+ *
+ * *) CPU internal use only
+ */
+
+/*
+ * SMC91x network controller specific stuff
+ */
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= PCM027_ETH_PHYS + 0x300,
+		.end	= PCM027_ETH_PHYS + PCM027_ETH_SIZE,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= PCM027_ETH_IRQ,
+		.end	= PCM027_ETH_IRQ,
+		/* note: smc91x's driver doesn't use the trigger bits yet */
+		.flags	= IORESOURCE_IRQ | PCM027_ETH_IRQ_EDGE,
+	}
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static struct physmap_flash_data pcm027_flash_data = {
+	.width  = 4,
+};
+
+static struct resource pcm027_flash_resource = {
+	.start          = PCM027_FLASH_PHYS,
+	.end            = PCM027_FLASH_PHYS + PCM027_FLASH_SIZE - 1 ,
+	.flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm027_flash = {
+	.name           = "physmap-flash",
+	.id             = 0,
+	.dev            = {
+		.platform_data  = &pcm027_flash_data,
+	},
+	.resource       = &pcm027_flash_resource,
+	.num_resources  = 1,
+};
+
+#ifdef CONFIG_LEDS_GPIO
+
+static struct gpio_led pcm027_led[] = {
+	{
+		.name = "led0:red",	/* FIXME */
+		.gpio = PCM027_LED_CPU
+	},
+	{
+		.name = "led1:green",	/* FIXME */
+		.gpio = PCM027_LED_HEARD_BEAT
+	},
+};
+
+static struct gpio_led_platform_data pcm027_led_data = {
+	.num_leds	= ARRAY_SIZE(pcm027_led),
+	.leds		= pcm027_led
+};
+
+static struct platform_device pcm027_led_dev = {
+	.name		= "leds-gpio",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &pcm027_led_data,
+	},
+};
+
+#endif /* CONFIG_LEDS_GPIO */
+
+/*
+ * declare the available device resources on this board
+ */
+static struct platform_device *devices[] __initdata = {
+	&smc91x_device,
+	&pcm027_flash,
+#ifdef CONFIG_LEDS_GPIO
+	&pcm027_led_dev
+#endif
+};
+
+/*
+ * pcm027_init - breath some life into the board
+ */
+static void __init pcm027_init(void)
+{
+	/* system bus arbiter setting
+	 * - Core_Park
+	 * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
+	 */
+	ARB_CNTRL = ARB_CORE_PARK | 0x234;
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	/* LEDs (on demand only) */
+#ifdef CONFIG_LEDS_GPIO
+	pxa_gpio_mode(PCM027_LED_CPU | GPIO_OUT);
+	pxa_gpio_mode(PCM027_LED_HEARD_BEAT | GPIO_OUT);
+#endif /* CONFIG_LEDS_GPIO */
+
+	/* at last call the baseboard to initialize itself */
+#ifdef CONFIG_MACH_PCM990_BASEBOARD
+	pcm990_baseboard_init();
+#endif
+}
+
+static void __init pcm027_map_io(void)
+{
+	pxa_map_io();
+
+	/* initialize sleep mode regs (wake-up sources, etc) */
+	PGSR0 = 0x01308000;
+	PGSR1 = 0x00CF0002;
+	PGSR2 = 0x0E294000;
+	PGSR3 = 0x0000C000;
+	PWER  = 0x40000000 | PWER_GPIO0 | PWER_GPIO1;
+	PRER  = 0x00000000;
+	PFER  = 0x00000003;
+}
+
+MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270")
+	/* Maintainer: Pengutronix */
+	.boot_params	= 0xa0000100,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= pcm027_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= pcm027_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
new file mode 100644
index 0000000..3dda16a
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -0,0 +1,330 @@
+/*
+ *  arch/arm/mach-pxa/pcm990-baseboard.c
+ *  Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
+ *
+ *  Refer
+ *   http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
+ *  for additional hardware info
+ *
+ *  Author:	Juergen Kilb
+ *  Created:	April 05, 2005
+ *  Copyright:	Phytec Messtechnik GmbH
+ *  e-Mail:	armlinux@phytec.de
+ *
+ *  based on Intel Mainstone Board
+ *
+ *  Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ide.h>
+#include <asm/mach/map.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/ohci.h>
+#include <asm/arch/pcm990_baseboard.h>
+
+/*
+ * The PCM-990 development baseboard uses PCM-027's hardeware in the
+ * following way:
+ *
+ * - LCD support is in use
+ *  - GPIO16 is output for back light on/off with PWM
+ *  - GPIO58 ... GPIO73 are outputs for display data
+ *  - GPIO74 is output output for LCDFCLK
+ *  - GPIO75 is output for LCDLCLK
+ *  - GPIO76 is output for LCDPCLK
+ *  - GPIO77 is output for LCDBIAS
+ * - MMC support is in use
+ *  - GPIO32 is output for MMCCLK
+ *  - GPIO92 is MMDAT0
+ *  - GPIO109 is MMDAT1
+ *  - GPIO110 is MMCS0
+ *  - GPIO111 is MMCS1
+ *  - GPIO112 is MMCMD
+ * - IDE/CF card is in use
+ *  - GPIO48 is output /POE
+ *  - GPIO49 is output /PWE
+ *  - GPIO50 is output /PIOR
+ *  - GPIO51 is output /PIOW
+ *  - GPIO54 is output /PCE2
+ *  - GPIO55 is output /PREG
+ *  - GPIO56 is input /PWAIT
+ *  - GPIO57 is output /PIOS16
+ *  - GPIO79 is output PSKTSEL
+ *  - GPIO85 is output /PCE1
+ * - FFUART is in use
+ *  - GPIO34 is input FFRXD
+ *  - GPIO35 is input FFCTS
+ *  - GPIO36 is input FFDCD
+ *  - GPIO37 is input FFDSR
+ *  - GPIO38 is input FFRI
+ *  - GPIO39 is output FFTXD
+ *  - GPIO40 is output FFDTR
+ *  - GPIO41 is output FFRTS
+ * - BTUART is in use
+ *  - GPIO42 is input BTRXD
+ *  - GPIO43 is output BTTXD
+ *  - GPIO44 is input BTCTS
+ *  - GPIO45 is output BTRTS
+ * - IRUART is in use
+ *  - GPIO46 is input STDRXD
+ *  - GPIO47 is output STDTXD
+ * - AC97 is in use*)
+ *  - GPIO28 is input AC97CLK
+ *  - GPIO29 is input AC97DatIn
+ *  - GPIO30 is output AC97DatO
+ *  - GPIO31 is output AC97SYNC
+ *  - GPIO113 is output AC97_RESET
+ * - SSP is in use
+ *  - GPIO23 is output SSPSCLK
+ *  - GPIO24 is output chip select to Max7301
+ *  - GPIO25 is output SSPTXD
+ *  - GPIO26 is input SSPRXD
+ *  - GPIO27 is input for Max7301 IRQ
+ *  - GPIO53 is input SSPSYSCLK
+ * - SSP3 is in use
+ *  - GPIO81 is output SSPTXD3
+ *  - GPIO82 is input SSPRXD3
+ *  - GPIO83 is output SSPSFRM
+ *  - GPIO84 is output SSPCLK3
+ *
+ * Otherwise claimed GPIOs:
+ * GPIO1 -> IRQ from user switch
+ * GPIO9 -> IRQ from power management
+ * GPIO10 -> IRQ from WML9712 AC97 controller
+ * GPIO11 -> IRQ from IDE controller
+ * GPIO12 -> IRQ from CF controller
+ * GPIO13 -> IRQ from CF controller
+ * GPIO14 -> GPIO free
+ * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path)
+ * GPIO19 -> GPIO free
+ * GPIO20 -> /SDCS2
+ * GPIO21 -> /CS3 PC card socket select
+ * GPIO33 -> /CS5  network controller select
+ * GPIO78 -> /CS2  (16 bit wide data path)
+ * GPIO80 -> /CS4  (16 bit wide data path)
+ * GPIO86 -> GPIO free
+ * GPIO87 -> GPIO free
+ * GPIO90 -> LED0 on CPU module
+ * GPIO91 -> LED1 on CPI module
+ * GPIO117 -> SCL
+ * GPIO118 -> SDA
+ */
+
+static unsigned long pcm990_irq_enabled;
+
+static void pcm990_mask_ack_irq(unsigned int irq)
+{
+	int pcm990_irq = (irq - PCM027_IRQ(0));
+	PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq));
+}
+
+static void pcm990_unmask_irq(unsigned int irq)
+{
+	int pcm990_irq = (irq - PCM027_IRQ(0));
+	/* the irq can be acknowledged only if deasserted, so it's done here */
+	PCM990_INTSETCLR |= 1 << pcm990_irq;
+	PCM990_INTMSKENA  = (pcm990_irq_enabled |= (1 << pcm990_irq));
+}
+
+static struct irq_chip pcm990_irq_chip = {
+	.mask_ack	= pcm990_mask_ack_irq,
+	.unmask		= pcm990_unmask_irq,
+};
+
+static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
+
+	do {
+		GEDR(PCM990_CTRL_INT_IRQ_GPIO) =
+					GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO);
+		if (likely(pending)) {
+			irq = PCM027_IRQ(0) + __ffs(pending);
+			desc = irq_desc + irq;
+			desc_handle_irq(irq, desc);
+		}
+		pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
+	} while (pending);
+}
+
+static void __init pcm990_init_irq(void)
+{
+	int irq;
+
+	/* setup extra PCM990 irqs */
+	for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
+		set_irq_chip(irq, &pcm990_irq_chip);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	PCM990_INTMSKENA = 0x00;	/* disable all Interrupts */
+	PCM990_INTSETCLR = 0xFF;
+
+	set_irq_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
+	set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
+}
+
+static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
+			void *data)
+{
+	int err;
+
+	/*
+	 * enable GPIO for PXA27x MMC controller
+	 */
+	pxa_gpio_mode(GPIO32_MMCCLK_MD);
+	pxa_gpio_mode(GPIO112_MMCCMD_MD);
+	pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+	pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+	pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+	pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+	err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED,
+			     "MMC card detect", data);
+	if (err)
+		printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC "
+				"card detect IRQ\n");
+
+	return err;
+}
+
+static void pcm990_mci_setpower(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data *p_d = dev->platform_data;
+
+	if ((1 << vdd) & p_d->ocr_mask)
+		__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
+						PCM990_CTRL_MMC2PWR;
+	else
+		__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
+						~PCM990_CTRL_MMC2PWR;
+}
+
+static void pcm990_mci_exit(struct device *dev, void *data)
+{
+	free_irq(PCM027_MMCDET_IRQ, data);
+}
+
+#define MSECS_PER_JIFFY (1000/HZ)
+
+static struct pxamci_platform_data pcm990_mci_platform_data = {
+	.detect_delay	= 250 / MSECS_PER_JIFFY,
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.init 		= pcm990_mci_init,
+	.setpower 	= pcm990_mci_setpower,
+	.exit		= pcm990_mci_exit,
+};
+
+/*
+ * init OHCI hardware to work with
+ *
+ * Note: Only USB port 1 (host only) is connected
+ *
+ * GPIO88 (USBHPWR#1): overcurrent in, overcurrent when low
+ * GPIO89 (USBHPEN#1): power-on out, on when low
+ */
+static int pcm990_ohci_init(struct device *dev)
+{
+	pxa_gpio_mode(PCM990_USB_OVERCURRENT);
+	pxa_gpio_mode(PCM990_USB_PWR_EN);
+	/*
+	 * disable USB port 2 and 3
+	 * power sense is active low
+	 */
+	UHCHR = ((UHCHR) | UHCHR_PCPL | UHCHR_PSPL | UHCHR_SSEP2 |
+				UHCHR_SSEP3) & ~(UHCHR_SSEP1 | UHCHR_SSE);
+	/*
+	 * wait 10ms after Power on
+	 * overcurrent per port
+	 * power switch per port
+	 */
+	UHCRHDA = (5<<24) | (1<<11) | (1<<8);	/* FIXME: Required? */
+
+	return 0;
+}
+
+static struct pxaohci_platform_data pcm990_ohci_platform_data = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.init		= pcm990_ohci_init,
+	.exit		= NULL,
+};
+
+/*
+ * AC97 support
+ * Note: The connected AC97 mixer also reports interrupts at PCM990_AC97_IRQ
+ */
+static struct resource pxa27x_ac97_resources[] = {
+	[0] = {
+		.start  = 0x40500000,
+		.end	= 0x40500000 + 0xfff,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = IRQ_AC97,
+		.end    = IRQ_AC97,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static u64 pxa_ac97_dmamask = 0xffffffffUL;
+
+static struct platform_device pxa27x_device_ac97 = {
+	.name           = "pxa2xx-ac97",
+	.id             = -1,
+	.dev            = {
+		.dma_mask = &pxa_ac97_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources  = ARRAY_SIZE(pxa27x_ac97_resources),
+	.resource       = pxa27x_ac97_resources,
+};
+
+/*
+ * enable generic access to the base board control CPLDs U6 and U7
+ */
+static struct map_desc pcm990_io_desc[] __initdata = {
+	{
+		.virtual	= PCM990_CTRL_BASE,
+		.pfn		= __phys_to_pfn(PCM990_CTRL_PHYS),
+		.length		= PCM990_CTRL_SIZE,
+		.type		= MT_DEVICE	/* CPLD */
+	}, {
+		.virtual	= PCM990_CF_PLD_BASE,
+		.pfn		= __phys_to_pfn(PCM990_CF_PLD_PHYS),
+		.length		= PCM990_CF_PLD_SIZE,
+		.type		= MT_DEVICE	/* CPLD */
+	}
+};
+
+/*
+ * system init for baseboard usage. Will be called by pcm027 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init pcm990_baseboard_init(void)
+{
+	/* register CPLD access */
+	iotable_init(pcm990_io_desc, ARRAY_SIZE(pcm990_io_desc));
+
+	/* register CPLD's IRQ controller */
+	pcm990_init_irq();
+
+	platform_device_register(&pxa27x_device_ac97);
+
+	/* MMC */
+	pxa_set_mci_info(&pcm990_mci_platform_data);
+
+	/* USB host */
+	pxa_set_ohci_info(&pcm990_ohci_platform_data);
+
+	printk(KERN_INFO"PCM-990 Evaluation baseboard initialized\n");
+}
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index a941c71..039194c 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -38,34 +38,37 @@
 		iwmmxt_task_disable(NULL);
 #endif
 
-	pxa_cpu_pm_fns->save(sleep_save);
+	/* skip registers saving for standby */
+	if (state != PM_SUSPEND_STANDBY) {
+		pxa_cpu_pm_fns->save(sleep_save);
+		/* before sleeping, calculate and save a checksum */
+		for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+			sleep_save_checksum += sleep_save[i];
+	}
 
 	/* Clear sleep reset status */
 	RCSR = RCSR_SMR;
 
-	/* before sleeping, calculate and save a checksum */
-	for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
-		sleep_save_checksum += sleep_save[i];
-
 	/* *** go zzz *** */
 	pxa_cpu_pm_fns->enter(state);
 	cpu_init();
 
-	/* after sleeping, validate the checksum */
-	for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
-		checksum += sleep_save[i];
+	if (state != PM_SUSPEND_STANDBY) {
+		/* after sleeping, validate the checksum */
+		for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+			checksum += sleep_save[i];
 
-	/* if invalid, display message and wait for a hardware reset */
-	if (checksum != sleep_save_checksum) {
+		/* if invalid, display message and wait for a hardware reset */
+		if (checksum != sleep_save_checksum) {
 #ifdef CONFIG_ARCH_LUBBOCK
-		LUB_HEXLED = 0xbadbadc5;
+			LUB_HEXLED = 0xbadbadc5;
 #endif
-		while (1)
-			pxa_cpu_pm_fns->enter(state);
+			while (1)
+				pxa_cpu_pm_fns->enter(state);
+		}
+		pxa_cpu_pm_fns->restore(sleep_save);
 	}
 
-	pxa_cpu_pm_fns->restore(sleep_save);
-
 	pr_debug("*** made it back from resume\n");
 
 	return 0;
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 655668d..dd54496 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -215,12 +215,10 @@
 	err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int,
 			  IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 			  "MMC card detect", data);
-	if (err) {
+	if (err)
 		printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
-		return -1;
-	}
 
-	return 0;
+	return err;
 }
 
 static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 9732d5d..ddd05bf 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -111,21 +111,27 @@
  * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
  * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
  */
+static struct clk pxa25x_hwuart_clk =
+	INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev)
+;
+
 static struct clk pxa25x_clks[] = {
 	INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev),
 	INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev),
 	INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
-	INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
 	INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL),
 	INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev),
 	INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev),
 	INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev),
+
+	INIT_CKEN("SSPCLK",  SSP, 3686400, 0, &pxa25x_device_ssp.dev),
+	INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev),
+	INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev),
+
 	/*
 	INIT_CKEN("PWMCLK",  PWM0, 3686400,  0, NULL),
 	INIT_CKEN("PWMCLK",  PWM0, 3686400,  0, NULL),
-	INIT_CKEN("SSPCLK",  SSP,  3686400,  0, NULL),
 	INIT_CKEN("I2SCLK",  I2S,  14745600, 0, NULL),
-	INIT_CKEN("NSSPCLK", NSSP, 3686400,  0, NULL),
 	*/
 	INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
 };
@@ -213,8 +219,6 @@
 
 static void pxa25x_cpu_pm_enter(suspend_state_t state)
 {
-	CKEN = 0;
-
 	switch (state) {
 	case PM_SUSPEND_MEM:
 		/* set resume return address */
@@ -236,6 +240,8 @@
 {
 	pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns;
 }
+#else
+static inline void pxa25x_init_pm(void) {}
 #endif
 
 /* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
@@ -287,30 +293,33 @@
 }
 
 static struct platform_device *pxa25x_devices[] __initdata = {
-	&pxa_device_mci,
 	&pxa_device_udc,
-	&pxa_device_fb,
 	&pxa_device_ffuart,
 	&pxa_device_btuart,
 	&pxa_device_stuart,
-	&pxa_device_i2c,
 	&pxa_device_i2s,
-	&pxa_device_ficp,
 	&pxa_device_rtc,
+	&pxa25x_device_ssp,
+	&pxa25x_device_nssp,
+	&pxa25x_device_assp,
 };
 
 static int __init pxa25x_init(void)
 {
 	int ret = 0;
 
+	/* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
+	if (cpu_is_pxa25x())
+		clks_register(&pxa25x_hwuart_clk, 1);
+
 	if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
 		clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks));
 
 		if ((ret = pxa_init_dma(16)))
 			return ret;
-#ifdef CONFIG_PM
+
 		pxa25x_init_pm();
-#endif
+
 		ret = platform_add_devices(pxa25x_devices,
 					   ARRAY_SIZE(pxa25x_devices));
 	}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 57efebd..96cf274 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -21,6 +21,7 @@
 #include <asm/irq.h>
 #include <asm/arch/irqs.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
 #include <asm/arch/ohci.h>
 #include <asm/arch/pm.h>
 #include <asm/arch/dma.h>
@@ -151,11 +152,12 @@
 	INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
 	INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
 
+	INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
+	INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
+	INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
+
 	/*
 	INIT_CKEN("PWMCLK",  PWM0, 13000000, 0, NULL),
-	INIT_CKEN("SSPCLK",  SSP1, 13000000, 0, NULL),
-	INIT_CKEN("SSPCLK",  SSP2, 13000000, 0, NULL),
-	INIT_CKEN("SSPCLK",  SSP3, 13000000, 0, NULL),
 	INIT_CKEN("MSLCLK",  MSL,  48000000, 0, NULL),
 	INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL),
 	INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL),
@@ -264,12 +266,6 @@
 {
 	extern void pxa_cpu_standby(void);
 
-	if (state == PM_SUSPEND_STANDBY)
-		CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) |
-			(1 << CKEN_LCD) | (1 << CKEN_PWM0);
-	else
-		CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER);
-
 	/* ensure voltage-change sequencer not initiated, which hangs */
 	PCFR &= ~PCFR_FVC;
 
@@ -305,6 +301,8 @@
 {
 	pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns;
 }
+#else
+static inline void pxa27x_init_pm(void) {}
 #endif
 
 /* PXA27x:  Various gpios can issue wakeup events.  This logic only
@@ -374,37 +372,6 @@
  * device registration specific to PXA27x.
  */
 
-static u64 pxa27x_dmamask = 0xffffffffUL;
-
-static struct resource pxa27x_ohci_resources[] = {
-	[0] = {
-		.start  = 0x4C000000,
-		.end    = 0x4C00ff6f,
-		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start  = IRQ_USBH1,
-		.end    = IRQ_USBH1,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device pxa27x_device_ohci = {
-	.name		= "pxa27x-ohci",
-	.id		= -1,
-	.dev		= {
-		.dma_mask = &pxa27x_dmamask,
-		.coherent_dma_mask = 0xffffffff,
-	},
-	.num_resources  = ARRAY_SIZE(pxa27x_ohci_resources),
-	.resource       = pxa27x_ohci_resources,
-};
-
-void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
-{
-	pxa27x_device_ohci.dev.platform_data = info;
-}
-
 static struct resource i2c_power_resources[] = {
 	{
 		.start	= 0x40f00180,
@@ -430,18 +397,16 @@
 }
 
 static struct platform_device *devices[] __initdata = {
-	&pxa_device_mci,
 	&pxa_device_udc,
-	&pxa_device_fb,
 	&pxa_device_ffuart,
 	&pxa_device_btuart,
 	&pxa_device_stuart,
-	&pxa_device_i2c,
 	&pxa_device_i2s,
-	&pxa_device_ficp,
 	&pxa_device_rtc,
 	&pxa27x_device_i2c_power,
-	&pxa27x_device_ohci,
+	&pxa27x_device_ssp1,
+	&pxa27x_device_ssp2,
+	&pxa27x_device_ssp3,
 };
 
 static int __init pxa27x_init(void)
@@ -452,9 +417,9 @@
 
 		if ((ret = pxa_init_dma(32)))
 			return ret;
-#ifdef CONFIG_PM
+
 		pxa27x_init_pm();
-#endif
+
 		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	}
 	return ret;
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 61d9c9d..5cbf057 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -19,6 +19,7 @@
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 
 #include <asm/hardware.h>
 #include <asm/arch/pxa3xx-regs.h>
@@ -86,7 +87,7 @@
 			HSS / 1000000, (HSS % 1000000) / 10000);
 	}
 
-	return CLK;
+	return CLK / 1000;
 }
 
 /*
@@ -189,8 +190,237 @@
 
 	PXA3xx_CKEN("I2CCLK", I2C,  32842000, 0, &pxa_device_i2c.dev),
 	PXA3xx_CKEN("UDCCLK", UDC,  48000000, 5, &pxa_device_udc.dev),
+	PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev),
+
+	PXA3xx_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
+	PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
+	PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
+	PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev),
+
+	PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev),
+	PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev),
+	PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev),
 };
 
+#ifdef CONFIG_PM
+#define SLEEP_SAVE_SIZE	4
+
+#define ISRAM_START	0x5c000000
+#define ISRAM_SIZE	SZ_256K
+
+static void __iomem *sram;
+static unsigned long wakeup_src;
+
+static void pxa3xx_cpu_pm_save(unsigned long *sleep_save)
+{
+	pr_debug("PM: CKENA=%08x CKENB=%08x\n", CKENA, CKENB);
+
+	if (CKENA & (1 << CKEN_USBH)) {
+		printk(KERN_ERR "PM: USB host clock not stopped?\n");
+		CKENA &= ~(1 << CKEN_USBH);
+	}
+//	CKENA |= 1 << (CKEN_ISC & 31);
+
+	/*
+	 * Low power modes require the HSIO2 clock to be enabled.
+	 */
+	CKENB |= 1 << (CKEN_HSIO2 & 31);
+}
+
+static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save)
+{
+	CKENB &= ~(1 << (CKEN_HSIO2 & 31));
+}
+
+/*
+ * Enter a standby mode (S0D1C2 or S0D2C2).  Upon wakeup, the dynamic
+ * memory controller has to be reinitialised, so we place some code
+ * in the SRAM to perform this function.
+ *
+ * We disable FIQs across the standby - otherwise, we might receive a
+ * FIQ while the SDRAM is unavailable.
+ */
+static void pxa3xx_cpu_standby(unsigned int pwrmode)
+{
+	extern const char pm_enter_standby_start[], pm_enter_standby_end[];
+	void (*fn)(unsigned int) = (void __force *)(sram + 0x8000);
+
+	memcpy_toio(sram + 0x8000, pm_enter_standby_start,
+		    pm_enter_standby_end - pm_enter_standby_start);
+
+	AD2D0SR = ~0;
+	AD2D1SR = ~0;
+	AD2D0ER = wakeup_src;
+	AD2D1ER = 0;
+	ASCR = ASCR;
+	ARSR = ARSR;
+
+	local_fiq_disable();
+	fn(pwrmode);
+	local_fiq_enable();
+
+	AD2D0ER = 0;
+	AD2D1ER = 0;
+
+	printk("PM: AD2D0SR=%08x ASCR=%08x\n", AD2D0SR, ASCR);
+}
+
+static void pxa3xx_cpu_pm_enter(suspend_state_t state)
+{
+	/*
+	 * Don't sleep if no wakeup sources are defined
+	 */
+	if (wakeup_src == 0)
+		return;
+
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+		pxa3xx_cpu_standby(PXA3xx_PM_S0D2C2);
+		break;
+
+	case PM_SUSPEND_MEM:
+		break;
+	}
+}
+
+static int pxa3xx_cpu_pm_valid(suspend_state_t state)
+{
+	return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
+}
+
+static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = {
+	.save_size	= SLEEP_SAVE_SIZE,
+	.save		= pxa3xx_cpu_pm_save,
+	.restore	= pxa3xx_cpu_pm_restore,
+	.valid		= pxa3xx_cpu_pm_valid,
+	.enter		= pxa3xx_cpu_pm_enter,
+};
+
+static void __init pxa3xx_init_pm(void)
+{
+	sram = ioremap(ISRAM_START, ISRAM_SIZE);
+	if (!sram) {
+		printk(KERN_ERR "Unable to map ISRAM: disabling standby/suspend\n");
+		return;
+	}
+
+	/*
+	 * Since we copy wakeup code into the SRAM, we need to ensure
+	 * that it is preserved over the low power modes.  Note: bit 8
+	 * is undocumented in the developer manual, but must be set.
+	 */
+	AD1R |= ADXR_L2 | ADXR_R0;
+	AD2R |= ADXR_L2 | ADXR_R0;
+	AD3R |= ADXR_L2 | ADXR_R0;
+
+	/*
+	 * Clear the resume enable registers.
+	 */
+	AD1D0ER = 0;
+	AD2D0ER = 0;
+	AD2D1ER = 0;
+	AD3ER = 0;
+
+	pxa_cpu_pm_fns = &pxa3xx_cpu_pm_fns;
+}
+
+static int pxa3xx_set_wake(unsigned int irq, unsigned int on)
+{
+	unsigned long flags, mask = 0;
+
+	switch (irq) {
+	case IRQ_SSP3:
+		mask = ADXER_MFP_WSSP3;
+		break;
+	case IRQ_MSL:
+		mask = ADXER_WMSL0;
+		break;
+	case IRQ_USBH2:
+	case IRQ_USBH1:
+		mask = ADXER_WUSBH;
+		break;
+	case IRQ_KEYPAD:
+		mask = ADXER_WKP;
+		break;
+	case IRQ_AC97:
+		mask = ADXER_MFP_WAC97;
+		break;
+	case IRQ_USIM:
+		mask = ADXER_WUSIM0;
+		break;
+	case IRQ_SSP2:
+		mask = ADXER_MFP_WSSP2;
+		break;
+	case IRQ_I2C:
+		mask = ADXER_MFP_WI2C;
+		break;
+	case IRQ_STUART:
+		mask = ADXER_MFP_WUART3;
+		break;
+	case IRQ_BTUART:
+		mask = ADXER_MFP_WUART2;
+		break;
+	case IRQ_FFUART:
+		mask = ADXER_MFP_WUART1;
+		break;
+	case IRQ_MMC:
+		mask = ADXER_MFP_WMMC1;
+		break;
+	case IRQ_SSP:
+		mask = ADXER_MFP_WSSP1;
+		break;
+	case IRQ_RTCAlrm:
+		mask = ADXER_WRTC;
+		break;
+	case IRQ_SSP4:
+		mask = ADXER_MFP_WSSP4;
+		break;
+	case IRQ_TSI:
+		mask = ADXER_WTSI;
+		break;
+	case IRQ_USIM2:
+		mask = ADXER_WUSIM1;
+		break;
+	case IRQ_MMC2:
+		mask = ADXER_MFP_WMMC2;
+		break;
+	case IRQ_NAND:
+		mask = ADXER_MFP_WFLASH;
+		break;
+	case IRQ_USB2:
+		mask = ADXER_WUSB2;
+		break;
+	case IRQ_WAKEUP0:
+		mask = ADXER_WEXTWAKE0;
+		break;
+	case IRQ_WAKEUP1:
+		mask = ADXER_WEXTWAKE1;
+		break;
+	case IRQ_MMC3:
+		mask = ADXER_MFP_GEN12;
+		break;
+	}
+
+	local_irq_save(flags);
+	if (on)
+		wakeup_src |= mask;
+	else
+		wakeup_src &= ~mask;
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static void pxa3xx_init_irq_pm(void)
+{
+	pxa_init_irq_set_wake(pxa3xx_set_wake);
+}
+
+#else
+static inline void pxa3xx_init_pm(void) {}
+static inline void pxa3xx_init_irq_pm(void) {}
+#endif
+
 void __init pxa3xx_init_irq(void)
 {
 	/* enable CP6 access */
@@ -202,6 +432,7 @@
 	pxa_init_irq_low();
 	pxa_init_irq_high();
 	pxa_init_irq_gpio(128);
+	pxa3xx_init_irq_pm();
 }
 
 /*
@@ -209,16 +440,16 @@
  */
 
 static struct platform_device *devices[] __initdata = {
-	&pxa_device_mci,
 	&pxa_device_udc,
-	&pxa_device_fb,
 	&pxa_device_ffuart,
 	&pxa_device_btuart,
 	&pxa_device_stuart,
-	&pxa_device_i2c,
 	&pxa_device_i2s,
-	&pxa_device_ficp,
 	&pxa_device_rtc,
+	&pxa27x_device_ssp1,
+	&pxa27x_device_ssp2,
+	&pxa27x_device_ssp3,
+	&pxa3xx_device_ssp4,
 };
 
 static int __init pxa3xx_init(void)
@@ -231,6 +462,8 @@
 		if ((ret = pxa_init_dma(32)))
 			return ret;
 
+		pxa3xx_init_pm();
+
 		return platform_add_devices(devices, ARRAY_SIZE(devices));
 	}
 	return 0;
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index da4769c..047909a 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -26,28 +26,15 @@
 
 
 /*
- * SharpSL Backlight
+ * SharpSL/Corgi LCD Driver
  */
-void corgi_bl_set_intensity(int intensity);
-void spitz_bl_set_intensity(int intensity);
-void akita_bl_set_intensity(int intensity);
-
-
-/*
- * SharpSL Touchscreen Driver
- */
-unsigned long corgi_get_hsync_len(void);
-unsigned long spitz_get_hsync_len(void);
-void corgi_put_hsync(void);
-void spitz_put_hsync(void);
-void corgi_wait_hsync(void);
-void spitz_wait_hsync(void);
+void corgi_lcdtg_suspend(void);
+void corgi_lcdtg_hw_init(int mode);
 
 
 /*
  * SharpSL Battery/PM Driver
  */
-
 #define READ_GPIO_BIT(x)    (GPLR(x) & GPIO_bit(x))
 
 /* MAX1111 Channel Definitions */
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index d044772..14bb4a9 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -16,6 +16,7 @@
 #include <asm/hardware.h>
 
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
 
 #define MDREFR_KDIV	0x200a4000	// all banks
 #define CCCR_SLEEP	0x00000107	// L=7 2N=2 A=0 PPDIS=0 CPDIS=0
@@ -49,6 +50,7 @@
 	str	r0, [r1]
 	ldr	pc, [sp], #4
 
+#ifdef CONFIG_PXA27x
 /*
  * pxa27x_cpu_suspend()
  *
@@ -104,9 +106,11 @@
 
 	@ align execution to a cache line
 	b	pxa_cpu_do_suspend
+#endif
 
+#ifdef CONFIG_PXA25x
 /*
- * pxa27x_cpu_suspend()
+ * pxa25x_cpu_suspend()
  *
  * Forces CPU into sleep state.
  *
@@ -169,6 +173,7 @@
 	mcr	p14, 0, r0, c6, c0, 0
 	orr	r0, r0, #2			@ initiate change bit
 	b	pxa_cpu_do_suspend
+#endif
 
 	.ltorg
 	.align	5
@@ -208,7 +213,7 @@
 20:	b	20b				@ loop waiting for sleep
 
 /*
- * cpu_pxa_resume()
+ * pxa_cpu_resume()
  *
  * entry point from bootloader into kernel during resume
  *
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 2d78199..5078ede 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -271,6 +271,55 @@
 /*
  * Spitz Touch Screen Device
  */
+
+static unsigned long (*get_hsync_invperiod)(struct device *dev);
+
+static void inline sharpsl_wait_sync(int gpio)
+{
+	while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
+	while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
+}
+
+static struct device *spitz_pxafb_dev;
+
+static int is_pxafb_device(struct device * dev, void * data)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
+
+	return (strncmp(pdev->name, "pxa2xx-fb", 9) == 0);
+}
+
+static unsigned long spitz_get_hsync_invperiod(void)
+{
+#ifdef CONFIG_FB_PXA
+	if (!spitz_pxafb_dev) {
+		spitz_pxafb_dev = bus_find_device(&platform_bus_type, NULL, NULL, is_pxafb_device);
+		if (!spitz_pxafb_dev)
+			return 0;
+	}
+	if (!get_hsync_invperiod)
+		get_hsync_invperiod = symbol_get(pxafb_get_hsync_time);
+	if (!get_hsync_invperiod)
+#endif
+		return 0;
+
+	return get_hsync_invperiod(spitz_pxafb_dev);
+}
+
+static void spitz_put_hsync(void)
+{
+	put_device(spitz_pxafb_dev);
+	if (get_hsync_invperiod)
+		symbol_put(pxafb_get_hsync_time);
+	spitz_pxafb_dev = NULL;
+	get_hsync_invperiod = NULL;
+}
+
+static void spitz_wait_hsync(void)
+{
+	sharpsl_wait_sync(SPITZ_GPIO_HSYNC);
+}
+
 static struct resource spitzts_resources[] = {
 	[0] = {
 		.start		= SPITZ_IRQ_GPIO_TP_INT,
@@ -280,9 +329,9 @@
 };
 
 static struct corgits_machinfo  spitz_ts_machinfo = {
-	.get_hsync_len   = spitz_get_hsync_len,
-	.put_hsync       = spitz_put_hsync,
-	.wait_hsync      = spitz_wait_hsync,
+	.get_hsync_invperiod = spitz_get_hsync_invperiod,
+	.put_hsync           = spitz_put_hsync,
+	.wait_hsync          = spitz_wait_hsync,
 };
 
 static struct platform_device spitzts_device = {
@@ -325,12 +374,10 @@
 	err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int,
 			  IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 			  "MMC card detect", data);
-	if (err) {
+	if (err)
 		printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
-		return -1;
-	}
 
-	return 0;
+	return err;
 }
 
 static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
@@ -423,6 +470,14 @@
  * Spitz PXA Framebuffer
  */
 
+static void spitz_lcd_power(int on, struct fb_var_screeninfo *var)
+{
+	if (on)
+		corgi_lcdtg_hw_init(var->xres);
+	else
+		corgi_lcdtg_suspend();
+}
+
 static struct pxafb_mode_info spitz_pxafb_modes[] = {
 {
 	.pixclock       = 19231,
@@ -520,6 +575,27 @@
 	set_pxa_fb_info(&spitz_pxafb_info);
 }
 
+#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
+static void spitz_bl_set_intensity(int intensity)
+{
+	if (intensity > 0x10)
+		intensity += 0x10;
+
+	/* Bits 0-4 are accessed via the SSP interface */
+	corgi_ssp_blduty_set(intensity & 0x1f);
+
+	/* Bit 5 is via SCOOP */
+	if (intensity & 0x0020)
+		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
+	else
+		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
+
+	if (intensity)
+		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
+	else
+		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
+}
+
 static void __init spitz_init(void)
 {
 	platform_scoop_config = &spitz_pcmcia_config;
@@ -530,6 +606,7 @@
 
 	platform_device_register(&spitzscoop2_device);
 }
+#endif
 
 #ifdef CONFIG_MACH_AKITA
 /*
@@ -542,6 +619,26 @@
 
 EXPORT_SYMBOL_GPL(akitaioexp_device);
 
+static void akita_bl_set_intensity(int intensity)
+{
+	if (intensity > 0x10)
+		intensity += 0x10;
+
+	/* Bits 0-4 are accessed via the SSP interface */
+	corgi_ssp_blduty_set(intensity & 0x1f);
+
+	/* Bit 5 is via IO-Expander */
+	if (intensity & 0x0020)
+		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
+	else
+		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
+
+	if (intensity)
+		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
+	else
+		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
+}
+
 static void __init akita_init(void)
 {
 	spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
@@ -558,7 +655,6 @@
 }
 #endif
 
-
 static void __init fixup_spitz(struct machine_desc *desc,
 		struct tag *tags, char **cmdline, struct meminfo *mi)
 {
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 422afee..00af7f2 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -32,45 +32,27 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/hardware.h>
 #include <asm/arch/ssp.h>
 #include <asm/arch/pxa-regs.h>
-
-#define PXA_SSP_PORTS 	3
+#include <asm/arch/regs-ssp.h>
 
 #define TIMEOUT 100000
 
-struct ssp_info_ {
-	int irq;
-	u32 clock;
-};
-
-/*
- * SSP port clock and IRQ settings
- */
-static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
-#if defined (CONFIG_PXA27x)
-	{IRQ_SSP,	CKEN_SSP1},
-	{IRQ_SSP2,	CKEN_SSP2},
-	{IRQ_SSP3,	CKEN_SSP3},
-#else
-	{IRQ_SSP,	CKEN_SSP},
-	{IRQ_NSSP,	CKEN_NSSP},
-	{IRQ_ASSP,	CKEN_ASSP},
-#endif
-};
-
-static DEFINE_MUTEX(mutex);
-static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
-
 static irqreturn_t ssp_interrupt(int irq, void *dev_id)
 {
-	struct ssp_dev *dev = (struct ssp_dev*) dev_id;
-	unsigned int status = SSSR_P(dev->port);
+	struct ssp_dev *dev = dev_id;
+	struct ssp_device *ssp = dev->ssp;
+	unsigned int status;
 
-	SSSR_P(dev->port) = status; /* clear status bits */
+	status = __raw_readl(ssp->mmio_base + SSSR);
+	__raw_writel(status, ssp->mmio_base + SSSR);
 
 	if (status & SSSR_ROR)
 		printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port);
@@ -99,15 +81,16 @@
  */
 int ssp_write_word(struct ssp_dev *dev, u32 data)
 {
+	struct ssp_device *ssp = dev->ssp;
 	int timeout = TIMEOUT;
 
-	while (!(SSSR_P(dev->port) & SSSR_TNF)) {
+	while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_TNF)) {
 	        if (!--timeout)
 	        	return -ETIMEDOUT;
 		cpu_relax();
 	}
 
-	SSDR_P(dev->port) = data;
+	__raw_writel(data, ssp->mmio_base + SSDR);
 
 	return 0;
 }
@@ -129,15 +112,16 @@
  */
 int ssp_read_word(struct ssp_dev *dev, u32 *data)
 {
+	struct ssp_device *ssp = dev->ssp;
 	int timeout = TIMEOUT;
 
-	while (!(SSSR_P(dev->port) & SSSR_RNE)) {
+	while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE)) {
 	        if (!--timeout)
 	        	return -ETIMEDOUT;
 		cpu_relax();
 	}
 
-	*data = SSDR_P(dev->port);
+	*data = __raw_readl(ssp->mmio_base + SSDR);
 	return 0;
 }
 
@@ -151,17 +135,28 @@
  */
 int ssp_flush(struct ssp_dev *dev)
 {
+	struct ssp_device *ssp = dev->ssp;
 	int timeout = TIMEOUT * 2;
 
+	/* ensure TX FIFO is empty instead of not full */
+	if (cpu_is_pxa3xx()) {
+		while (__raw_readl(ssp->mmio_base + SSSR) & 0xf00) {
+			if (!--timeout)
+				return -ETIMEDOUT;
+			cpu_relax();
+		}
+		timeout = TIMEOUT * 2;
+	}
+
 	do {
-		while (SSSR_P(dev->port) & SSSR_RNE) {
+		while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE) {
 		        if (!--timeout)
 		        	return -ETIMEDOUT;
-			(void) SSDR_P(dev->port);
+			(void)__raw_readl(ssp->mmio_base + SSDR);
 		}
 	        if (!--timeout)
 	        	return -ETIMEDOUT;
-	} while (SSSR_P(dev->port) & SSSR_BSY);
+	} while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_BSY);
 
 	return 0;
 }
@@ -173,7 +168,12 @@
  */
 void ssp_enable(struct ssp_dev *dev)
 {
-	SSCR0_P(dev->port) |= SSCR0_SSE;
+	struct ssp_device *ssp = dev->ssp;
+	uint32_t sscr0;
+
+	sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
+	sscr0 |= SSCR0_SSE;
+	__raw_writel(sscr0, ssp->mmio_base + SSCR0);
 }
 
 /**
@@ -183,7 +183,12 @@
  */
 void ssp_disable(struct ssp_dev *dev)
 {
-	SSCR0_P(dev->port) &= ~SSCR0_SSE;
+	struct ssp_device *ssp = dev->ssp;
+	uint32_t sscr0;
+
+	sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
+	sscr0 &= ~SSCR0_SSE;
+	__raw_writel(sscr0, ssp->mmio_base + SSCR0);
 }
 
 /**
@@ -192,14 +197,16 @@
  *
  * Save the configured SSP state for suspend.
  */
-void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp)
+void ssp_save_state(struct ssp_dev *dev, struct ssp_state *state)
 {
-	ssp->cr0 = SSCR0_P(dev->port);
-	ssp->cr1 = SSCR1_P(dev->port);
-	ssp->to = SSTO_P(dev->port);
-	ssp->psp = SSPSP_P(dev->port);
+	struct ssp_device *ssp = dev->ssp;
 
-	SSCR0_P(dev->port) &= ~SSCR0_SSE;
+	state->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
+	state->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
+	state->to  = __raw_readl(ssp->mmio_base + SSTO);
+	state->psp = __raw_readl(ssp->mmio_base + SSPSP);
+
+	ssp_disable(dev);
 }
 
 /**
@@ -208,16 +215,18 @@
  *
  * Restore the SSP configuration saved previously by ssp_save_state.
  */
-void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp)
+void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *state)
 {
-	SSSR_P(dev->port) = SSSR_ROR | SSSR_TUR | SSSR_BCE;
+	struct ssp_device *ssp = dev->ssp;
+	uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
 
-	SSCR0_P(dev->port) = ssp->cr0 & ~SSCR0_SSE;
-	SSCR1_P(dev->port) = ssp->cr1;
-	SSTO_P(dev->port) = ssp->to;
-	SSPSP_P(dev->port) = ssp->psp;
+	__raw_writel(sssr, ssp->mmio_base + SSSR);
 
-	SSCR0_P(dev->port) = ssp->cr0;
+	__raw_writel(state->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
+	__raw_writel(state->cr1, ssp->mmio_base + SSCR1);
+	__raw_writel(state->to,  ssp->mmio_base + SSTO);
+	__raw_writel(state->psp, ssp->mmio_base + SSPSP);
+	__raw_writel(state->cr0, ssp->mmio_base + SSCR0);
 }
 
 /**
@@ -231,15 +240,17 @@
  */
 int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed)
 {
+	struct ssp_device *ssp = dev->ssp;
+
 	dev->mode = mode;
 	dev->flags = flags;
 	dev->psp_flags = psp_flags;
 	dev->speed = speed;
 
 	/* set up port type, speed, port settings */
-	SSCR0_P(dev->port) = (dev->speed | dev->mode);
-	SSCR1_P(dev->port) = dev->flags;
-	SSPSP_P(dev->port) = dev->psp_flags;
+	__raw_writel((dev->speed | dev->mode), ssp->mmio_base + SSCR0);
+	__raw_writel(dev->flags, ssp->mmio_base + SSCR1);
+	__raw_writel(dev->psp_flags, ssp->mmio_base + SSPSP);
 
 	return 0;
 }
@@ -256,44 +267,32 @@
  */
 int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
 {
+	struct ssp_device *ssp;
 	int ret;
 
-	if (port > PXA_SSP_PORTS || port == 0)
+	ssp = ssp_request(port, "SSP");
+	if (ssp == NULL)
 		return -ENODEV;
 
-	mutex_lock(&mutex);
-	if (use_count[port - 1]) {
-		mutex_unlock(&mutex);
-		return -EBUSY;
-	}
-	use_count[port - 1]++;
-
-	if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) {
-		use_count[port - 1]--;
-		mutex_unlock(&mutex);
-		return -EBUSY;
-	}
+	dev->ssp = ssp;
 	dev->port = port;
 
 	/* do we need to get irq */
 	if (!(init_flags & SSP_NO_IRQ)) {
-		ret = request_irq(ssp_info[port-1].irq, ssp_interrupt,
+		ret = request_irq(ssp->irq, ssp_interrupt,
 				0, "SSP", dev);
 	    	if (ret)
 			goto out_region;
-	    	dev->irq = ssp_info[port-1].irq;
+		dev->irq = ssp->irq;
 	} else
 		dev->irq = 0;
 
 	/* turn on SSP port clock */
-	pxa_set_cken(ssp_info[port-1].clock, 1);
-	mutex_unlock(&mutex);
+	clk_enable(ssp->clk);
 	return 0;
 
 out_region:
-	release_mem_region(__PREG(SSCR0_P(port)), 0x2c);
-	use_count[port - 1]--;
-	mutex_unlock(&mutex);
+	ssp_free(ssp);
 	return ret;
 }
 
@@ -304,22 +303,239 @@
  */
 void ssp_exit(struct ssp_dev *dev)
 {
-	mutex_lock(&mutex);
-	SSCR0_P(dev->port) &= ~SSCR0_SSE;
+	struct ssp_device *ssp = dev->ssp;
 
-    	if (dev->port > PXA_SSP_PORTS || dev->port == 0) {
-		printk(KERN_WARNING "SSP: tried to close invalid port\n");
-		mutex_unlock(&mutex);
-		return;
+	ssp_disable(dev);
+	free_irq(dev->irq, dev);
+	clk_disable(ssp->clk);
+	ssp_free(ssp);
+}
+
+static DEFINE_MUTEX(ssp_lock);
+static LIST_HEAD(ssp_list);
+
+struct ssp_device *ssp_request(int port, const char *label)
+{
+	struct ssp_device *ssp = NULL;
+
+	mutex_lock(&ssp_lock);
+
+	list_for_each_entry(ssp, &ssp_list, node) {
+		if (ssp->port_id == port && ssp->use_count == 0) {
+			ssp->use_count++;
+			ssp->label = label;
+			break;
+		}
 	}
 
-	pxa_set_cken(ssp_info[dev->port-1].clock, 0);
-	if (dev->irq)
-		free_irq(dev->irq, dev);
-	release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
-	use_count[dev->port - 1]--;
-	mutex_unlock(&mutex);
+	mutex_unlock(&ssp_lock);
+
+	if (ssp->port_id != port)
+		return NULL;
+
+	return ssp;
 }
+EXPORT_SYMBOL(ssp_request);
+
+void ssp_free(struct ssp_device *ssp)
+{
+	mutex_lock(&ssp_lock);
+	if (ssp->use_count) {
+		ssp->use_count--;
+		ssp->label = NULL;
+	} else
+		dev_err(&ssp->pdev->dev, "device already free\n");
+	mutex_unlock(&ssp_lock);
+}
+EXPORT_SYMBOL(ssp_free);
+
+static int __devinit ssp_probe(struct platform_device *pdev, int type)
+{
+	struct resource *res;
+	struct ssp_device *ssp;
+	int ret = 0;
+
+	ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL);
+	if (ssp == NULL) {
+		dev_err(&pdev->dev, "failed to allocate memory");
+		return -ENOMEM;
+	}
+
+	ssp->clk = clk_get(&pdev->dev, "SSPCLK");
+	if (IS_ERR(ssp->clk)) {
+		ret = PTR_ERR(ssp->clk);
+		goto err_free;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no memory resource defined\n");
+		ret = -ENODEV;
+		goto err_free_clk;
+	}
+
+	res = request_mem_region(res->start, res->end - res->start + 1,
+			pdev->name);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to request memory resource\n");
+		ret = -EBUSY;
+		goto err_free_clk;
+	}
+
+	ssp->phys_base = res->start;
+
+	ssp->mmio_base = ioremap(res->start, res->end - res->start + 1);
+	if (ssp->mmio_base == NULL) {
+		dev_err(&pdev->dev, "failed to ioremap() registers\n");
+		ret = -ENODEV;
+		goto err_free_mem;
+	}
+
+	ssp->irq = platform_get_irq(pdev, 0);
+	if (ssp->irq < 0) {
+		dev_err(&pdev->dev, "no IRQ resource defined\n");
+		ret = -ENODEV;
+		goto err_free_io;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no SSP RX DRCMR defined\n");
+		ret = -ENODEV;
+		goto err_free_io;
+	}
+	ssp->drcmr_rx = res->start;
+
+	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no SSP TX DRCMR defined\n");
+		ret = -ENODEV;
+		goto err_free_io;
+	}
+	ssp->drcmr_tx = res->start;
+
+	/* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
+	 * starts from 0, do a translation here
+	 */
+	ssp->port_id = pdev->id + 1;
+	ssp->use_count = 0;
+	ssp->type = type;
+
+	mutex_lock(&ssp_lock);
+	list_add(&ssp->node, &ssp_list);
+	mutex_unlock(&ssp_lock);
+
+	platform_set_drvdata(pdev, ssp);
+	return 0;
+
+err_free_io:
+	iounmap(ssp->mmio_base);
+err_free_mem:
+	release_mem_region(res->start, res->end - res->start + 1);
+err_free_clk:
+	clk_put(ssp->clk);
+err_free:
+	kfree(ssp);
+	return ret;
+}
+
+static int __devexit ssp_remove(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct ssp_device *ssp;
+
+	ssp = platform_get_drvdata(pdev);
+	if (ssp == NULL)
+		return -ENODEV;
+
+	iounmap(ssp->mmio_base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, res->end - res->start + 1);
+
+	clk_put(ssp->clk);
+
+	mutex_lock(&ssp_lock);
+	list_del(&ssp->node);
+	mutex_unlock(&ssp_lock);
+
+	kfree(ssp);
+	return 0;
+}
+
+static int __devinit pxa25x_ssp_probe(struct platform_device *pdev)
+{
+	return ssp_probe(pdev, PXA25x_SSP);
+}
+
+static int __devinit pxa25x_nssp_probe(struct platform_device *pdev)
+{
+	return ssp_probe(pdev, PXA25x_NSSP);
+}
+
+static int __devinit pxa27x_ssp_probe(struct platform_device *pdev)
+{
+	return ssp_probe(pdev, PXA27x_SSP);
+}
+
+static struct platform_driver pxa25x_ssp_driver = {
+	.driver		= {
+		.name	= "pxa25x-ssp",
+	},
+	.probe		= pxa25x_ssp_probe,
+	.remove		= __devexit_p(ssp_remove),
+};
+
+static struct platform_driver pxa25x_nssp_driver = {
+	.driver		= {
+		.name	= "pxa25x-nssp",
+	},
+	.probe		= pxa25x_nssp_probe,
+	.remove		= __devexit_p(ssp_remove),
+};
+
+static struct platform_driver pxa27x_ssp_driver = {
+	.driver		= {
+		.name	= "pxa27x-ssp",
+	},
+	.probe		= pxa27x_ssp_probe,
+	.remove		= __devexit_p(ssp_remove),
+};
+
+static int __init pxa_ssp_init(void)
+{
+	int ret = 0;
+
+	ret = platform_driver_register(&pxa25x_ssp_driver);
+	if (ret) {
+		printk(KERN_ERR "failed to register pxa25x_ssp_driver");
+		return ret;
+	}
+
+	ret = platform_driver_register(&pxa25x_nssp_driver);
+	if (ret) {
+		printk(KERN_ERR "failed to register pxa25x_nssp_driver");
+		return ret;
+	}
+
+	ret = platform_driver_register(&pxa27x_ssp_driver);
+	if (ret) {
+		printk(KERN_ERR "failed to register pxa27x_ssp_driver");
+		return ret;
+	}
+
+	return ret;
+}
+
+static void __exit pxa_ssp_exit(void)
+{
+	platform_driver_unregister(&pxa25x_ssp_driver);
+	platform_driver_unregister(&pxa25x_nssp_driver);
+	platform_driver_unregister(&pxa27x_ssp_driver);
+}
+
+arch_initcall(pxa_ssp_init);
+module_exit(pxa_ssp_exit);
 
 EXPORT_SYMBOL(ssp_write_word);
 EXPORT_SYMBOL(ssp_read_word);
diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
index d774430..167412e 100644
--- a/arch/arm/mach-pxa/standby.S
+++ b/arch/arm/mach-pxa/standby.S
@@ -17,6 +17,7 @@
 
 		.text
 
+#ifdef CONFIG_PXA27x
 ENTRY(pxa_cpu_standby)
 	ldr	r0, =PSSR
 	mov	r1, #(PSSR_PH | PSSR_STS)
@@ -29,3 +30,85 @@
 1:	mcr	p14, 0, r2, c7, c0, 0	@ put the system into Standby
 	str	r1, [r0]		@ make sure PSSR_PH/STS are clear
 	mov	pc, lr
+
+#endif
+
+#ifdef CONFIG_PXA3xx
+
+#define MDCNFG		0x0000
+#define MDCNFG_DMCEN	(1 << 30)
+#define DDR_HCAL	0x0060
+#define DDR_HCAL_HCRNG	0x1f
+#define DDR_HCAL_HCPROG	(1 << 28)
+#define DDR_HCAL_HCEN	(1 << 31)
+#define DMCIER		0x0070
+#define DMCIER_EDLP	(1 << 29)
+#define DMCISR		0x0078
+#define RCOMP		0x0100
+#define RCOMP_SWEVAL	(1 << 31)
+
+ENTRY(pm_enter_standby_start)
+	mov	r1, #0xf6000000		@ DMEMC_REG_BASE (MDCNFG)
+	add	r1, r1, #0x00100000
+
+	/*
+	 * Preload the TLB entry for accessing the dynamic memory
+	 * controller registers.  Note that page table lookups will
+	 * fail until the dynamic memory controller has been
+	 * reinitialised - and that includes MMU page table walks.
+	 * This also means that only the dynamic memory controller
+	 * can be reliably accessed in the code following standby.
+	 */
+	ldr	r2, [r1]		@ Dummy read MDCNFG
+
+	mcr	p14, 0, r0, c7, c0, 0
+	.rept	8
+	nop
+	.endr
+
+	ldr	r0, [r1, #DDR_HCAL]	@ Clear (and wait for) HCEN
+	bic	r0, r0, #DDR_HCAL_HCEN
+	str	r0, [r1, #DDR_HCAL]
+1:	ldr	r0, [r1, #DDR_HCAL]
+	tst	r0, #DDR_HCAL_HCEN
+	bne	1b
+
+	ldr	r0, [r1, #RCOMP]	@ Initiate RCOMP
+	orr	r0, r0, #RCOMP_SWEVAL
+	str	r0, [r1, #RCOMP]
+
+	mov	r0, #~0			@ Clear interrupts
+	str	r0, [r1, #DMCISR]
+
+	ldr	r0, [r1, #DMCIER]	@ set DMIER[EDLP]
+	orr	r0, r0, #DMCIER_EDLP
+	str	r0, [r1, #DMCIER]
+
+	ldr	r0, [r1, #DDR_HCAL]	@ clear HCRNG, set HCPROG, HCEN
+	bic	r0, r0, #DDR_HCAL_HCRNG
+	orr	r0, r0, #DDR_HCAL_HCEN | DDR_HCAL_HCPROG
+	str	r0, [r1, #DDR_HCAL]
+
+1:	ldr	r0, [r1, #DMCISR]
+	tst	r0, #DMCIER_EDLP
+	beq	1b
+
+	ldr	r0, [r1, #MDCNFG]	@ set MDCNFG[DMCEN]
+	orr	r0, r0, #MDCNFG_DMCEN
+	str	r0, [r1, #MDCNFG]
+1:	ldr	r0, [r1, #MDCNFG]
+	tst	r0, #MDCNFG_DMCEN
+	beq	1b
+
+	ldr	r0, [r1, #DDR_HCAL]	@ set DDR_HCAL[HCRNG]
+	orr	r0, r0, #2 @ HCRNG
+	str	r0, [r1, #DDR_HCAL]
+
+	ldr	r0, [r1, #DMCIER]	@ Clear the interrupt
+	bic	r0, r0, #0x20000000
+	str	r0, [r1, #DMCIER]
+
+	mov	pc, lr
+ENTRY(pm_enter_standby_end)
+
+#endif
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index fbfa192..7b7c0179 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -59,55 +59,17 @@
 }
 
 
+#define MIN_OSCR_DELTA 16
+
 static irqreturn_t
 pxa_ost0_interrupt(int irq, void *dev_id)
 {
-	int next_match;
 	struct clock_event_device *c = dev_id;
 
-	if (c->mode == CLOCK_EVT_MODE_ONESHOT) {
-		/* Disarm the compare/match, signal the event. */
-		OIER &= ~OIER_E0;
-		OSSR = OSSR_M0;
-		c->event_handler(c);
-	} else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
-		/* Call the event handler as many times as necessary
-		 * to recover missed events, if any (if we update
-		 * OSMR0 and OSCR0 is still ahead of us, we've missed
-		 * the event).  As we're dealing with that, re-arm the
-		 * compare/match for the next event.
-		 *
-		 * HACK ALERT:
-		 *
-		 * There's a latency between the instruction that
-		 * writes to OSMR0 and the actual commit to the
-		 * physical hardware, because the CPU doesn't (have
-		 * to) run at bus speed, there's a write buffer
-		 * between the CPU and the bus, etc. etc.  So if the
-		 * target OSCR0 is "very close", to the OSMR0 load
-		 * value, the update to OSMR0 might not get to the
-		 * hardware in time and we'll miss that interrupt.
-		 *
-		 * To be safe, if the new OSMR0 is "very close" to the
-		 * target OSCR0 value, we call the event_handler as
-		 * though the event actually happened.  According to
-		 * Nico's comment in the previous version of this
-		 * code, experience has shown that 6 OSCR ticks is
-		 * "very close" but he went with 8.  We will use 16,
-		 * based on the results of testing on PXA270.
-		 *
-		 * To be doubly sure, we also tell clkevt via
-		 * clockevents_register_device() not to ask for
-		 * anything that might put us "very close".
-	 */
-#define MIN_OSCR_DELTA 16
-		do {
-			OSSR = OSSR_M0;
-			next_match = (OSMR0 += LATCH);
-			c->event_handler(c);
-		} while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
-			 && (c->mode == CLOCK_EVT_MODE_PERIODIC));
-	}
+	/* Disarm the compare/match, signal the event. */
+	OIER &= ~OIER_E0;
+	OSSR = OSSR_M0;
+	c->event_handler(c);
 
 	return IRQ_HANDLED;
 }
@@ -133,14 +95,6 @@
 	unsigned long irqflags;
 
 	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		raw_local_irq_save(irqflags);
-		OSSR = OSSR_M0;
-		OIER |= OIER_E0;
-		OSMR0 = OSCR + LATCH;
-		raw_local_irq_restore(irqflags);
-		break;
-
 	case CLOCK_EVT_MODE_ONESHOT:
 		raw_local_irq_save(irqflags);
 		OIER &= ~OIER_E0;
@@ -158,13 +112,14 @@
 		break;
 
 	case CLOCK_EVT_MODE_RESUME:
+	case CLOCK_EVT_MODE_PERIODIC:
 		break;
 	}
 }
 
 static struct clock_event_device ckevt_pxa_osmr0 = {
 	.name		= "osmr0",
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
 	.shift		= 32,
 	.rating		= 200,
 	.cpumask	= CPU_MASK_CPU0,
@@ -214,7 +169,7 @@
 	ckevt_pxa_osmr0.max_delta_ns =
 		clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
 	ckevt_pxa_osmr0.min_delta_ns =
-		clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1;
+		clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1;
 
 	cksrc_pxa_oscr0.mult =
 		clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift);
@@ -226,7 +181,7 @@
 }
 
 #ifdef CONFIG_PM
-static unsigned long osmr[4], oier;
+static unsigned long osmr[4], oier, oscr;
 
 static void pxa_timer_suspend(void)
 {
@@ -235,23 +190,26 @@
 	osmr[2] = OSMR2;
 	osmr[3] = OSMR3;
 	oier = OIER;
+	oscr = OSCR;
 }
 
 static void pxa_timer_resume(void)
 {
+	/*
+	 * Ensure that we have at least MIN_OSCR_DELTA between match
+	 * register 0 and the OSCR, to guarantee that we will receive
+	 * the one-shot timer interrupt.  We adjust OSMR0 in preference
+	 * to OSCR to guarantee that OSCR is monotonically incrementing.
+	 */
+	if (osmr[0] - oscr < MIN_OSCR_DELTA)
+		osmr[0] += MIN_OSCR_DELTA;
+
 	OSMR0 = osmr[0];
 	OSMR1 = osmr[1];
 	OSMR2 = osmr[2];
 	OSMR3 = osmr[3];
 	OIER = oier;
-
-	/*
-	 * OSCR0 is the system timer, which has to increase
-	 * monotonically until it rolls over in hardware.  The value
-	 * (OSMR0 - LATCH) is OSCR0 at the most recent system tick,
-	 * which is a handy value to restore to OSCR0.
-	 */
-	OSCR = OSMR0 - LATCH;
+	OSCR = oscr;
 }
 #else
 #define pxa_timer_suspend NULL
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 240fd04..1919756 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -184,16 +184,13 @@
 
 	tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
-	err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, IRQF_DISABLED,
+	err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int,
+			  IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				"MMC/SD card detect", data);
-	if (err) {
+	if (err)
 		printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
-		return -1;
-	}
 
-	set_irq_type(TOSA_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
-
-	return 0;
+	return err;
 }
 
 static void tosa_mci_setpower(struct device *dev, unsigned int vdd)
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index e4ba43b..853fc94 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -296,11 +296,10 @@
 	err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
 			  IRQF_DISABLED | IRQF_TRIGGER_RISING,
 			  "MMC card detect", data);
-	if (err) {
+	if (err)
 		printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
-		return -1;
-	}
-	return 0;
+
+	return err;
 }
 
 static void trizeps4_mci_exit(struct device *dev, void *data)
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 743a87b..7731d50 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -25,9 +25,13 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/pxafb.h>
 #include <asm/arch/zylonite.h>
+#include <asm/arch/mmc.h>
 
 #include "generic.h"
 
+#define MAX_SLOTS	3
+struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
+
 int gpio_backlight;
 int gpio_eth_irq;
 
@@ -43,7 +47,7 @@
 	[1] = {
 		.start	= -1,	/* for run-time assignment */
 		.end	= -1,
-		.flags	= IORESOURCE_IRQ,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	}
 };
 
@@ -156,6 +160,95 @@
 static inline void zylonite_init_lcd(void) {}
 #endif
 
+#if defined(CONFIG_MMC)
+static int zylonite_mci_ro(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp);
+}
+
+static int zylonite_mci_init(struct device *dev,
+			     irq_handler_t zylonite_detect_int,
+			     void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	int err, cd_irq, gpio_cd, gpio_wp;
+
+	cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
+	gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
+	gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
+
+	/*
+	 * setup GPIO for Zylonite MMC controller
+	 */
+	err = gpio_request(gpio_cd, "mmc card detect");
+	if (err)
+		goto err_request_cd;
+	gpio_direction_input(gpio_cd);
+
+	err = gpio_request(gpio_wp, "mmc write protect");
+	if (err)
+		goto err_request_wp;
+	gpio_direction_input(gpio_wp);
+
+	err = request_irq(cd_irq, zylonite_detect_int,
+			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			  "MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "%s: MMC/SD/SDIO: "
+				"can't request card detect IRQ\n", __func__);
+		goto err_request_irq;
+	}
+
+	return 0;
+
+err_request_irq:
+	gpio_free(gpio_wp);
+err_request_wp:
+	gpio_free(gpio_cd);
+err_request_cd:
+	return err;
+}
+
+static void zylonite_mci_exit(struct device *dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	int cd_irq, gpio_cd, gpio_wp;
+
+	cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
+	gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
+	gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
+
+	free_irq(cd_irq, data);
+	gpio_free(gpio_cd);
+	gpio_free(gpio_wp);
+}
+
+static struct pxamci_platform_data zylonite_mci_platform_data = {
+	.detect_delay	= 20,
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= zylonite_mci_init,
+	.exit		= zylonite_mci_exit,
+	.get_ro		= zylonite_mci_ro,
+};
+
+static struct pxamci_platform_data zylonite_mci2_platform_data = {
+	.detect_delay	= 20,
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+};
+
+static void __init zylonite_init_mmc(void)
+{
+	pxa_set_mci_info(&zylonite_mci_platform_data);
+	pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
+	if (cpu_is_pxa310())
+		pxa3xx_set_mci3_info(&zylonite_mci_platform_data);
+}
+#else
+static inline void zylonite_init_mmc(void) {}
+#endif
+
 static void __init zylonite_init(void)
 {
 	/* board-processor specific initialization */
@@ -171,6 +264,7 @@
 	platform_device_register(&smc91x_device);
 
 	zylonite_init_lcd();
+	zylonite_init_mmc();
 }
 
 MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index 1832bc3..6ac04c0 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -53,13 +53,13 @@
 
 	/* BTUART */
 	GPIO111_UART2_RTS,
-	GPIO112_UART2_RXD,
+	GPIO112_UART2_RXD | MFP_LPM_EDGE_FALL,
 	GPIO113_UART2_TXD,
-	GPIO114_UART2_CTS,
+	GPIO114_UART2_CTS | MFP_LPM_EDGE_BOTH,
 
 	/* STUART */
 	GPIO109_UART3_TXD,
-	GPIO110_UART3_RXD,
+	GPIO110_UART3_RXD | MFP_LPM_EDGE_FALL,
 
 	/* AC97 */
 	GPIO23_AC97_nACRESET,
@@ -70,16 +70,16 @@
 	GPIO28_AC97_SYNC,
 
 	/* Keypad */
-	GPIO107_KP_DKIN_0,
-	GPIO108_KP_DKIN_1,
-	GPIO115_KP_MKIN_0,
-	GPIO116_KP_MKIN_1,
-	GPIO117_KP_MKIN_2,
-	GPIO118_KP_MKIN_3,
-	GPIO119_KP_MKIN_4,
-	GPIO120_KP_MKIN_5,
-	GPIO2_2_KP_MKIN_6,
-	GPIO3_2_KP_MKIN_7,
+	GPIO107_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
+	GPIO108_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
+	GPIO115_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
+	GPIO116_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
+	GPIO117_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
+	GPIO118_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
+	GPIO119_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
+	GPIO120_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
+	GPIO2_2_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
+	GPIO3_2_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
 	GPIO121_KP_MKOUT_0,
 	GPIO122_KP_MKOUT_1,
 	GPIO123_KP_MKOUT_2,
@@ -88,16 +88,33 @@
 	GPIO4_2_KP_MKOUT_5,
 	GPIO5_2_KP_MKOUT_6,
 	GPIO6_2_KP_MKOUT_7,
+
+	/* MMC1 */
+	GPIO3_MMC1_DAT0,
+	GPIO4_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
+	GPIO5_MMC1_DAT2,
+	GPIO6_MMC1_DAT3,
+	GPIO7_MMC1_CLK,
+	GPIO8_MMC1_CMD,	/* CMD0 for slot 0 */
+	GPIO15_GPIO,	/* CMD1 default as GPIO for slot 0 */
+
+	/* MMC2 */
+	GPIO9_MMC2_DAT0,
+	GPIO10_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
+	GPIO11_MMC2_DAT2,
+	GPIO12_MMC2_DAT3,
+	GPIO13_MMC2_CLK,
+	GPIO14_MMC2_CMD,
 };
 
 static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
 	/* FFUART */
-	GPIO30_UART1_RXD,
+	GPIO30_UART1_RXD | MFP_LPM_EDGE_FALL,
 	GPIO31_UART1_TXD,
 	GPIO32_UART1_CTS,
 	GPIO37_UART1_RTS,
 	GPIO33_UART1_DCD,
-	GPIO34_UART1_DSR,
+	GPIO34_UART1_DSR | MFP_LPM_EDGE_FALL,
 	GPIO35_UART1_RI,
 	GPIO36_UART1_DTR,
 
@@ -108,7 +125,7 @@
 
 static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
 	/* FFUART */
-	GPIO99_UART1_RXD,
+	GPIO99_UART1_RXD | MFP_LPM_EDGE_FALL,
 	GPIO100_UART1_TXD,
 	GPIO101_UART1_CTS,
 	GPIO106_UART1_RTS,
@@ -116,6 +133,14 @@
 	/* Ethernet */
 	GPIO2_nCS3,
 	GPIO102_GPIO,
+
+	/* MMC3 */
+	GPIO7_2_MMC3_DAT0,
+	GPIO8_2_MMC3_DAT1 | MFP_LPM_EDGE_BOTH,
+	GPIO9_2_MMC3_DAT2,
+	GPIO10_2_MMC3_DAT3,
+	GPIO103_MMC3_CLK,
+	GPIO105_MMC3_CMD,
 };
 
 #define NUM_LCD_DETECT_PINS	7
@@ -174,6 +199,10 @@
 
 		/* GPIO pin assignment */
 		gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20);
+
+		/* MMC card detect & write protect for controller 0 */
+		zylonite_mmc_slot[0].gpio_cd  = EXT_GPIO(0);
+		zylonite_mmc_slot[0].gpio_wp  = EXT_GPIO(2);
 	}
 
 	if (cpu_is_pxa300()) {
@@ -184,5 +213,9 @@
 	if (cpu_is_pxa310()) {
 		pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg));
 		gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102);
+
+		/* MMC card detect & write protect for controller 2 */
+		zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30);
+		zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31);
 	}
 }
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
index 94c7158..dfa7999 100644
--- a/arch/arm/mach-pxa/zylonite_pxa320.c
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -51,11 +51,11 @@
 	GPIO17_2_LCD_BIAS,
 
 	/* FFUART */
-	GPIO41_UART1_RXD,
+	GPIO41_UART1_RXD | MFP_LPM_EDGE_FALL,
 	GPIO42_UART1_TXD,
 	GPIO43_UART1_CTS,
 	GPIO44_UART1_DCD,
-	GPIO45_UART1_DSR,
+	GPIO45_UART1_DSR | MFP_LPM_EDGE_FALL,
 	GPIO46_UART1_RI,
 	GPIO47_UART1_DTR,
 	GPIO48_UART1_RTS,
@@ -73,16 +73,16 @@
 	GPIO33_I2C_SDA,
 
 	/* Keypad */
-	GPIO105_KP_DKIN_0,
-	GPIO106_KP_DKIN_1,
-	GPIO113_KP_MKIN_0,
-	GPIO114_KP_MKIN_1,
-	GPIO115_KP_MKIN_2,
-	GPIO116_KP_MKIN_3,
-	GPIO117_KP_MKIN_4,
-	GPIO118_KP_MKIN_5,
-	GPIO119_KP_MKIN_6,
-	GPIO120_KP_MKIN_7,
+	GPIO105_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
+	GPIO106_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
+	GPIO113_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
+	GPIO114_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
+	GPIO115_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
+	GPIO116_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
+	GPIO117_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
+	GPIO118_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
+	GPIO119_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
+	GPIO120_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
 	GPIO121_KP_MKOUT_0,
 	GPIO122_KP_MKOUT_1,
 	GPIO123_KP_MKOUT_2,
@@ -95,6 +95,23 @@
 	/* Ethernet */
 	GPIO4_nCS3,
 	GPIO90_GPIO,
+
+	/* MMC1 */
+	GPIO18_MMC1_DAT0,
+	GPIO19_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
+	GPIO20_MMC1_DAT2,
+	GPIO21_MMC1_DAT3,
+	GPIO22_MMC1_CLK,
+	GPIO23_MMC1_CMD,/* CMD0 for slot 0 */
+	GPIO31_GPIO,	/* CMD1 default as GPIO for slot 0 */
+
+	/* MMC2 */
+	GPIO24_MMC2_DAT0,
+	GPIO25_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
+	GPIO26_MMC2_DAT2,
+	GPIO27_MMC2_DAT3,
+	GPIO28_MMC2_CLK,
+	GPIO29_MMC2_CMD,
 };
 
 #define NUM_LCD_DETECT_PINS	7
@@ -169,5 +186,9 @@
 		/* GPIO pin assignment */
 		gpio_backlight	= mfp_to_gpio(MFP_PIN_GPIO14);
 		gpio_eth_irq	= mfp_to_gpio(MFP_PIN_GPIO9);
+
+		/* MMC card detect & write protect for controller 0 */
+		zylonite_mmc_slot[0].gpio_cd  = mfp_to_gpio(MFP_PIN_GPIO1);
+		zylonite_mmc_slot[0].gpio_wp  = mfp_to_gpio(MFP_PIN_GPIO5);
 	}
 }
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index c7f1b44..61d7021 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -530,8 +530,6 @@
  */
 static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
-
 	// ...clear the interrupt
 	writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 
@@ -542,8 +540,6 @@
 	update_process_times(user_mode(get_irq_regs()));
 #endif
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 587864f..6617547 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -530,7 +530,7 @@
 
 	.displays = bast_lcd_info,
 	.num_displays = ARRAY_SIZE(bast_lcd_info),
-	.default_display = 4,
+	.default_display = 1,
 };
 
 /* Standard BAST devices */
@@ -540,7 +540,6 @@
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c,
-	&s3c_device_iis,
  	&s3c_device_rtc,
 	&s3c_device_nand,
 	&bast_device_nor,
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 9f43f3f..3aade7b 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -365,7 +365,6 @@
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c,
-	&s3c_device_iis,
 	&s3c_device_adc,
 	&serial_device,
 	&vr1000_nor,
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index bcd562a..6aec86a 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -60,7 +60,7 @@
 static irqreturn_t
 usb_simtec_ocirq(int irq, void *pw)
 {
-	struct s3c2410_hcd_info *info = (struct s3c2410_hcd_info *)pw;
+	struct s3c2410_hcd_info *info = pw;
 
 	if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) {
 		pr_debug("usb_simtec: over-current irq (oc detected)\n");
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 8e8fe48..0b43431 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -10,6 +10,7 @@
 	select CPU_LLSERIAL_S3C2440
 	select S3C2412_PM if PM
 	select S3C2412_DMA if S3C2410_DMA
+	select S3C2410_GPIO
 	help
 	  Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
 
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
index f8e0116..267f334 100644
--- a/arch/arm/mach-s3c2412/Makefile
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -12,8 +12,9 @@
 obj-$(CONFIG_CPU_S3C2412)	+= s3c2412.o
 obj-$(CONFIG_CPU_S3C2412)	+= irq.o
 obj-$(CONFIG_CPU_S3C2412)	+= clock.o
+obj-$(CONFIG_CPU_S3C2412)	+= gpio.o
 obj-$(CONFIG_S3C2412_DMA)	+= dma.o
-obj-$(CONFIG_S3C2412_PM)	+= pm.o
+obj-$(CONFIG_S3C2412_PM)	+= pm.o sleep.o
 
 # Machine support
 
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 4589936..2697a65 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -217,7 +217,7 @@
 
 	if (parent == &clk_mdivclk)
 		clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL;
-	else if (parent == &clk_upll)
+	else if (parent == &clk_mpll)
 		clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL;
 	else
 		return -EINVAL;
@@ -234,6 +234,45 @@
 	.set_parent	= s3c2412_setparent_msysclk,
 };
 
+static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+	unsigned long flags;
+	unsigned long clkdiv;
+	unsigned long dvs;
+
+	/* Note, we current equate fclk andf msysclk for S3C2412 */
+
+	if (parent == &clk_msysclk || parent == &clk_f)
+		dvs = 0;
+	else if (parent == &clk_h)
+		dvs = S3C2412_CLKDIVN_DVSEN;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	/* update this under irq lockdown, clkdivn is not protected
+	 * by the clock system. */
+
+	local_irq_save(flags);
+
+	clkdiv  = __raw_readl(S3C2410_CLKDIVN);
+	clkdiv &= ~S3C2412_CLKDIVN_DVSEN;
+	clkdiv |= dvs;
+	__raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static struct clk clk_armclk = {
+	.name		= "armclk",
+	.id		= -1,
+	.parent		= &clk_msysclk,
+	.set_parent	= s3c2412_setparent_armclk,
+};
+
 /* these next clocks have an divider immediately after them,
  * so we can register them with their divider and leave out the
  * intermediate clock stage
@@ -630,11 +669,13 @@
 	&clk_erefclk,
 	&clk_urefclk,
 	&clk_mrefclk,
+	&clk_armclk,
 };
 
 int __init s3c2412_baseclk_add(void)
 {
 	unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
+	unsigned int dvs;
 	struct clk *clkp;
 	int ret;
 	int ptr;
@@ -643,6 +684,8 @@
 	clk_usb_bus.parent = &clk_usbsrc;
 	clk_usb_bus.rate = 0x0;
 
+	clk_f.parent = &clk_msysclk;
+
 	s3c2412_clk_initparents();
 
 	for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
@@ -655,6 +698,15 @@
 		}
 	}
 
+	/* set the dvs state according to what we got at boot time */
+
+	dvs = __raw_readl(S3C2410_CLKDIVN) & S3C2412_CLKDIVN_DVSEN;
+
+	if (dvs)
+		clk_armclk.parent = &clk_h;
+
+	printk(KERN_INFO "S3C2412: DVS is %s\n", dvs ? "on" : "off");
+
 	/* ensure usb bus clock is within correct rate of 48MHz */
 
 	if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) {
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index 53c1d5bb..1dd8649 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -30,6 +30,7 @@
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-sdi.h>
+#include <asm/plat-s3c24xx/regs-s3c2412-iis.h>
 #include <asm/plat-s3c24xx/regs-iis.h>
 #include <asm/plat-s3c24xx/regs-spi.h>
 
@@ -39,106 +40,141 @@
 	[DMACH_XD0] = {
 		.name		= "xdreq0",
 		.channels	= MAP(S3C2412_DMAREQSEL_XDREQ0),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_XDREQ0),
 	},
 	[DMACH_XD1] = {
 		.name		= "xdreq1",
 		.channels	= MAP(S3C2412_DMAREQSEL_XDREQ1),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_XDREQ1),
 	},
 	[DMACH_SDI] = {
 		.name		= "sdi",
 		.channels	= MAP(S3C2412_DMAREQSEL_SDI),
-		.hw_addr.to	= S3C2410_PA_IIS + S3C2410_IISFIFO,
-		.hw_addr.from	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_SDI),
+		.hw_addr.to	= S3C2410_PA_SDI + S3C2410_SDIDATA,
+		.hw_addr.from	= S3C2410_PA_SDI + S3C2410_SDIDATA,
 	},
 	[DMACH_SPI0] = {
 		.name		= "spi0",
 		.channels	= MAP(S3C2412_DMAREQSEL_SPI0TX),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_SPI0RX),
 		.hw_addr.to	= S3C2410_PA_SPI + S3C2410_SPTDAT,
 		.hw_addr.from	= S3C2410_PA_SPI + S3C2410_SPRDAT,
 	},
 	[DMACH_SPI1] = {
 		.name		= "spi1",
 		.channels	= MAP(S3C2412_DMAREQSEL_SPI1TX),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_SPI1RX),
 		.hw_addr.to	= S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT,
 		.hw_addr.from	= S3C2410_PA_SPI + S3C2412_SPI1  + S3C2410_SPRDAT,
 	},
 	[DMACH_UART0] = {
 		.name		= "uart0",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART0_0),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART0_0),
 		.hw_addr.to	= S3C2410_PA_UART0 + S3C2410_UTXH,
 		.hw_addr.from	= S3C2410_PA_UART0 + S3C2410_URXH,
 	},
 	[DMACH_UART1] = {
 		.name		= "uart1",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART1_0),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART1_0),
 		.hw_addr.to	= S3C2410_PA_UART1 + S3C2410_UTXH,
 		.hw_addr.from	= S3C2410_PA_UART1 + S3C2410_URXH,
 	},
       	[DMACH_UART2] = {
 		.name		= "uart2",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART2_0),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART2_0),
 		.hw_addr.to	= S3C2410_PA_UART2 + S3C2410_UTXH,
 		.hw_addr.from	= S3C2410_PA_UART2 + S3C2410_URXH,
 	},
 	[DMACH_UART0_SRC2] = {
 		.name		= "uart0",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART0_1),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART0_1),
 		.hw_addr.to	= S3C2410_PA_UART0 + S3C2410_UTXH,
 		.hw_addr.from	= S3C2410_PA_UART0 + S3C2410_URXH,
 	},
 	[DMACH_UART1_SRC2] = {
 		.name		= "uart1",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART1_1),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART1_1),
 		.hw_addr.to	= S3C2410_PA_UART1 + S3C2410_UTXH,
 		.hw_addr.from	= S3C2410_PA_UART1 + S3C2410_URXH,
 	},
       	[DMACH_UART2_SRC2] = {
 		.name		= "uart2",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART2_1),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART2_1),
 		.hw_addr.to	= S3C2410_PA_UART2 + S3C2410_UTXH,
 		.hw_addr.from	= S3C2410_PA_UART2 + S3C2410_URXH,
 	},
 	[DMACH_TIMER] = {
 		.name		= "timer",
 		.channels	= MAP(S3C2412_DMAREQSEL_TIMER),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_TIMER),
 	},
 	[DMACH_I2S_IN] = {
 		.name		= "i2s-sdi",
 		.channels	= MAP(S3C2412_DMAREQSEL_I2SRX),
-		.hw_addr.from	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_I2SRX),
+		.hw_addr.from	= S3C2410_PA_IIS + S3C2412_IISRXD,
 	},
 	[DMACH_I2S_OUT] = {
 		.name		= "i2s-sdo",
 		.channels	= MAP(S3C2412_DMAREQSEL_I2STX),
-		.hw_addr.to	= S3C2410_PA_IIS + S3C2410_IISFIFO,
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_I2STX),
+		.hw_addr.to	= S3C2410_PA_IIS + S3C2412_IISTXD,
 	},
 	[DMACH_USB_EP1] = {
 		.name		= "usb-ep1",
 		.channels	= MAP(S3C2412_DMAREQSEL_USBEP1),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_USBEP1),
 	},
 	[DMACH_USB_EP2] = {
 		.name		= "usb-ep2",
 		.channels	= MAP(S3C2412_DMAREQSEL_USBEP2),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_USBEP2),
 	},
 	[DMACH_USB_EP3] = {
 		.name		= "usb-ep3",
 		.channels	= MAP(S3C2412_DMAREQSEL_USBEP3),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_USBEP3),
 	},
 	[DMACH_USB_EP4] = {
 		.name		= "usb-ep4",
 		.channels	= MAP(S3C2412_DMAREQSEL_USBEP4),
+		.channels_rx	= MAP(S3C2412_DMAREQSEL_USBEP4),
 	},
 };
 
+static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
+				  struct s3c24xx_dma_map *map,
+				  enum s3c2410_dmasrc dir)
+{
+	unsigned long chsel;
+
+	if (dir == S3C2410_DMASRC_HW)
+		chsel = map->channels_rx[0];
+	else
+		chsel = map->channels[0];
+
+	chsel &= ~DMA_CH_VALID;
+	chsel |= S3C2412_DMAREQSEL_HW;
+
+	writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL);
+}
+
 static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
 			       struct s3c24xx_dma_map *map)
 {
-	writel(map->channels[0] | S3C2412_DMAREQSEL_HW,
-	       chan->regs + S3C2412_DMA_DMAREQSEL);
+	s3c2412_dma_direction(chan, map, chan->source);
 }
 
 static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
 	.select		= s3c2412_dma_select,
+	.direction	= s3c2412_dma_direction,
 	.dcon_mask	= 0,
 	.map		= s3c2412_dma_mappings,
 	.map_size	= ARRAY_SIZE(s3c2412_dma_mappings),
diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c
new file mode 100644
index 0000000..8e55c3a
--- /dev/null
+++ b/arch/arm/mach-s3c2412/gpio.c
@@ -0,0 +1,60 @@
+/* linux/arch/arm/mach-s3c2412/gpio.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * S3C2412/S3C2413 specific GPIO support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/hardware.h>
+
+int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
+{
+	void __iomem *base = S3C24XX_GPIO_BASE(pin);
+	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+	unsigned long flags;
+	unsigned long slpcon;
+
+	offs *= 2;
+
+	if (pin < S3C2410_GPIO_BANKB)
+		return -EINVAL;
+
+	if (pin >= S3C2410_GPIO_BANKF &&
+	    pin <= S3C2410_GPIO_BANKG)
+		return -EINVAL;
+
+	if (pin > (S3C2410_GPIO_BANKH + 32))
+		return -EINVAL;
+
+	local_irq_save(flags);
+
+	slpcon = __raw_readl(base + 0x0C);
+
+	slpcon &= ~(3 << offs);
+	slpcon |= state << offs;
+
+	__raw_writel(slpcon, base + 0x0C);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2412_gpio_set_sleepcfg);
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index e9d0c76..cc1917b 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -33,6 +33,7 @@
 
 #include <asm/arch/regs-irq.h>
 #include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-power.h>
 
 #include <asm/plat-s3c24xx/cpu.h>
 #include <asm/plat-s3c24xx/irq.h>
@@ -153,6 +154,22 @@
 	.unmask		= s3c2412_irq_cfsdi_unmask,
 };
 
+static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state)
+{
+	unsigned long pwrcfg;
+
+	pwrcfg = __raw_readl(S3C2412_PWRCFG);
+	if (state)
+		pwrcfg &= ~S3C2412_PWRCFG_RTC_MASKIRQ;
+	else
+		pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
+	__raw_writel(pwrcfg, S3C2412_PWRCFG);
+
+	return s3c_irq_chip.set_wake(irqno, state);
+}
+
+static struct irq_chip s3c2412_irq_rtc_chip;
+
 static int s3c2412_irq_add(struct sys_device *sysdev)
 {
 	unsigned int irqno;
@@ -173,6 +190,13 @@
 		set_irq_flags(irqno, IRQF_VALID);
 	}
 
+	/* change RTC IRQ's set wake method */
+
+	s3c2412_irq_rtc_chip = s3c_irq_chip;
+	s3c2412_irq_rtc_chip.set_wake = s3c2412_irq_rtc_wake;
+
+	set_irq_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
index 8988dac..d4ffb2d 100644
--- a/arch/arm/mach-s3c2412/pm.c
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -33,6 +33,8 @@
 
 #include <asm/plat-s3c24xx/s3c2412.h>
 
+extern void s3c2412_sleep_enter(void);
+
 static void s3c2412_cpu_suspend(void)
 {
 	unsigned long tmp;
@@ -43,20 +45,7 @@
 	tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
 	__raw_writel(tmp, S3C2412_PWRCFG);
 
-	/* issue the standby signal into the pm unit. Note, we
-	 * issue a write-buffer drain just in case */
-
-	tmp = 0;
-
-	asm("b 1f\n\t"
-	    ".align 5\n\t"
-	    "1:\n\t"
-	    "mcr p15, 0, %0, c7, c10, 4\n\t"
-	    "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
-
-	/* we should never get past here */
-
-	panic("sleep resumed to originator?");
+	s3c2412_sleep_enter();
 }
 
 static void s3c2412_pm_prepare(void)
@@ -88,7 +77,6 @@
 	SAVE_ITEM(S3C2412_GPBSLPCON),
 	SAVE_ITEM(S3C2412_GPCSLPCON),
 	SAVE_ITEM(S3C2412_GPDSLPCON),
-	SAVE_ITEM(S3C2412_GPESLPCON),
 	SAVE_ITEM(S3C2412_GPFSLPCON),
 	SAVE_ITEM(S3C2412_GPGSLPCON),
 	SAVE_ITEM(S3C2412_GPHSLPCON),
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index 265cd3f..abf1599 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -168,6 +168,8 @@
 
 	fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2);
 
+	clk_mpll.rate = fclk;
+
 	tmp = __raw_readl(S3C2410_CLKDIVN);
 
 	/* work out clock scalings */
diff --git a/arch/arm/mach-s3c2412/sleep.S b/arch/arm/mach-s3c2412/sleep.S
new file mode 100644
index 0000000..db32cac
--- /dev/null
+++ b/arch/arm/mach-s3c2412/sleep.S
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-s3c2412/sleep.S
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 Power Manager low-level sleep support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+#include <asm/arch/map.h>
+
+#include <asm/arch/regs-irq.h>
+
+	.text
+
+	.global	s3c2412_sleep_enter
+
+s3c2412_sleep_enter:
+	mov	r0, #0			/* argument for coprocessors */
+	ldr	r1, =S3C2410_INTPND
+	ldr	r2, =S3C2410_SRCPND
+	ldr	r3, =S3C2410_EINTPEND
+
+	teq	r0, r0
+	bl	s3c2412_sleep_enter1
+	teq	pc, r0
+	bl	s3c2412_sleep_enter1
+
+	.align	5
+
+	/* this is called twice, first with the Z flag to ensure that the
+	 * instructions have been loaded into the cache, and the second
+	 * time to try and suspend the system.
+	*/
+s3c2412_sleep_enter1:
+	mcr	p15, 0, r0, c7, c10, 4
+	mcrne	p15, 0, r0, c7, c0, 4
+
+	/* if we return from here, it is because an interrupt was
+	 * active when we tried to shutdown. Try and ack the IRQ and
+	 * retry, as simply returning causes the system to lock.
+	*/
+
+	ldrne	r9, [ r1 ]
+	strne	r9, [ r1 ]
+	ldrne	r9, [ r2 ]
+	strne	r9, [ r2 ]
+	ldrne	r9, [ r3 ]
+	strne	r9, [ r3 ]
+	bne	s3c2412_sleep_enter1
+
+	mov	pc, r14
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index 79e2ea4..184d804 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -111,14 +111,9 @@
 
 static int s3c2440_clk_add(struct sys_device *sysdev)
 {
-	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
-	unsigned long clkdivn;
+	struct clk *clock_upll;
 	struct clk *clock_h;
 	struct clk *clock_p;
-	struct clk *clock_upll;
-
-	printk("S3C2440: Clock Support, DVS %s\n",
-	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
 
 	clock_p = clk_get(NULL, "pclk");
 	clock_h = clk_get(NULL, "hclk");
@@ -129,21 +124,6 @@
 		return -EINVAL;
 	}
 
-	/* check rate of UPLL, and if it is near 96MHz, then change
-	 * to using half the UPLL rate for the system */
-
-	if (clk_get_rate(clock_upll) > (94 * MHZ)) {
-		clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
-
-		mutex_lock(&clocks_mutex);
-
-		clkdivn = __raw_readl(S3C2410_CLKDIVN);
-		clkdivn |= S3C2440_CLKDIVN_UCLK;
-		__raw_writel(clkdivn, S3C2410_CLKDIVN);
-
-		mutex_unlock(&clocks_mutex);
-	}
-
 	s3c2440_clk_cam.parent = clock_h;
 	s3c2440_clk_ac97.parent = clock_p;
 	s3c2440_clk_cam_upll.parent = clock_upll;
diff --git a/arch/arm/mach-s3c2442/clock.c b/arch/arm/mach-s3c2442/clock.c
index 5b9e830..2d030d4 100644
--- a/arch/arm/mach-s3c2442/clock.c
+++ b/arch/arm/mach-s3c2442/clock.c
@@ -115,14 +115,9 @@
 
 static int s3c2442_clk_add(struct sys_device *sysdev)
 {
-	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
-	unsigned long clkdivn;
+	struct clk *clock_upll;
 	struct clk *clock_h;
 	struct clk *clock_p;
-	struct clk *clock_upll;
-
-	printk("S3C2442: Clock Support, DVS %s\n",
-	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
 
 	clock_p = clk_get(NULL, "pclk");
 	clock_h = clk_get(NULL, "hclk");
@@ -133,21 +128,6 @@
 		return -EINVAL;
 	}
 
-	/* check rate of UPLL, and if it is near 96MHz, then change
-	 * to using half the UPLL rate for the system */
-
-	if (clk_get_rate(clock_upll) > (94 * MHZ)) {
-		clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
-
-		mutex_lock(&clocks_mutex);
-
-		clkdivn = __raw_readl(S3C2410_CLKDIVN);
-		clkdivn |= S3C2440_CLKDIVN_UCLK;
-		__raw_writel(clkdivn, S3C2410_CLKDIVN);
-
-		mutex_unlock(&clocks_mutex);
-	}
-
 	s3c2442_clk_cam.parent = clock_h;
 	s3c2442_clk_cam_upll.parent = clock_upll;
 
diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c
index 59703c6..06206ce 100644
--- a/arch/arm/mach-sa1100/ssp.c
+++ b/arch/arm/mach-sa1100/ssp.c
@@ -29,9 +29,8 @@
 {
 	unsigned int status = Ser4SSSR;
 
-	if (status & SSSR_ROR) {
+	if (status & SSSR_ROR)
 		printk(KERN_WARNING "SSP: receiver overrun\n");
-	}
 
 	Ser4SSSR = SSSR_ROR;
 
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index fdf7b01..c267736 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/timex.h>
 #include <linux/signal.h>
+#include <linux/clocksource.h>
 
 #include <asm/mach/time.h>
 #include <asm/hardware.h>
@@ -35,23 +36,6 @@
 	return 0;
 }
 
-/* IRQs are disabled before entering here from do_gettimeofday() */
-static unsigned long sa1100_gettimeoffset (void)
-{
-	unsigned long ticks_to_match, elapsed, usec;
-
-	/* Get ticks before next timer match */
-	ticks_to_match = OSMR0 - OSCR;
-
-	/* We need elapsed ticks since last match */
-	elapsed = LATCH - ticks_to_match;
-
-	/* Now convert them to usec */
-	usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
-
-	return usec;
-}
-
 #ifdef CONFIG_NO_IDLE_HZ
 static unsigned long initial_match;
 static int match_posponed;
@@ -62,8 +46,6 @@
 {
 	unsigned int next_match;
 
-	write_seqlock(&xtime_lock);
-
 #ifdef CONFIG_NO_IDLE_HZ
 	if (match_posponed) {
 		match_posponed = 0;
@@ -85,8 +67,6 @@
 		next_match = (OSMR0 += LATCH);
 	} while ((signed long)(next_match - OSCR) <= 0);
 
-	write_sequnlock(&xtime_lock);
-
 	return IRQ_HANDLED;
 }
 
@@ -96,6 +76,20 @@
 	.handler	= sa1100_timer_interrupt,
 };
 
+static cycle_t sa1100_read_oscr(void)
+{
+	return OSCR;
+}
+
+static struct clocksource cksrc_sa1100_oscr = {
+	.name		= "oscr",
+	.rating		= 200,
+	.read		= sa1100_read_oscr,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift		= 20,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
 static void __init sa1100_timer_init(void)
 {
 	unsigned long flags;
@@ -109,6 +103,11 @@
 	OIER = OIER_E0;		/* enable match on timer 0 to cause interrupts */
 	OSMR0 = OSCR + LATCH;	/* set initial match */
 	local_irq_restore(flags);
+
+	cksrc_sa1100_oscr.mult =
+		clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_sa1100_oscr.shift);
+
+	clocksource_register(&cksrc_sa1100_oscr);
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
@@ -182,7 +181,6 @@
 	.init		= sa1100_timer_init,
 	.suspend	= sa1100_timer_suspend,
 	.resume		= sa1100_timer_resume,
-	.offset		= sa1100_gettimeoffset,
 #ifdef CONFIG_NO_IDLE_HZ
 	.dyn_tick	= &sa1100_dyn_tick,
 #endif
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index a0545db..09d9f33 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -82,9 +82,7 @@
 static irqreturn_t
 shark_timer_interrupt(int irq, void *dev_id)
 {
-	write_seqlock(&xtime_lock);
 	timer_tick();
-	write_sequnlock(&xtime_lock);
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 7868f4d..76348f0 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -171,8 +171,8 @@
 # ARM926T
 config CPU_ARM926T
 	bool "Support ARM926T processor"
-	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
-	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
+	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
+	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
 	select CPU_32v5
 	select CPU_ABRT_EV5TJ
 	select CPU_CACHE_VIVT
@@ -342,11 +342,33 @@
 	select CPU_TLB_V4WBI if MMU
 	select IO_36
 
+# Feroceon
+config CPU_FEROCEON
+	bool
+	depends on ARCH_ORION
+	default y
+	select CPU_32v5
+	select CPU_ABRT_EV5T
+	select CPU_CACHE_VIVT
+	select CPU_CP15_MMU
+	select CPU_COPY_V4WB if MMU
+	select CPU_TLB_V4WBI if MMU
+
+config CPU_FEROCEON_OLD_ID
+	bool "Accept early Feroceon cores with an ARM926 ID"
+	depends on CPU_FEROCEON && !CPU_ARM926T
+	default y
+	help
+	  This enables the usage of some old Feroceon cores
+	  for which the CPU ID is equal to the ARM926 ID.
+	  Relevant for Feroceon-1850 and early Feroceon-2850.
+
 # ARMv6
 config CPU_V6
 	bool "Support ARM V6 processor"
-	depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3
+	depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM7X00A
 	default y if ARCH_MX3
+	default y if ARCH_MSM7X00A
 	select CPU_32v6
 	select CPU_ABRT_EV6
 	select CPU_CACHE_V6
@@ -538,7 +560,7 @@
 
 config ARM_THUMB
 	bool "Support Thumb user binaries"
-	depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7
+	depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7 || CPU_FEROCEON
 	default y
 	help
 	  Say Y if you want to include kernel support for running user space
@@ -600,7 +622,7 @@
 
 config CPU_DCACHE_WRITETHROUGH
 	bool "Force write through D-cache"
-	depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE
+	depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FEROCEON) && !CPU_DCACHE_DISABLE
 	default y if CPU_ARM925T
 	help
 	  Say Y here to use the data cache in writethrough mode. Unless you
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 7627027..44536a0 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -68,6 +68,7 @@
 obj-$(CONFIG_CPU_SA1100)	+= proc-sa1100.o
 obj-$(CONFIG_CPU_XSCALE)	+= proc-xscale.o
 obj-$(CONFIG_CPU_XSC3)		+= proc-xsc3.o
+obj-$(CONFIG_CPU_FEROCEON)	+= proc-feroceon.o
 obj-$(CONFIG_CPU_V6)		+= proc-v6.o
 obj-$(CONFIG_CPU_V7)		+= proc-v7.o
 
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index a8a7dab..28ad7ab 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -12,6 +12,7 @@
 #include <linux/signal.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/kprobes.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -20,6 +21,29 @@
 
 #include "fault.h"
 
+
+#ifdef CONFIG_KPROBES
+static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr)
+{
+	int ret = 0;
+
+	if (!user_mode(regs)) {
+		/* kprobe_running() needs smp_processor_id() */
+		preempt_disable();
+		if (kprobe_running() && kprobe_fault_handler(regs, fsr))
+			ret = 1;
+		preempt_enable();
+	}
+
+	return ret;
+}
+#else
+static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr)
+{
+	return 0;
+}
+#endif
+
 /*
  * This is useful to dump out the page tables associated with
  * 'addr' in mm 'mm'.
@@ -215,13 +239,16 @@
 	return fault;
 }
 
-static int
+static int __kprobes
 do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	int fault, sig, code;
 
+	if (notify_page_fault(regs, fsr))
+		return 0;
+
 	tsk = current;
 	mm  = tsk->mm;
 
@@ -311,7 +338,7 @@
  * interrupt or a critical region, and should only copy the information
  * from the master page table, nothing more.
  */
-static int
+static int __kprobes
 do_translation_fault(unsigned long addr, unsigned int fsr,
 		     struct pt_regs *regs)
 {
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
new file mode 100644
index 0000000..fa0dc7e
--- /dev/null
+++ b/arch/arm/mm/proc-feroceon.S
@@ -0,0 +1,506 @@
+/*
+ *  linux/arch/arm/mm/proc-feroceon.S: MMU functions for Feroceon
+ *
+ *  Heavily based on proc-arm926.S
+ *  Maintainer: Assaf Hoffman <hoffman@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/elf.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions.  Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define CACHE_DLIMIT	16384
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define CACHE_DLINESIZE	32
+
+	.text
+/*
+ * cpu_feroceon_proc_init()
+ */
+ENTRY(cpu_feroceon_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_feroceon_proc_fin()
+ */
+ENTRY(cpu_feroceon_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	feroceon_flush_kern_cache_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x000e			@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_feroceon_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_feroceon_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+#ifdef CONFIG_MMU
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+#endif
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f			@ ............wcam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_feroceon_do_idle()
+ *
+ * Called with IRQs disabled
+ */
+	.align	10
+ENTRY(cpu_feroceon_do_idle)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ Drain write buffer
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+	mov	pc, lr
+
+/*
+ *	flush_user_cache_all()
+ *
+ *	Clean and invalidate all cache entries in a particular
+ *	address space.
+ */
+ENTRY(feroceon_flush_user_cache_all)
+	/* FALLTHROUGH */
+
+/*
+ *	flush_kern_cache_all()
+ *
+ *	Clean and invalidate the entire cache.
+ */
+ENTRY(feroceon_flush_kern_cache_all)
+	mov	r2, #VM_EXEC
+	mov	ip, #0
+__flush_whole_cache:
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
+	bne	1b
+#endif
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	flush_user_cache_range(start, end, flags)
+ *
+ *	Clean and invalidate a range of cache entries in the
+ *	specified address range.
+ *
+ *	- start	- start address (inclusive)
+ *	- end	- end address (exclusive)
+ *	- flags	- vm_flags describing address space
+ */
+ENTRY(feroceon_flush_user_cache_range)
+	mov	ip, #0
+	sub	r3, r1, r0			@ calculate total size
+	cmp	r3, #CACHE_DLIMIT
+	bgt	__flush_whole_cache
+1:	tst	r2, #VM_EXEC
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+#else
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+#endif
+	cmp	r0, r1
+	blo	1b
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	coherent_kern_range(start, end)
+ *
+ *	Ensure coherency between the Icache and the Dcache in the
+ *	region described by start, end.  If you have non-snooping
+ *	Harvard caches, you need to implement this function.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ */
+ENTRY(feroceon_coherent_kern_range)
+	/* FALLTHROUGH */
+
+/*
+ *	coherent_user_range(start, end)
+ *
+ *	Ensure coherency between the Icache and the Dcache in the
+ *	region described by start, end.  If you have non-snooping
+ *	Harvard caches, you need to implement this function.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ */
+ENTRY(feroceon_coherent_user_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	flush_kern_dcache_page(void *page)
+ *
+ *	Ensure no D cache aliasing occurs, either with itself or
+ *	the I cache
+ *
+ *	- addr	- page aligned address
+ */
+ENTRY(feroceon_flush_kern_dcache_page)
+	add	r1, r0, #PAGE_SZ
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	dma_inv_range(start, end)
+ *
+ *	Invalidate (discard) the specified virtual address range.
+ *	May not write back any entries.  If 'start' or 'end'
+ *	are not cache line aligned, those lines must be written
+ *	back.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ *
+ * (same as v4wb)
+ */
+ENTRY(feroceon_dma_inv_range)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	tst	r0, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+#endif
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	dma_clean_range(start, end)
+ *
+ *	Clean the specified virtual address range.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ *
+ * (same as v4wb)
+ */
+ENTRY(feroceon_dma_clean_range)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	dma_flush_range(start, end)
+ *
+ *	Clean and invalidate the specified virtual address range.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ */
+ENTRY(feroceon_dma_flush_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
+#else
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+ENTRY(feroceon_cache_fns)
+	.long	feroceon_flush_kern_cache_all
+	.long	feroceon_flush_user_cache_all
+	.long	feroceon_flush_user_cache_range
+	.long	feroceon_coherent_kern_range
+	.long	feroceon_coherent_user_range
+	.long	feroceon_flush_kern_dcache_page
+	.long	feroceon_dma_inv_range
+	.long	feroceon_dma_clean_range
+	.long	feroceon_dma_flush_range
+
+ENTRY(cpu_feroceon_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	subs	r1, r1, #CACHE_DLINESIZE
+	bhi	1b
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_feroceon_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_feroceon_switch_mm)
+#ifdef CONFIG_MMU
+	mov	ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
+	bne	1b
+#endif
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_feroceon_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_feroceon_set_pte_ext)
+#ifdef CONFIG_MMU
+	str	r1, [r0], #-2048		@ linux version
+
+	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+	bic	r2, r1, #PTE_SMALL_AP_MASK
+	bic	r2, r2, #PTE_TYPE_MASK
+	orr	r2, r2, #PTE_TYPE_SMALL
+
+	tst	r1, #L_PTE_USER			@ User?
+	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
+
+	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
+	movne	r2, #0
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	eor	r3, r2, #0x0a			@ C & small page?
+	tst	r3, #0x0b
+	biceq	r2, r2, #4
+#endif
+	str	r2, [r0]			@ hardware version
+	mov	r0, r0
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+#endif
+	mov	pc, lr
+
+	__INIT
+
+	.type	__feroceon_setup, #function
+__feroceon_setup:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+#ifdef CONFIG_MMU
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+#endif
+
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mov	r0, #4				@ disable write-back on caches explicitly
+	mcr	p15, 7, r0, c15, c0, 0
+#endif
+
+	adr	r5, feroceon_crval
+	ldmia	r5, {r5, r6}
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+	bic	r0, r0, r5
+	orr	r0, r0, r6
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+	orr	r0, r0, #0x4000			@ .1.. .... .... ....
+#endif
+	mov	pc, lr
+	.size	__feroceon_setup, . - __feroceon_setup
+
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .011 0001 ..11 0101
+	 *
+	 */
+	.type	feroceon_crval, #object
+feroceon_crval:
+	crval	clear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134
+
+	__INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	feroceon_processor_functions, #object
+feroceon_processor_functions:
+	.word	v5t_early_abort
+	.word	cpu_feroceon_proc_init
+	.word	cpu_feroceon_proc_fin
+	.word	cpu_feroceon_reset
+	.word	cpu_feroceon_do_idle
+	.word	cpu_feroceon_dcache_clean_area
+	.word	cpu_feroceon_switch_mm
+	.word	cpu_feroceon_set_pte_ext
+	.size	feroceon_processor_functions, . - feroceon_processor_functions
+
+	.section ".rodata"
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv5te"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v5"
+	.size	cpu_elf_name, . - cpu_elf_name
+
+	.type	cpu_feroceon_name, #object
+cpu_feroceon_name:
+	.asciz	"Feroceon"
+	.size	cpu_feroceon_name, . - cpu_feroceon_name
+
+	.align
+
+	.section ".proc.info.init", #alloc, #execinstr
+
+#ifdef CONFIG_CPU_FEROCEON_OLD_ID
+	.type	__feroceon_old_id_proc_info,#object
+__feroceon_old_id_proc_info:
+	.long	0x41069260
+	.long	0xfffffff0
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	b	__feroceon_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_feroceon_name
+	.long	feroceon_processor_functions
+	.long	v4wbi_tlb_fns
+	.long	v4wb_user_fns
+	.long	feroceon_cache_fns
+	.size	__feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info
+#endif
+
+	.type	__feroceon_proc_info,#object
+__feroceon_proc_info:
+	.long	0x56055310
+	.long	0xfffffff0
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	b	__feroceon_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_feroceon_name
+	.long	feroceon_processor_functions
+	.long	v4wbi_tlb_fns
+	.long	v4wb_user_fns
+	.long	feroceon_cache_fns
+	.size	__feroceon_proc_info, . - __feroceon_proc_info
diff --git a/arch/arm/plat-omap/debug-devices.c b/arch/arm/plat-omap/debug-devices.c
index 83a5f8b..f455233 100644
--- a/arch/arm/plat-omap/debug-devices.c
+++ b/arch/arm/plat-omap/debug-devices.c
@@ -29,7 +29,7 @@
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.flags  = IORESOURCE_IRQ,
+		.flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
 	},
 };
 
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 0360b1f..1945ddf 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -116,8 +116,8 @@
 		}
 
 		spin_lock(q->queue_lock);
-		blkdev_dequeue_request(rq);
-		end_that_request_last(rq, 0);
+		if (__blk_end_request(rq, 0, 0))
+			BUG();
 		spin_unlock(q->queue_lock);
 	}
 }
@@ -149,10 +149,8 @@
 
 		msg = (mbox_msg_t) rq->data;
 
-		spin_lock_irqsave(q->queue_lock, flags);
-		blkdev_dequeue_request(rq);
-		end_that_request_last(rq, 0);
-		spin_unlock_irqrestore(q->queue_lock, flags);
+		if (blk_end_request(rq, 0, 0))
+			BUG();
 
 		mbox->rxq->callback((void *)msg);
 	}
@@ -212,7 +210,7 @@
 
 static irqreturn_t mbox_interrupt(int irq, void *p)
 {
-	struct omap_mbox *mbox = (struct omap_mbox *)p;
+	struct omap_mbox *mbox = p;
 
 	if (is_mbox_irq(mbox, IRQ_TX))
 		__mbox_tx_interrupt(mbox);
@@ -263,10 +261,8 @@
 
 		*p = (mbox_msg_t) rq->data;
 
-		spin_lock_irqsave(q->queue_lock, flags);
-		blkdev_dequeue_request(rq);
-		end_that_request_last(rq, 0);
-		spin_unlock_irqrestore(q->queue_lock, flags);
+		if (blk_end_request(rq, 0, 0))
+			BUG();
 
 		if (unlikely(mbox_seq_test(mbox, *p))) {
 			pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index f7b9ccd..2af5bd5 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -98,9 +98,10 @@
 
 static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
 {
-	struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
+	struct omap_mcbsp *mcbsp_tx = dev_id;
 
-	DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
+	DBG("TX IRQ callback : 0x%x\n",
+	    OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
 
 	complete(&mcbsp_tx->tx_irq_completion);
 	return IRQ_HANDLED;
@@ -108,9 +109,10 @@
 
 static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
 {
-	struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id);
+	struct omap_mcbsp *mcbsp_rx = dev_id;
 
-	DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
+	DBG("RX IRQ callback : 0x%x\n",
+	    OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
 
 	complete(&mcbsp_rx->rx_irq_completion);
 	return IRQ_HANDLED;
@@ -118,9 +120,10 @@
 
 static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
 {
-	struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
+	struct omap_mcbsp *mcbsp_dma_tx = data;
 
-	DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
+	DBG("TX DMA callback : 0x%x\n",
+	    OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
 
 	/* We can free the channels */
 	omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
@@ -131,9 +134,10 @@
 
 static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
 {
-	struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data);
+	struct omap_mcbsp *mcbsp_dma_rx = data;
 
-	DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
+	DBG("RX DMA callback : 0x%x\n",
+	    OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
 
 	/* We can free the channels */
 	omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 8e5ccaa..131d202 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -23,6 +23,7 @@
 
 obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o
 obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-irq.o
+obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-clock.o
 obj-$(CONFIG_PM_SIMTEC)		+= pm-simtec.o
 obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_PM)		+= sleep.o
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
index 79cda0f..99a4474 100644
--- a/arch/arm/plat-s3c24xx/clock.c
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -172,6 +172,15 @@
 	if (IS_ERR(clk))
 		return -EINVAL;
 
+	/* We do not default just do a clk->rate = rate as
+	 * the clock may have been made this way by choice.
+	 */
+
+	WARN_ON(clk->set_rate == NULL);
+
+	if (clk->set_rate == NULL)
+		return -EINVAL;
+
 	mutex_lock(&clocks_mutex);
 	ret = (clk->set_rate)(clk, rate);
 	mutex_unlock(&clocks_mutex);
@@ -213,6 +222,12 @@
 
 /* base clocks */
 
+static int clk_default_setrate(struct clk *clk, unsigned long rate)
+{
+	clk->rate = rate;
+	return 0;
+}
+
 struct clk clk_xtal = {
 	.name		= "xtal",
 	.id		= -1,
@@ -224,6 +239,7 @@
 struct clk clk_mpll = {
 	.name		= "mpll",
 	.id		= -1,
+	.set_rate	= clk_default_setrate,
 };
 
 struct clk clk_upll = {
@@ -239,6 +255,7 @@
 	.rate		= 0,
 	.parent		= &clk_mpll,
 	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
 };
 
 struct clk clk_h = {
@@ -247,6 +264,7 @@
 	.rate		= 0,
 	.parent		= NULL,
 	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
 };
 
 struct clk clk_p = {
@@ -255,6 +273,7 @@
 	.rate		= 0,
 	.parent		= NULL,
 	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
 };
 
 struct clk clk_usb_bus = {
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index aae1b9c..ac9ff16 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -525,7 +525,8 @@
 		}
 	} else if (chan->state == S3C2410_DMA_IDLE) {
 		if (chan->flags & S3C2410_DMAF_AUTOSTART) {
-			s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START);
+			s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
+					 S3C2410_DMAOP_START);
 		}
 	}
 
@@ -787,7 +788,7 @@
 
 	pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
 
-	return 0;
+	return chan->number | DMACH_LOW_LEVEL;
 }
 
 EXPORT_SYMBOL(s3c2410_dma_request);
@@ -1173,6 +1174,7 @@
 
 	chan->source = source;
 	chan->dev_addr = devaddr;
+	chan->hw_cfg = hwcfg;
 
 	switch (source) {
 	case S3C2410_DMASRC_HW:
@@ -1184,7 +1186,7 @@
 		dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
 
 		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
-		return 0;
+		break;
 
 	case S3C2410_DMASRC_MEM:
 		/* source is memory */
@@ -1195,11 +1197,19 @@
 		dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
 
 		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
-		return 0;
+		break;
+
+	default:
+		printk(KERN_ERR "dma%d: invalid source type (%d)\n",
+		       channel, source);
+
+		return -EINVAL;
 	}
 
-	printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source);
-	return -EINVAL;
+	if (dma_sel.direction != NULL)
+		(dma_sel.direction)(chan, chan->map, source);
+
+	return 0;
 }
 
 EXPORT_SYMBOL(s3c2410_dma_devconfig);
@@ -1227,6 +1237,10 @@
 
 EXPORT_SYMBOL(s3c2410_dma_getposition);
 
+static struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev)
+{
+	return container_of(dev, struct s3c2410_dma_chan, dev);
+}
 
 /* system device class */
 
@@ -1234,7 +1248,7 @@
 
 static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
 {
-	struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
+	struct s3c2410_dma_chan *cp = to_dma_chan(dev);
 
 	printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
 
@@ -1256,6 +1270,24 @@
 
 static int s3c2410_dma_resume(struct sys_device *dev)
 {
+	struct s3c2410_dma_chan *cp = to_dma_chan(dev);
+	unsigned int no = cp->number | DMACH_LOW_LEVEL;
+
+	/* restore channel's hardware configuration */
+
+	if (!cp->in_use)
+		return 0;
+
+	printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
+
+	s3c2410_dma_config(no, cp->xfer_unit, cp->dcon);
+	s3c2410_dma_devconfig(no, cp->source, cp->hw_cfg, cp->dev_addr);
+
+	/* re-select the dma source for this channel */
+
+	if (cp->map != NULL)
+		dma_sel.select(cp, cp->map);
+
 	return 0;
 }
 
@@ -1445,6 +1477,7 @@
 
  found:
 	dmach = &s3c2410_chans[ch];
+	dmach->map = ch_map;
 	dma_chan_map[channel] = dmach;
 
 	/* select the channel */
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
index ec3a09c..ee99dcc 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -122,6 +122,19 @@
 
 EXPORT_SYMBOL(s3c2410_gpio_pullup);
 
+int s3c2410_gpio_getpull(unsigned int pin)
+{
+	void __iomem *base = S3C24XX_GPIO_BASE(pin);
+	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+
+	if (pin < S3C2410_GPIO_BANKB)
+		return -EINVAL;
+
+	return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getpull);
+
 void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
 {
 	void __iomem *base = S3C24XX_GPIO_BASE(pin);
@@ -186,3 +199,19 @@
 }
 
 EXPORT_SYMBOL(s3c2410_gpio_getirq);
+
+int s3c2410_gpio_irq2pin(unsigned int irq)
+{
+	if (irq >= IRQ_EINT0 && irq <= IRQ_EINT3)
+		return S3C2410_GPF0 + (irq - IRQ_EINT0);
+
+	if (irq >= IRQ_EINT4 && irq <= IRQ_EINT7)
+		return S3C2410_GPF4 + (irq - IRQ_EINT4);
+
+	if (irq >= IRQ_EINT8 && irq <= IRQ_EINT23)
+		return S3C2410_GPG0 + (irq - IRQ_EINT8);
+
+	return -EINVAL;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_irq2pin);
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 8fbc884..d486f51 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -187,7 +187,7 @@
 	.set_wake	= s3c_irq_wake
 };
 
-static struct irq_chip s3c_irq_chip = {
+struct irq_chip s3c_irq_chip = {
 	.name		= "s3c",
 	.ack		= s3c_irq_ack,
 	.mask		= s3c_irq_mask,
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index 4fdb311..bf5581a 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -83,38 +83,39 @@
 	SAVE_ITEM(S3C2410_REFRESH),
 };
 
-static struct sleep_save gpio_save[] = {
-	SAVE_ITEM(S3C2410_GPACON),
-	SAVE_ITEM(S3C2410_GPADAT),
+static struct gpio_sleep {
+	void __iomem	*base;
+	unsigned int	 gpcon;
+	unsigned int	 gpdat;
+	unsigned int	 gpup;
+} gpio_save[] = {
+	[0] = {
+		.base	= S3C2410_GPACON,
+	},
+	[1] = {
+		.base	= S3C2410_GPBCON,
+	},
+	[2] = {
+		.base	= S3C2410_GPCCON,
+	},
+	[3] = {
+		.base	= S3C2410_GPDCON,
+	},
+	[4] = {
+		.base	= S3C2410_GPECON,
+	},
+	[5] = {
+		.base	= S3C2410_GPFCON,
+	},
+	[6] = {
+		.base	= S3C2410_GPGCON,
+	},
+	[7] = {
+		.base	= S3C2410_GPHCON,
+	},
+};
 
-	SAVE_ITEM(S3C2410_GPBCON),
-	SAVE_ITEM(S3C2410_GPBDAT),
-	SAVE_ITEM(S3C2410_GPBUP),
-
-	SAVE_ITEM(S3C2410_GPCCON),
-	SAVE_ITEM(S3C2410_GPCDAT),
-	SAVE_ITEM(S3C2410_GPCUP),
-
-	SAVE_ITEM(S3C2410_GPDCON),
-	SAVE_ITEM(S3C2410_GPDDAT),
-	SAVE_ITEM(S3C2410_GPDUP),
-
-	SAVE_ITEM(S3C2410_GPECON),
-	SAVE_ITEM(S3C2410_GPEDAT),
-	SAVE_ITEM(S3C2410_GPEUP),
-
-	SAVE_ITEM(S3C2410_GPFCON),
-	SAVE_ITEM(S3C2410_GPFDAT),
-	SAVE_ITEM(S3C2410_GPFUP),
-
-	SAVE_ITEM(S3C2410_GPGCON),
-	SAVE_ITEM(S3C2410_GPGDAT),
-	SAVE_ITEM(S3C2410_GPGUP),
-
-	SAVE_ITEM(S3C2410_GPHCON),
-	SAVE_ITEM(S3C2410_GPHDAT),
-	SAVE_ITEM(S3C2410_GPHUP),
-
+static struct sleep_save misc_save[] = {
 	SAVE_ITEM(S3C2410_DCLKCON),
 };
 
@@ -486,6 +487,184 @@
 	}
 }
 
+/* offsets for CON/DAT/UP registers */
+
+#define OFFS_CON	(S3C2410_GPACON - S3C2410_GPACON)
+#define OFFS_DAT	(S3C2410_GPADAT - S3C2410_GPACON)
+#define OFFS_UP		(S3C2410_GPBUP  - S3C2410_GPBCON)
+
+/* s3c2410_pm_save_gpios()
+ *
+ * Save the state of the GPIOs
+ */
+
+static void s3c2410_pm_save_gpios(void)
+{
+	struct gpio_sleep *gps = gpio_save;
+	unsigned int gpio;
+
+	for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) {
+		void __iomem *base = gps->base;
+
+		gps->gpcon = __raw_readl(base + OFFS_CON);
+		gps->gpdat = __raw_readl(base + OFFS_DAT);
+
+		if (gpio > 0)
+			gps->gpup = __raw_readl(base + OFFS_UP);
+
+	}
+}
+
+/* Test whether the given masked+shifted bits of an GPIO configuration
+ * are one of the SFN (special function) modes. */
+
+static inline int is_sfn(unsigned long con)
+{
+	return (con == 2 || con == 3);
+}
+
+/* Test if the given masked+shifted GPIO configuration is an input */
+
+static inline int is_in(unsigned long con)
+{
+	return con == 0;
+}
+
+/* Test if the given masked+shifted GPIO configuration is an output */
+
+static inline int is_out(unsigned long con)
+{
+	return con == 1;
+}
+
+/* s3c2410_pm_restore_gpio()
+ *
+ * Restore one of the GPIO banks that was saved during suspend. This is
+ * not as simple as once thought, due to the possibility of glitches
+ * from the order that the CON and DAT registers are set in.
+ *
+ * The three states the pin can be are {IN,OUT,SFN} which gives us 9
+ * combinations of changes to check. Three of these, if the pin stays
+ * in the same configuration can be discounted. This leaves us with
+ * the following:
+ *
+ * { IN => OUT }  Change DAT first
+ * { IN => SFN }  Change CON first
+ * { OUT => SFN } Change CON first, so new data will not glitch
+ * { OUT => IN }  Change CON first, so new data will not glitch
+ * { SFN => IN }  Change CON first
+ * { SFN => OUT } Change DAT first, so new data will not glitch [1]
+ *
+ * We do not currently deal with the UP registers as these control
+ * weak resistors, so a small delay in change should not need to bring
+ * these into the calculations.
+ *
+ * [1] this assumes that writing to a pin DAT whilst in SFN will set the
+ *     state for when it is next output.
+ */
+
+static void s3c2410_pm_restore_gpio(int index, struct gpio_sleep *gps)
+{
+	void __iomem *base = gps->base;
+	unsigned long gps_gpcon = gps->gpcon;
+	unsigned long gps_gpdat = gps->gpdat;
+	unsigned long old_gpcon;
+	unsigned long old_gpdat;
+	unsigned long old_gpup = 0x0;
+	unsigned long gpcon;
+	int nr;
+
+	old_gpcon = __raw_readl(base + OFFS_CON);
+	old_gpdat = __raw_readl(base + OFFS_DAT);
+
+	if (base == S3C2410_GPACON) {
+		/* GPACON only has one bit per control / data and no PULLUPs.
+		 * GPACON[x] = 0 => Output, 1 => SFN */
+
+		/* first set all SFN bits to SFN */
+
+		gpcon = old_gpcon | gps->gpcon;
+		__raw_writel(gpcon, base + OFFS_CON);
+
+		/* now set all the other bits */
+
+		__raw_writel(gps_gpdat, base + OFFS_DAT);
+		__raw_writel(gps_gpcon, base + OFFS_CON);
+	} else {
+		unsigned long old, new, mask;
+		unsigned long change_mask = 0x0;
+
+		old_gpup = __raw_readl(base + OFFS_UP);
+
+		/* Create a change_mask of all the items that need to have
+		 * their CON value changed before their DAT value, so that
+		 * we minimise the work between the two settings.
+		 */
+
+		for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
+			old = (old_gpcon & mask) >> nr;
+			new = (gps_gpcon & mask) >> nr;
+
+			/* If there is no change, then skip */
+
+			if (old == new)
+				continue;
+
+			/* If both are special function, then skip */
+
+			if (is_sfn(old) && is_sfn(new))
+				continue;
+
+			/* Change is IN => OUT, do not change now */
+
+			if (is_in(old) && is_out(new))
+				continue;
+
+			/* Change is SFN => OUT, do not change now */
+
+			if (is_sfn(old) && is_out(new))
+				continue;
+
+			/* We should now be at the case of IN=>SFN,
+			 * OUT=>SFN, OUT=>IN, SFN=>IN. */
+
+			change_mask |= mask;
+		}
+
+		/* Write the new CON settings */
+
+		gpcon = old_gpcon & ~change_mask;
+		gpcon |= gps_gpcon & change_mask;
+
+		__raw_writel(gpcon, base + OFFS_CON);
+
+		/* Now change any items that require DAT,CON */
+
+		__raw_writel(gps_gpdat, base + OFFS_DAT);
+		__raw_writel(gps_gpcon, base + OFFS_CON);
+		__raw_writel(gps->gpup, base + OFFS_UP);
+	}
+
+	DBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n",
+	    index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+}
+
+
+/** s3c2410_pm_restore_gpios()
+ *
+ * Restore the state of the GPIOs
+ */
+
+static void s3c2410_pm_restore_gpios(void)
+{
+	struct gpio_sleep *gps = gpio_save;
+	int gpio;
+
+	for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) {
+		s3c2410_pm_restore_gpio(gpio, gps);
+	}
+}
+
 void (*pm_cpu_prep)(void);
 void (*pm_cpu_sleep)(void);
 
@@ -535,7 +714,8 @@
 
 	/* save all necessary core registers not covered by the drivers */
 
-	s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
+	s3c2410_pm_save_gpios();
+	s3c2410_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
 	s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
 	s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
 
@@ -585,8 +765,9 @@
 	/* restore the system state */
 
 	s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
-	s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
+	s3c2410_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
 	s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
+	s3c2410_pm_restore_gpios();
 
 	s3c2410_pm_debug_init();
 
diff --git a/arch/arm/plat-s3c24xx/s3c244x-clock.c b/arch/arm/plat-s3c24xx/s3c244x-clock.c
new file mode 100644
index 0000000..faf3e0f
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c244x-clock.c
@@ -0,0 +1,137 @@
+/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
+ *
+ * Copyright (c) 2004-2005,2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440/S3C2442 Common clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-clock.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+	unsigned long camdivn;
+	unsigned long dvs;
+
+	if (parent == &clk_f)
+		dvs = 0;
+	else if (parent == &clk_h)
+		dvs = S3C2440_CAMDIVN_DVSEN;
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	camdivn  = __raw_readl(S3C2440_CAMDIVN);
+	camdivn &= ~S3C2440_CAMDIVN_DVSEN;
+	camdivn |= dvs;
+	__raw_writel(camdivn, S3C2440_CAMDIVN);
+
+	return 0;
+}
+
+static struct clk clk_arm = {
+	.name		= "armclk",
+	.id		= -1,
+	.set_parent	= s3c2440_setparent_armclk,
+};
+
+static int s3c244x_clk_add(struct sys_device *sysdev)
+{
+	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+	unsigned long clkdivn;
+	struct clk *clock_upll;
+	int ret;
+
+	printk("S3C244X: Clock Support, DVS %s\n",
+	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+
+	clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
+
+	ret = s3c24xx_register_clock(&clk_arm);
+	if (ret < 0) {
+		printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
+		return ret;
+	}
+
+	clock_upll = clk_get(NULL, "upll");
+	if (IS_ERR(clock_upll)) {
+		printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
+		return -ENOENT;
+	}
+
+	/* check rate of UPLL, and if it is near 96MHz, then change
+	 * to using half the UPLL rate for the system */
+
+	if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+		clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
+
+		mutex_lock(&clocks_mutex);
+
+		clkdivn = __raw_readl(S3C2410_CLKDIVN);
+		clkdivn |= S3C2440_CLKDIVN_UCLK;
+		__raw_writel(clkdivn, S3C2410_CLKDIVN);
+
+		mutex_unlock(&clocks_mutex);
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_clk_driver = {
+	.add		= s3c244x_clk_add,
+};
+
+static int s3c2440_clk_init(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
+}
+
+arch_initcall(s3c2440_clk_init);
+
+static struct sysdev_driver s3c2442_clk_driver = {
+	.add		= s3c244x_clk_add,
+};
+
+static int s3c2442_clk_init(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 0a9a5e7..7ed58c0 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Fri May 11 19:53:41 2007
+# Last update: Sat Jan 26 14:45:34 2008
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -266,7 +266,7 @@
 wismo			SA1100_WISMO		WISMO			249
 ezlinx			ARCH_EZLINX		EZLINX			250
 at91rm9200		ARCH_AT91RM9200		AT91RM9200		251
-orion			ARCH_ORION		ORION			252
+adtech_orion		ARCH_ADTECH_ORION	ADTECH_ORION		252
 neptune			ARCH_NEPTUNE		NEPTUNE			253
 hackkit			SA1100_HACKKIT		HACKKIT			254
 pxa_wins30		ARCH_PXA_WINS30		PXA_WINS30		255
@@ -661,7 +661,6 @@
 pnx0105			MACH_PNX0105		PNX0105			646
 adcpoecpu		MACH_ADCPOECPU		ADCPOECPU		647
 csb637			MACH_CSB637		CSB637			648
-ml69q6203		MACH_ML69Q6203		ML69Q6203		649
 mb9200			MACH_MB9200		MB9200			650
 kulun			MACH_KULUN		KULUN			651
 snapper			MACH_SNAPPER		SNAPPER			652
@@ -953,7 +952,6 @@
 ttg_color1		MACH_TTG_COLOR1		TTG_COLOR1		940
 nxeb500hmi		MACH_NXEB500HMI		NXEB500HMI		941
 netdcu8			MACH_NETDCU8		NETDCU8			942
-ml675050_cpu_boa	MACH_ML675050_CPU_BOA	ML675050_CPU_BOA	943
 ng_fvx538		MACH_NG_FVX538		NG_FVX538		944
 ng_fvs338		MACH_NG_FVS338		NG_FVS338		945
 pnx4103			MACH_PNX4103		PNX4103			946
@@ -1148,7 +1146,7 @@
 rema			MACH_REMA		REMA			1135
 bps1000			MACH_BPS1000		BPS1000			1136
 hw90350			MACH_HW90350		HW90350			1137
-omap_sdp3430		MACH_OMAP_SDP3430	OMAP_SDP3430		1138
+omap_3430sdp		MACH_OMAP_3430SDP	OMAP_3430SDP		1138
 bluetouch		MACH_BLUETOUCH		BLUETOUCH		1139
 vstms			MACH_VSTMS		VSTMS			1140
 xsbase270		MACH_XSBASE270		XSBASE270		1141
@@ -1214,7 +1212,7 @@
 kbat9261		MACH_KBAT9261		KBAT9261		1204
 ct1100			MACH_CT1100		CT1100			1205
 akcppxa			MACH_AKCPPXA		AKCPPXA			1206
-zevio_1020		MACH_ZEVIO_1020		ZEVIO_1020		1207
+ochaya1020		MACH_OCHAYA1020		OCHAYA1020		1207
 hitrack			MACH_HITRACK		HITRACK			1208
 syme1			MACH_SYME1		SYME1			1209
 syhl1			MACH_SYHL1		SYHL1			1210
@@ -1299,7 +1297,7 @@
 h4300			MACH_H4300		H4300			1291
 goramo_mlr		MACH_GORAMO_MLR		GORAMO_MLR		1292
 mxc30020evb		MACH_MXC30020EVB	MXC30020EVB		1293
-adsbitsymx		MACH_ADSBITSIMX		ADSBITSIMX		1294
+adsbitsyg5		MACH_ADSBITSYG5		ADSBITSYG5		1294
 adsportalplus		MACH_ADSPORTALPLUS	ADSPORTALPLUS		1295
 mmsp2plus		MACH_MMSP2PLUS		MMSP2PLUS		1296
 em_x270			MACH_EM_X270		EM_X270			1297
@@ -1367,3 +1365,249 @@
 csb726			MACH_CSB726		CSB726			1359
 tik27			MACH_TIK27		TIK27			1360
 mx_uc7420		MACH_MX_UC7420		MX_UC7420		1361
+rirm3			MACH_RIRM3		RIRM3			1362
+pelco_odyssey		MACH_PELCO_ODYSSEY	PELCO_ODYSSEY		1363
+adx_abox		MACH_ADX_ABOX		ADX_ABOX		1365
+adx_tpid		MACH_ADX_TPID		ADX_TPID		1366
+minicheck		MACH_MINICHECK		MINICHECK		1367
+idam			MACH_IDAM		IDAM			1368
+mario_mx		MACH_MARIO_MX		MARIO_MX		1369
+vi1888			MACH_VI1888		VI1888			1370
+zr4230			MACH_ZR4230		ZR4230			1371
+t1_ix_blue		MACH_T1_IX_BLUE		T1_IX_BLUE		1372
+syhq2			MACH_SYHQ2		SYHQ2			1373
+computime_r3		MACH_COMPUTIME_R3	COMPUTIME_R3		1374
+oratis			MACH_ORATIS		ORATIS			1375
+mikko			MACH_MIKKO		MIKKO			1376
+holon			MACH_HOLON		HOLON			1377
+olip8			MACH_OLIP8		OLIP8			1378
+ghi270hg		MACH_GHI270HG		GHI270HG		1379
+davinci_dm6467_evm	MACH_DAVINCI_DM6467_EVM	DAVINCI_DM6467_EVM	1380
+davinci_dm355_evm	MACH_DAVINCI_DM350_EVM	DAVINCI_DM350_EVM	1381
+blackriver		MACH_BLACKRIVER		BLACKRIVER		1383
+sandgate_wp		MACH_SANDGATEWP		SANDGATEWP		1384
+cdotbwsg		MACH_CDOTBWSG		CDOTBWSG		1385
+quark963		MACH_QUARK963		QUARK963		1386
+csb735			MACH_CSB735		CSB735			1387
+littleton		MACH_LITTLETON		LITTLETON		1388
+mio_p550		MACH_MIO_P550		MIO_P550		1389
+motion2440		MACH_MOTION2440		MOTION2440		1390
+imm500			MACH_IMM500		IMM500			1391
+homematic		MACH_HOMEMATIC		HOMEMATIC		1392
+ermine			MACH_ERMINE		ERMINE			1393
+kb9202b			MACH_KB9202B		KB9202B			1394
+hs1xx			MACH_HS1XX		HS1XX			1395
+studentmate2440		MACH_STUDENTMATE2440	STUDENTMATE2440		1396
+arvoo_l1_z1		MACH_ARVOO_L1_Z1	ARVOO_L1_Z1		1397
+dep2410k		MACH_DEP2410K		DEP2410K		1398
+xxsvideo		MACH_XXSVIDEO		XXSVIDEO		1399
+im4004			MACH_IM4004		IM4004			1400
+ochaya1050		MACH_OCHAYA1050		OCHAYA1050		1401
+lep9261			MACH_LEP9261		LEP9261			1402
+svenmeb			MACH_SVENMEB		SVENMEB			1403
+fortunet2ne		MACH_FORTUNET2NE	FORTUNET2NE		1404
+nxhx			MACH_NXHX		NXHX			1406
+realview_pb11mp		MACH_REALVIEW_PB11MP	REALVIEW_PB11MP		1407
+ids500			MACH_IDS500		IDS500			1408
+ors_n725		MACH_ORS_N725		ORS_N725		1409
+hsdarm			MACH_HSDARM		HSDARM			1410
+sha_pon003		MACH_SHA_PON003		SHA_PON003		1411
+sha_pon004		MACH_SHA_PON004		SHA_PON004		1412
+sha_pon007		MACH_SHA_PON007		SHA_PON007		1413
+sha_pon011		MACH_SHA_PON011		SHA_PON011		1414
+h6042			MACH_H6042		H6042			1415
+h6043			MACH_H6043		H6043			1416
+looxc550		MACH_LOOXC550		LOOXC550		1417
+cnty_titan		MACH_CNTY_TITAN		CNTY_TITAN		1418
+app3xx			MACH_APP3XX		APP3XX			1419
+sideoatsgrama		MACH_SIDEOATSGRAMA	SIDEOATSGRAMA		1420
+xscale_palmt700p	MACH_XSCALE_PALMT700P	XSCALE_PALMT700P	1421
+xscale_palmt700w	MACH_XSCALE_PALMT700W	XSCALE_PALMT700W	1422
+xscale_palmt750		MACH_XSCALE_PALMT750	XSCALE_PALMT750		1423
+xscale_palmt755p	MACH_XSCALE_PALMT755P	XSCALE_PALMT755P	1424
+ezreganut9200		MACH_EZREGANUT9200	EZREGANUT9200		1425
+sarge			MACH_SARGE		SARGE			1426
+a696			MACH_A696		A696			1427
+turtle1916		MACH_TURTLE		TURTLE			1428
+mx27_3ds		MACH_MX27_3DS		MX27_3DS		1430
+bishop			MACH_BISHOP		BISHOP			1431
+pxx			MACH_PXX		PXX			1432
+redwood			MACH_REDWOOD		REDWOOD			1433
+omap_2430dlp		MACH_OMAP_2430DLP	OMAP_2430DLP		1436
+omap_2430osk		MACH_OMAP_2430OSK	OMAP_2430OSK		1437
+sardine			MACH_SARDINE		SARDINE			1438
+halibut			MACH_HALIBUT		HALIBUT			1439
+trout			MACH_TROUT		TROUT			1440
+goldfish		MACH_GOLDFISH		GOLDFISH		1441
+gesbc2440		MACH_GESBC2440		GESBC2440		1442
+nomad			MACH_NOMAD		NOMAD			1443
+rosalind		MACH_ROSALIND		ROSALIND		1444
+cc9p9215		MACH_CC9P9215		CC9P9215		1445
+cc9p9210		MACH_CC9P9210		CC9P9210		1446
+cc9p9215js		MACH_CC9P9215JS		CC9P9215JS		1447
+cc9p9210js		MACH_CC9P9210JS		CC9P9210JS		1448
+nasffe			MACH_NASFFE		NASFFE			1449
+tn2x0bd			MACH_TN2X0BD		TN2X0BD			1450
+gwmpxa			MACH_GWMPXA		GWMPXA			1451
+exyplus			MACH_EXYPLUS		EXYPLUS			1452
+jadoo21			MACH_JADOO21		JADOO21			1453
+looxn560		MACH_LOOXN560		LOOXN560		1454
+bonsai			MACH_BONSAI		BONSAI			1455
+adsmilgato		MACH_ADSMILGATO		ADSMILGATO		1456
+gba			MACH_GBA		GBA			1457
+h6044			MACH_H6044		H6044			1458
+app			MACH_APP		APP			1459
+tct_hammer		MACH_TCT_HAMMER		TCT_HAMMER		1460
+herald			MACH_HERMES		HERMES			1461
+artemis			MACH_ARTEMIS		ARTEMIS			1462
+htctitan		MACH_HTCTITAN		HTCTITAN		1463
+qranium			MACH_QRANIUM		QRANIUM			1464
+adx_wsc2		MACH_ADX_WSC2		ADX_WSC2		1465
+adx_medinet		MACH_ADX_MEDINET	ADX_MEDINET		1466
+bboard			MACH_BBOARD		BBOARD			1467
+cambria			MACH_CAMBRIA		CAMBRIA			1468
+mt7xxx			MACH_MT7XXX		MT7XXX			1469
+matrix512		MACH_MATRIX512		MATRIX512		1470
+matrix522		MACH_MATRIX522		MATRIX522		1471
+ipac5010		MACH_IPAC5010		IPAC5010		1472
+sakura			MACH_SAKURA		SAKURA			1473
+grocx			MACH_GROCX		GROCX			1474
+pm9263			MACH_PM9263		PM9263			1475
+sim_one			MACH_SIM_ONE		SIM_ONE			1476
+acq132			MACH_ACQ132		ACQ132			1477
+datr			MACH_DATR		DATR			1478
+actux1			MACH_ACTUX1		ACTUX1			1479
+actux2			MACH_ACTUX2		ACTUX2			1480
+actux3			MACH_ACTUX3		ACTUX3			1481
+flexit			MACH_FLEXIT		FLEXIT			1482
+bh2x0bd			MACH_BH2X0BD		BH2X0BD			1483
+atb2002			MACH_ATB2002		ATB2002			1484
+xenon			MACH_XENON		XENON			1485
+fm607			MACH_FM607		FM607			1486
+matrix514		MACH_MATRIX514		MATRIX514		1487
+matrix524		MACH_MATRIX524		MATRIX524		1488
+inpod			MACH_INPOD		INPOD			1489
+jive			MACH_JIVE		JIVE			1490
+tll_mx21		MACH_TLL_MX21		TLL_MX21		1491
+sbc2800			MACH_SBC2800		SBC2800			1492
+cc7ucamry		MACH_CC7UCAMRY		CC7UCAMRY		1493
+ubisys_p9_sc15		MACH_UBISYS_P9_SC15	UBISYS_P9_SC15		1494
+ubisys_p9_ssc2d10	MACH_UBISYS_P9_SSC2D10	UBISYS_P9_SSC2D10	1495
+ubisys_p9_rcu3		MACH_UBISYS_P9_RCU3	UBISYS_P9_RCU3		1496
+aml_m8000		MACH_AML_M8000		AML_M8000		1497
+snapper_270		MACH_SNAPPER_270	SNAPPER_270		1498
+omap_bbx		MACH_OMAP_BBX		OMAP_BBX		1499
+ucn2410			MACH_UCN2410		UCN2410			1500
+sam9_l9260		MACH_SAM9_L9260		SAM9_L9260		1501
+eti_c2			MACH_ETI_C2		ETI_C2			1502
+avalanche		MACH_AVALANCHE		AVALANCHE		1503
+realview_pb1176		MACH_REALVIEW_PB1176	REALVIEW_PB1176		1504
+dp1500			MACH_DP1500		DP1500			1505
+apple_iphone		MACH_APPLE_IPHONE	APPLE_IPHONE		1506
+yl9200			MACH_YL9200		YL9200			1507
+rd88f5182		MACH_RD88F5182		RD88F5182		1508
+kurobox_pro		MACH_KUROBOX_PRO	KUROBOX_PRO		1509
+se_poet			MACH_SE_POET		SE_POET			1510
+mx31_3ds		MACH_MX31_3DS		MX31_3DS		1511
+r270			MACH_R270		R270			1512
+armour21		MACH_ARMOUR21		ARMOUR21		1513
+dt2			MACH_DT2		DT2			1514
+vt4			MACH_VT4		VT4			1515
+tyco320			MACH_TYCO320		TYCO320			1516
+adma			MACH_ADMA		ADMA			1517
+wp188			MACH_WP188		WP188			1518
+corsica			MACH_CORSICA		CORSICA			1519
+bigeye			MACH_BIGEYE		BIGEYE			1520
+tll5000			MACH_TLL5000		TLL5000			1522
+hni270			MACH_HNI_X270		HNI_X270		1523
+qong			MACH_QONG		QONG			1524
+tcompact		MACH_TCOMPACT		TCOMPACT		1525
+puma5			MACH_PUMA5		PUMA5			1526
+elara			MACH_ELARA		ELARA			1527
+ellington		MACH_ELLINGTON		ELLINGTON		1528
+xda_atom		MACH_XDA_ATOM		XDA_ATOM		1529
+energizer2		MACH_ENERGIZER2		ENERGIZER2		1530
+odin			MACH_ODIN		ODIN			1531
+actux4			MACH_ACTUX4		ACTUX4			1532
+esl_omap		MACH_ESL_OMAP		ESL_OMAP		1533
+omap2evm		MACH_OMAP2EVM		OMAP2EVM		1534
+omap3evm		MACH_OMAP3EVM		OMAP3EVM		1535
+adx_pcu57		MACH_ADX_PCU57		ADX_PCU57		1536
+monaco			MACH_MONACO		MONACO			1537
+levante			MACH_LEVANTE		LEVANTE			1538
+tmxipx425		MACH_TMXIPX425		TMXIPX425		1539
+leep			MACH_LEEP		LEEP			1540
+raad			MACH_RAAD		RAAD			1541
+dns323			MACH_DNS323		DNS323			1542
+ap1000			MACH_AP1000		AP1000			1543
+a9sam6432		MACH_A9SAM6432		A9SAM6432		1544
+shiny			MACH_SHINY		SHINY			1545
+omap3_beagle		MACH_OMAP3_BEAGLE	OMAP3_BEAGLE		1546
+csr_bdb2		MACH_CSR_BDB2		CSR_BDB2		1547
+nokia_n810		MACH_NOKIA_N810		NOKIA_N810		1548
+c270			MACH_C270		C270			1549
+sentry			MACH_SENTRY		SENTRY			1550
+pcm038			MACH_PCM038		PCM038			1551
+anc300			MACH_ANC300		ANC300			1552
+htckaiser		MACH_HTCKAISER		HTCKAISER		1553
+sbat100			MACH_SBAT100		SBAT100			1554
+modunorm		MACH_MODUNORM		MODUNORM		1555
+pelos_twarm		MACH_PELOS_TWARM	PELOS_TWARM		1556
+flank			MACH_FLANK		FLANK			1557
+sirloin			MACH_SIRLOIN		SIRLOIN			1558
+brisket			MACH_BRISKET		BRISKET			1559
+chuck			MACH_CHUCK		CHUCK			1560
+otter			MACH_OTTER		OTTER			1561
+davinci_ldk		MACH_DAVINCI_LDK	DAVINCI_LDK		1562
+phreedom		MACH_PHREEDOM		PHREEDOM		1563
+sg310			MACH_SG310		SG310			1564
+ts_x09			MACH_TS209		TS209			1565
+at91cap9adk		MACH_AT91CAP9ADK	AT91CAP9ADK		1566
+tion9315		MACH_TION9315		TION9315		1567
+mast			MACH_MAST		MAST			1568
+pfw			MACH_PFW		PFW			1569
+yl_p2440		MACH_YL_P2440		YL_P2440		1570
+zsbc32			MACH_ZSBC32		ZSBC32			1571
+omap_pace2		MACH_OMAP_PACE2		OMAP_PACE2		1572
+imx_pace2		MACH_IMX_PACE2		IMX_PACE2		1573
+mx31moboard		MACH_MX31MOBOARD	MX31MOBOARD		1574
+mx37_3ds		MACH_MX37_3DS		MX37_3DS		1575
+rcc			MACH_RCC		RCC			1576
+dmp			MACH_ARM9		ARM9			1577
+vision_ep9307		MACH_VISION_EP9307	VISION_EP9307		1578
+scly1000		MACH_SCLY1000		SCLY1000		1579
+fontel_ep		MACH_FONTEL_EP		FONTEL_EP		1580
+voiceblue3g		MACH_VOICEBLUE3G	VOICEBLUE3G		1581
+tt9200			MACH_TT9200		TT9200			1582
+digi2410		MACH_DIGI2410		DIGI2410		1583
+terastation_pro2	MACH_TERASTATION_PRO2	TERASTATION_PRO2	1584
+linkstation_pro		MACH_LINKSTATION_PRO	LINKSTATION_PRO		1585
+motorola_a780		MACH_MOTOROLA_A780	MOTOROLA_A780		1587
+motorola_e6		MACH_MOTOROLA_E6	MOTOROLA_E6		1588
+motorola_e2		MACH_MOTOROLA_E2	MOTOROLA_E2		1589
+motorola_e680		MACH_MOTOROLA_E680	MOTOROLA_E680		1590
+ur2410			MACH_UR2410		UR2410			1591
+tas9261			MACH_TAS9261		TAS9261			1592
+davinci_hermes_hd	MACH_HERMES_HD		HERMES_HD		1593
+davinci_perseo_hd	MACH_PERSEO_HD		PERSEO_HD		1594
+stargazer2		MACH_STARGAZER2		STARGAZER2		1595
+e350			MACH_E350		E350			1596
+wpcm450			MACH_WPCM450		WPCM450			1597
+cartesio		MACH_CARTESIO		CARTESIO		1598
+toybox			MACH_TOYBOX		TOYBOX			1599
+tx27			MACH_TX27		TX27			1600
+ts409			MACH_TS409		TS409			1601
+p300			MACH_P300		P300			1602
+xdacomet		MACH_XDACOMET		XDACOMET		1603
+dexflex2		MACH_DEXFLEX2		DEXFLEX2		1604
+ow			MACH_OW			OW			1605
+armebs3			MACH_ARMEBS3		ARMEBS3			1606
+u3			MACH_U3			U3			1607
+smdk2450		MACH_SMDK2450		SMDK2450		1608
+rsi_ews			MACH_RSI_EWS		RSI_EWS			1609
+tnb			MACH_TNB		TNB			1610
+toepath			MACH_TOEPATH		TOEPATH			1611
+kb9263			MACH_KB9263		KB9263			1612
+mt7108			MACH_MT7108		MT7108			1613
+smtr2440		MACH_SMTR2440		SMTR2440		1614
+manao			MACH_MANAO		MANAO			1615
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index 791d023..c85860b 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -265,7 +265,11 @@
  * which returns (double)0.0.  This is useful for the compare with
  * zero instructions.
  */
+#ifdef CONFIG_VFPv3
+#define VFP_REG_ZERO	32
+#else
 #define VFP_REG_ZERO	16
+#endif
 extern u64 vfp_get_double(unsigned int reg);
 extern void vfp_put_double(u64 val, unsigned int reg);
 
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 0ac022f..353f9e5 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -99,12 +99,12 @@
 	DBGSTR1	"save old state %p", r4
 	cmp	r4, #0
 	beq	no_old_VFP_process
+	VFPFSTMIA r4, r5		@ save the working registers
 	VFPFMRX	r5, FPSCR		@ current status
-	VFPFMRX	r6, FPINST		@ FPINST (always there, rev0 onwards)
-	tst	r1, #FPEXC_FPV2		@ is there an FPINST2 to read?
-	VFPFMRX	r8, FPINST2, NE		@ FPINST2 if needed - avoids reading
-					@ nonexistant reg on rev0
-	VFPFSTMIA r4 			@ save the working registers
+	tst	r1, #FPEXC_EX		@ is there additional state to save?
+	VFPFMRX	r6, FPINST, NE		@ FPINST (only if FPEXC.EX is set)
+	tstne	r1, #FPEXC_FP2V		@ is there an FPINST2 to read?
+	VFPFMRX	r8, FPINST2, NE		@ FPINST2 if needed (and present)
 	stmia	r4, {r1, r5, r6, r8}	@ save FPEXC, FPSCR, FPINST, FPINST2
 					@ and point r4 at the word at the
 					@ start of the register dump
@@ -114,13 +114,13 @@
 	DBGSTR1	"load state %p", r10
 	str	r10, [r3, r11, lsl #2]	@ update the last_VFP_context pointer
 					@ Load the saved state back into the VFP
-	VFPFLDMIA r10	 		@ reload the working registers while
+	VFPFLDMIA r10, r5		@ reload the working registers while
 					@ FPEXC is in a safe state
 	ldmia	r10, {r1, r5, r6, r8}	@ load FPEXC, FPSCR, FPINST, FPINST2
-	tst	r1, #FPEXC_FPV2		@ is there an FPINST2 to write?
-	VFPFMXR	FPINST2, r8, NE		@ FPINST2 if needed - avoids writing
-					@ nonexistant reg on rev0
-	VFPFMXR	FPINST, r6
+	tst	r1, #FPEXC_EX		@ is there additional state to restore?
+	VFPFMXR	FPINST, r6, NE		@ restore FPINST (only if FPEXC.EX is set)
+	tstne	r1, #FPEXC_FP2V		@ is there an FPINST2 to write?
+	VFPFMXR	FPINST2, r8, NE		@ FPINST2 if needed (and present)
 	VFPFMXR	FPSCR, r5		@ restore status
 
 check_for_exception:
@@ -136,10 +136,14 @@
 
 
 look_for_VFP_exceptions:
-	tst	r1, #FPEXC_EX
+	@ Check for synchronous or asynchronous exception
+	tst	r1, #FPEXC_EX | FPEXC_DEX
 	bne	process_exception
+	@ On some implementations of the VFP subarch 1, setting FPSCR.IXE
+	@ causes all the CDP instructions to be bounced synchronously without
+	@ setting the FPEXC.EX bit
 	VFPFMRX	r5, FPSCR
-	tst	r5, #FPSCR_IXE		@ IXE doesn't set FPEXC_EX !
+	tst	r5, #FPSCR_IXE
 	bne	process_exception
 
 	@ Fall into hand on to next handler - appropriate coproc instr
@@ -150,10 +154,6 @@
 
 process_exception:
 	DBGSTR	"bounce"
-	sub	r2, r2, #4
-	str	r2, [sp, #S_PC]		@ retry the instruction on exit from
-					@ the imprecise exception handling in
-					@ the support code
 	mov	r2, sp			@ nothing stacked - regdump is at TOS
 	mov	lr, r9			@ setup for a return to the user code.
 
@@ -161,7 +161,7 @@
 	@   r0 holds the trigger instruction
 	@   r1 holds the FPEXC value
 	@   r2 pointer to register dump
-	b	VFP9_bounce		@ we have handled this - the support
+	b	VFP_bounce		@ we have handled this - the support
 					@ code will raise an exception if
 					@ required. If not, the user code will
 					@ retry the faulted instruction
@@ -174,12 +174,12 @@
 	@ r0 - save location
 	@ r1 - FPEXC
 	DBGSTR1	"save VFP state %p", r0
+	VFPFSTMIA r0, r2		@ save the working registers
 	VFPFMRX	r2, FPSCR		@ current status
-	VFPFMRX	r3, FPINST		@ FPINST (always there, rev0 onwards)
-	tst	r1, #FPEXC_FPV2		@ is there an FPINST2 to read?
-	VFPFMRX	r12, FPINST2, NE	@ FPINST2 if needed - avoids reading
-					@ nonexistant reg on rev0
-	VFPFSTMIA r0 			@ save the working registers
+	tst	r1, #FPEXC_EX		@ is there additional state to save?
+	VFPFMRX	r3, FPINST, NE		@ FPINST (only if FPEXC.EX is set)
+	tstne	r1, #FPEXC_FP2V		@ is there an FPINST2 to read?
+	VFPFMRX	r12, FPINST2, NE	@ FPINST2 if needed (and present)
 	stmia	r0, {r1, r2, r3, r12}	@ save FPEXC, FPSCR, FPINST, FPINST2
 	mov	pc, lr
 #endif
@@ -217,8 +217,15 @@
 	fmrrd	r0, r1, d\dr
 	mov	pc, lr
 	.endr
+#ifdef CONFIG_VFPv3
+	@ d16 - d31 registers
+	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+	mrrc	p11, 3, r0, r1, c\dr	@ fmrrd	r0, r1, d\dr
+	mov	pc, lr
+	.endr
+#endif
 
-	@ virtual register 16 for compare with zero
+	@ virtual register 16 (or 32 if VFPv3) for compare with zero
 	mov	r0, #0
 	mov	r1, #0
 	mov	pc, lr
@@ -231,3 +238,10 @@
 	fmdrr	d\dr, r0, r1
 	mov	pc, lr
 	.endr
+#ifdef CONFIG_VFPv3
+	@ d16 - d31 registers
+	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+	mcrr	p11, 3, r1, r2, c\dr	@ fmdrr	r1, r2, d\dr
+	mov	pc, lr
+	.endr
+#endif
diff --git a/arch/arm/vfp/vfpinstr.h b/arch/arm/vfp/vfpinstr.h
index 7f343a4..15b95b5 100644
--- a/arch/arm/vfp/vfpinstr.h
+++ b/arch/arm/vfp/vfpinstr.h
@@ -52,11 +52,11 @@
 #define FEXT_TO_IDX(inst)	((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7)
 
 #define vfp_get_sd(inst)	((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22)
-#define vfp_get_dd(inst)	((inst & 0x0000f000) >> 12)
+#define vfp_get_dd(inst)	((inst & 0x0000f000) >> 12 | (inst & (1 << 22)) >> 18)
 #define vfp_get_sm(inst)	((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5)
-#define vfp_get_dm(inst)	((inst & 0x0000000f))
+#define vfp_get_dm(inst)	((inst & 0x0000000f) | (inst & (1 << 5)) >> 1)
 #define vfp_get_sn(inst)	((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7)
-#define vfp_get_dn(inst)	((inst & 0x000f0000) >> 16)
+#define vfp_get_dn(inst)	((inst & 0x000f0000) >> 16 | (inst & (1 << 7)) >> 3)
 
 #define vfp_single(inst)	(((inst) & 0x0000f00) == 0xa00)
 
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index b4e210d..32455c6 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -125,13 +125,13 @@
 	send_sig_info(SIGFPE, &info, current);
 }
 
-static void vfp_panic(char *reason)
+static void vfp_panic(char *reason, u32 inst)
 {
 	int i;
 
 	printk(KERN_ERR "VFP: Error: %s\n", reason);
 	printk(KERN_ERR "VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n",
-		fmrx(FPEXC), fmrx(FPSCR), fmrx(FPINST));
+		fmrx(FPEXC), fmrx(FPSCR), inst);
 	for (i = 0; i < 32; i += 2)
 		printk(KERN_ERR "VFP: s%2u: 0x%08x s%2u: 0x%08x\n",
 		       i, vfp_get_float(i), i+1, vfp_get_float(i+1));
@@ -147,19 +147,16 @@
 	pr_debug("VFP: raising exceptions %08x\n", exceptions);
 
 	if (exceptions == VFP_EXCEPTION_ERROR) {
-		vfp_panic("unhandled bounce");
+		vfp_panic("unhandled bounce", inst);
 		vfp_raise_sigfpe(0, regs);
 		return;
 	}
 
 	/*
-	 * If any of the status flags are set, update the FPSCR.
+	 * Update the FPSCR with the additional exception flags.
 	 * Comparison instructions always return at least one of
 	 * these flags set.
 	 */
-	if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V))
-		fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V);
-
 	fpscr |= exceptions;
 
 	fmxr(FPSCR, fpscr);
@@ -220,35 +217,64 @@
 /*
  * Package up a bounce condition.
  */
-void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
+void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
 {
-	u32 fpscr, orig_fpscr, exceptions, inst;
+	u32 fpscr, orig_fpscr, fpsid, exceptions;
 
 	pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc);
 
 	/*
-	 * Enable access to the VFP so we can handle the bounce.
+	 * At this point, FPEXC can have the following configuration:
+	 *
+	 *  EX DEX IXE
+	 *  0   1   x   - synchronous exception
+	 *  1   x   0   - asynchronous exception
+	 *  1   x   1   - sychronous on VFP subarch 1 and asynchronous on later
+	 *  0   0   1   - synchronous on VFP9 (non-standard subarch 1
+	 *                implementation), undefined otherwise
+	 *
+	 * Clear various bits and enable access to the VFP so we can
+	 * handle the bounce.
 	 */
-	fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_FPV2|FPEXC_INV|FPEXC_UFC|FPEXC_OFC|FPEXC_IOC));
+	fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_DEX|FPEXC_FP2V|FPEXC_VV|FPEXC_TRAP_MASK));
 
+	fpsid = fmrx(FPSID);
 	orig_fpscr = fpscr = fmrx(FPSCR);
 
 	/*
-	 * If we are running with inexact exceptions enabled, we need to
-	 * emulate the trigger instruction.  Note that as we're emulating
-	 * the trigger instruction, we need to increment PC.
+	 * Check for the special VFP subarch 1 and FPSCR.IXE bit case
 	 */
-	if (fpscr & FPSCR_IXE) {
-		regs->ARM_pc += 4;
+	if ((fpsid & FPSID_ARCH_MASK) == (1 << FPSID_ARCH_BIT)
+	    && (fpscr & FPSCR_IXE)) {
+		/*
+		 * Synchronous exception, emulate the trigger instruction
+		 */
 		goto emulate;
 	}
 
-	barrier();
+	if (fpexc & FPEXC_EX) {
+		/*
+		 * Asynchronous exception. The instruction is read from FPINST
+		 * and the interrupted instruction has to be restarted.
+		 */
+		trigger = fmrx(FPINST);
+		regs->ARM_pc -= 4;
+	} else if (!(fpexc & FPEXC_DEX)) {
+		/*
+		 * Illegal combination of bits. It can be caused by an
+		 * unallocated VFP instruction but with FPSCR.IXE set and not
+		 * on VFP subarch 1.
+		 */
+		 vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs);
+		 return;
+	}
 
 	/*
-	 * Modify fpscr to indicate the number of iterations remaining
+	 * Modify fpscr to indicate the number of iterations remaining.
+	 * If FPEXC.EX is 0, FPEXC.DEX is 1 and the FPEXC.VV bit indicates
+	 * whether FPEXC.VECITR or FPSCR.LEN is used.
 	 */
-	if (fpexc & FPEXC_EX) {
+	if (fpexc & (FPEXC_EX | FPEXC_VV)) {
 		u32 len;
 
 		len = fpexc + (1 << FPEXC_LENGTH_BIT);
@@ -262,15 +288,15 @@
 	 * FPEXC bounce reason, but this appears to be unreliable.
 	 * Emulate the bounced instruction instead.
 	 */
-	inst = fmrx(FPINST);
-	exceptions = vfp_emulate_instruction(inst, fpscr, regs);
+	exceptions = vfp_emulate_instruction(trigger, fpscr, regs);
 	if (exceptions)
-		vfp_raise_exceptions(exceptions, inst, orig_fpscr, regs);
+		vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
 
 	/*
-	 * If there isn't a second FP instruction, exit now.
+	 * If there isn't a second FP instruction, exit now. Note that
+	 * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
 	 */
-	if (!(fpexc & FPEXC_FPV2))
+	if (fpexc ^ (FPEXC_EX | FPEXC_FP2V))
 		return;
 
 	/*
@@ -279,10 +305,9 @@
 	 */
 	barrier();
 	trigger = fmrx(FPINST2);
-	orig_fpscr = fpscr = fmrx(FPSCR);
 
  emulate:
-	exceptions = vfp_emulate_instruction(trigger, fpscr, regs);
+	exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs);
 	if (exceptions)
 		vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
 }
@@ -306,16 +331,9 @@
 {
 	unsigned int vfpsid;
 	unsigned int cpu_arch = cpu_architecture();
-	u32 access = 0;
 
-	if (cpu_arch >= CPU_ARCH_ARMv6) {
-		access = get_copro_access();
-
-		/*
-		 * Enable full access to VFP (cp10 and cp11)
-		 */
-		set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
-	}
+	if (cpu_arch >= CPU_ARCH_ARMv6)
+		vfp_enable(NULL);
 
 	/*
 	 * First check that there is a VFP that we can use.
@@ -329,15 +347,9 @@
 	vfp_vector = vfp_null_entry;
 
 	printk(KERN_INFO "VFP support v0.3: ");
-	if (VFP_arch) {
+	if (VFP_arch)
 		printk("not present\n");
-
-		/*
-		 * Restore the copro access register.
-		 */
-		if (cpu_arch >= CPU_ARCH_ARMv6)
-			set_copro_access(access);
-	} else if (vfpsid & FPSID_NODOUBLE) {
+	else if (vfpsid & FPSID_NODOUBLE) {
 		printk("no double precision support\n");
 	} else {
 		smp_call_function(vfp_enable, NULL, 1, 1);
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 548a320..4316f5a 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -361,12 +361,6 @@
 	else
 		pdata.timeout = 1000;	/* 1 second */
 
-	prop = of_get_property(np, "retries", NULL);
-	if (prop)
-		pdata.retries = *prop;
-	else
-		pdata.retries = 1;
-
 	pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id);
 	if (!pdev)
 		return -ENOMEM;
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 2744b8a..90fe904 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -411,7 +411,6 @@
 	.freq_m			= 8,
 	.freq_n			= 3,
 	.timeout		= 1000, /* Default timeout of 1 second */
-	.retries		= 1,
 };
 
 static struct resource mv64xxx_i2c_resources[] = {
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index b1a77b1..99f9f96 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -475,17 +475,9 @@
 /* Only changed by ubd_init, which is an initcall. */
 int thread_fd = -1;
 
-static void ubd_end_request(struct request *req, int bytes, int uptodate)
+static void ubd_end_request(struct request *req, int bytes, int error)
 {
-	if (!end_that_request_first(req, uptodate, bytes >> 9)) {
-		struct ubd *dev = req->rq_disk->private_data;
-		unsigned long flags;
-
-		add_disk_randomness(req->rq_disk);
-		spin_lock_irqsave(&dev->lock, flags);
-		end_that_request_last(req, uptodate);
-		spin_unlock_irqrestore(&dev->lock, flags);
-	}
+	blk_end_request(req, error, bytes);
 }
 
 /* Callable only from interrupt context - otherwise you need to do
@@ -493,10 +485,10 @@
 static inline void ubd_finish(struct request *req, int bytes)
 {
 	if(bytes < 0){
-		ubd_end_request(req, 0, 0);
+		ubd_end_request(req, 0, -EIO);
 		return;
 	}
-	ubd_end_request(req, bytes, 1);
+	ubd_end_request(req, bytes, 0);
 }
 
 static LIST_HEAD(restart);
diff --git a/block/as-iosched.c b/block/as-iosched.c
index cb5e53b..b201d16 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -170,9 +170,11 @@
 
 static void as_trim(struct io_context *ioc)
 {
+	spin_lock(&ioc->lock);
 	if (ioc->aic)
 		free_as_io_context(ioc->aic);
 	ioc->aic = NULL;
+	spin_unlock(&ioc->lock);
 }
 
 /* Called when the task exits */
@@ -462,7 +464,9 @@
 	spin_lock_irqsave(q->queue_lock, flags);
 	if (ad->antic_status == ANTIC_WAIT_REQ
 			|| ad->antic_status == ANTIC_WAIT_NEXT) {
-		struct as_io_context *aic = ad->io_context->aic;
+		struct as_io_context *aic;
+		spin_lock(&ad->io_context->lock);
+		aic = ad->io_context->aic;
 
 		ad->antic_status = ANTIC_FINISHED;
 		kblockd_schedule_work(&ad->antic_work);
@@ -475,6 +479,7 @@
 			/* process not "saved" by a cooperating request */
 			ad->exit_no_coop = (7*ad->exit_no_coop + 256)/8;
 		}
+		spin_unlock(&ad->io_context->lock);
 	}
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
@@ -635,9 +640,11 @@
 
 	ioc = ad->io_context;
 	BUG_ON(!ioc);
+	spin_lock(&ioc->lock);
 
 	if (rq && ioc == RQ_IOC(rq)) {
 		/* request from same process */
+		spin_unlock(&ioc->lock);
 		return 1;
 	}
 
@@ -646,20 +653,25 @@
 		 * In this situation status should really be FINISHED,
 		 * however the timer hasn't had the chance to run yet.
 		 */
+		spin_unlock(&ioc->lock);
 		return 1;
 	}
 
 	aic = ioc->aic;
-	if (!aic)
+	if (!aic) {
+		spin_unlock(&ioc->lock);
 		return 0;
+	}
 
 	if (atomic_read(&aic->nr_queued) > 0) {
 		/* process has more requests queued */
+		spin_unlock(&ioc->lock);
 		return 1;
 	}
 
 	if (atomic_read(&aic->nr_dispatched) > 0) {
 		/* process has more requests dispatched */
+		spin_unlock(&ioc->lock);
 		return 1;
 	}
 
@@ -680,6 +692,7 @@
 		}
 
 		as_update_iohist(ad, aic, rq);
+		spin_unlock(&ioc->lock);
 		return 1;
 	}
 
@@ -688,20 +701,27 @@
 		if (aic->ttime_samples == 0)
 			ad->exit_prob = (7*ad->exit_prob + 256)/8;
 
-		if (ad->exit_no_coop > 128)
+		if (ad->exit_no_coop > 128) {
+			spin_unlock(&ioc->lock);
 			return 1;
+		}
 	}
 
 	if (aic->ttime_samples == 0) {
-		if (ad->new_ttime_mean > ad->antic_expire)
+		if (ad->new_ttime_mean > ad->antic_expire) {
+			spin_unlock(&ioc->lock);
 			return 1;
-		if (ad->exit_prob * ad->exit_no_coop > 128*256)
+		}
+		if (ad->exit_prob * ad->exit_no_coop > 128*256) {
+			spin_unlock(&ioc->lock);
 			return 1;
+		}
 	} else if (aic->ttime_mean > ad->antic_expire) {
 		/* the process thinks too much between requests */
+		spin_unlock(&ioc->lock);
 		return 1;
 	}
-
+	spin_unlock(&ioc->lock);
 	return 0;
 }
 
@@ -1255,7 +1275,9 @@
 			 * Don't copy here but swap, because when anext is
 			 * removed below, it must contain the unused context
 			 */
+			double_spin_lock(&rioc->lock, &nioc->lock, rioc < nioc);
 			swap_io_context(&rioc, &nioc);
+			double_spin_unlock(&rioc->lock, &nioc->lock, rioc < nioc);
 		}
 	}
 
diff --git a/block/blktrace.c b/block/blktrace.c
index 9b4da4a..568588c 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -235,7 +235,7 @@
 	kfree(bt);
 }
 
-static int blk_trace_remove(struct request_queue *q)
+int blk_trace_remove(struct request_queue *q)
 {
 	struct blk_trace *bt;
 
@@ -249,6 +249,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(blk_trace_remove);
 
 static int blk_dropped_open(struct inode *inode, struct file *filp)
 {
@@ -316,18 +317,17 @@
 /*
  * Setup everything required to start tracing
  */
-int do_blk_trace_setup(struct request_queue *q, struct block_device *bdev,
+int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
 			struct blk_user_trace_setup *buts)
 {
 	struct blk_trace *old_bt, *bt = NULL;
 	struct dentry *dir = NULL;
-	char b[BDEVNAME_SIZE];
 	int ret, i;
 
 	if (!buts->buf_size || !buts->buf_nr)
 		return -EINVAL;
 
-	strcpy(buts->name, bdevname(bdev, b));
+	strcpy(buts->name, name);
 
 	/*
 	 * some device names have larger paths - convert the slashes
@@ -352,7 +352,7 @@
 		goto err;
 
 	bt->dir = dir;
-	bt->dev = bdev->bd_dev;
+	bt->dev = dev;
 	atomic_set(&bt->dropped, 0);
 
 	ret = -EIO;
@@ -399,8 +399,8 @@
 	return ret;
 }
 
-static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
-			   char __user *arg)
+int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+		    char __user *arg)
 {
 	struct blk_user_trace_setup buts;
 	int ret;
@@ -409,7 +409,7 @@
 	if (ret)
 		return -EFAULT;
 
-	ret = do_blk_trace_setup(q, bdev, &buts);
+	ret = do_blk_trace_setup(q, name, dev, &buts);
 	if (ret)
 		return ret;
 
@@ -418,8 +418,9 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(blk_trace_setup);
 
-static int blk_trace_startstop(struct request_queue *q, int start)
+int blk_trace_startstop(struct request_queue *q, int start)
 {
 	struct blk_trace *bt;
 	int ret;
@@ -452,6 +453,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(blk_trace_startstop);
 
 /**
  * blk_trace_ioctl: - handle the ioctls associated with tracing
@@ -464,6 +466,7 @@
 {
 	struct request_queue *q;
 	int ret, start = 0;
+	char b[BDEVNAME_SIZE];
 
 	q = bdev_get_queue(bdev);
 	if (!q)
@@ -473,7 +476,8 @@
 
 	switch (cmd) {
 	case BLKTRACESETUP:
-		ret = blk_trace_setup(q, bdev, arg);
+		strcpy(b, bdevname(bdev, b));
+		ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
 		break;
 	case BLKTRACESTART:
 		start = 1;
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 13553e0..f28d1fb 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -26,9 +26,9 @@
 static int cfq_slice_idle = HZ / 125;
 
 /*
- * grace period before allowing idle class to get disk access
+ * offset from end of service tree
  */
-#define CFQ_IDLE_GRACE		(HZ / 10)
+#define CFQ_IDLE_DELAY		(HZ / 5)
 
 /*
  * below this threshold, we consider thinktime immediate
@@ -98,8 +98,6 @@
 	struct cfq_queue *async_cfqq[2][IOPRIO_BE_NR];
 	struct cfq_queue *async_idle_cfqq;
 
-	struct timer_list idle_class_timer;
-
 	sector_t last_position;
 	unsigned long last_end_request;
 
@@ -199,8 +197,8 @@
 
 static void cfq_dispatch_insert(struct request_queue *, struct request *);
 static struct cfq_queue *cfq_get_queue(struct cfq_data *, int,
-				       struct task_struct *, gfp_t);
-static struct cfq_io_context *cfq_cic_rb_lookup(struct cfq_data *,
+				       struct io_context *, gfp_t);
+static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *,
 						struct io_context *);
 
 static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic,
@@ -384,12 +382,15 @@
 /*
  * The below is leftmost cache rbtree addon
  */
-static struct rb_node *cfq_rb_first(struct cfq_rb_root *root)
+static struct cfq_queue *cfq_rb_first(struct cfq_rb_root *root)
 {
 	if (!root->left)
 		root->left = rb_first(&root->rb);
 
-	return root->left;
+	if (root->left)
+		return rb_entry(root->left, struct cfq_queue, rb_node);
+
+	return NULL;
 }
 
 static void cfq_rb_erase(struct rb_node *n, struct cfq_rb_root *root)
@@ -446,12 +447,20 @@
 static void cfq_service_tree_add(struct cfq_data *cfqd,
 				    struct cfq_queue *cfqq, int add_front)
 {
-	struct rb_node **p = &cfqd->service_tree.rb.rb_node;
-	struct rb_node *parent = NULL;
+	struct rb_node **p, *parent;
+	struct cfq_queue *__cfqq;
 	unsigned long rb_key;
 	int left;
 
-	if (!add_front) {
+	if (cfq_class_idle(cfqq)) {
+		rb_key = CFQ_IDLE_DELAY;
+		parent = rb_last(&cfqd->service_tree.rb);
+		if (parent && parent != &cfqq->rb_node) {
+			__cfqq = rb_entry(parent, struct cfq_queue, rb_node);
+			rb_key += __cfqq->rb_key;
+		} else
+			rb_key += jiffies;
+	} else if (!add_front) {
 		rb_key = cfq_slice_offset(cfqd, cfqq) + jiffies;
 		rb_key += cfqq->slice_resid;
 		cfqq->slice_resid = 0;
@@ -469,8 +478,9 @@
 	}
 
 	left = 1;
+	parent = NULL;
+	p = &cfqd->service_tree.rb.rb_node;
 	while (*p) {
-		struct cfq_queue *__cfqq;
 		struct rb_node **n;
 
 		parent = *p;
@@ -524,8 +534,7 @@
  * add to busy list of queues for service, trying to be fair in ordering
  * the pending list according to last request service
  */
-static inline void
-cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
 	BUG_ON(cfq_cfqq_on_rr(cfqq));
 	cfq_mark_cfqq_on_rr(cfqq);
@@ -538,8 +547,7 @@
  * Called when the cfqq no longer has requests pending, remove it from
  * the service tree.
  */
-static inline void
-cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
 	BUG_ON(!cfq_cfqq_on_rr(cfqq));
 	cfq_clear_cfqq_on_rr(cfqq);
@@ -554,7 +562,7 @@
 /*
  * rb tree support functions
  */
-static inline void cfq_del_rq_rb(struct request *rq)
+static void cfq_del_rq_rb(struct request *rq)
 {
 	struct cfq_queue *cfqq = RQ_CFQQ(rq);
 	struct cfq_data *cfqd = cfqq->cfqd;
@@ -594,8 +602,7 @@
 	BUG_ON(!cfqq->next_rq);
 }
 
-static inline void
-cfq_reposition_rq_rb(struct cfq_queue *cfqq, struct request *rq)
+static void cfq_reposition_rq_rb(struct cfq_queue *cfqq, struct request *rq)
 {
 	elv_rb_del(&cfqq->sort_list, rq);
 	cfqq->queued[rq_is_sync(rq)]--;
@@ -609,7 +616,7 @@
 	struct cfq_io_context *cic;
 	struct cfq_queue *cfqq;
 
-	cic = cfq_cic_rb_lookup(cfqd, tsk->io_context);
+	cic = cfq_cic_lookup(cfqd, tsk->io_context);
 	if (!cic)
 		return NULL;
 
@@ -721,7 +728,7 @@
 	 * Lookup the cfqq that this bio will be queued with. Allow
 	 * merge only if rq is queued there.
 	 */
-	cic = cfq_cic_rb_lookup(cfqd, current->io_context);
+	cic = cfq_cic_lookup(cfqd, current->io_context);
 	if (!cic)
 		return 0;
 
@@ -732,15 +739,10 @@
 	return 0;
 }
 
-static inline void
-__cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+static void __cfq_set_active_queue(struct cfq_data *cfqd,
+				   struct cfq_queue *cfqq)
 {
 	if (cfqq) {
-		/*
-		 * stop potential idle class queues waiting service
-		 */
-		del_timer(&cfqd->idle_class_timer);
-
 		cfqq->slice_end = 0;
 		cfq_clear_cfqq_must_alloc_slice(cfqq);
 		cfq_clear_cfqq_fifo_expire(cfqq);
@@ -789,47 +791,16 @@
 		__cfq_slice_expired(cfqd, cfqq, timed_out);
 }
 
-static int start_idle_class_timer(struct cfq_data *cfqd)
-{
-	unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE;
-	unsigned long now = jiffies;
-
-	if (time_before(now, end) &&
-	    time_after_eq(now, cfqd->last_end_request)) {
-		mod_timer(&cfqd->idle_class_timer, end);
-		return 1;
-	}
-
-	return 0;
-}
-
 /*
  * Get next queue for service. Unless we have a queue preemption,
  * we'll simply select the first cfqq in the service tree.
  */
 static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd)
 {
-	struct cfq_queue *cfqq;
-	struct rb_node *n;
-
 	if (RB_EMPTY_ROOT(&cfqd->service_tree.rb))
 		return NULL;
 
-	n = cfq_rb_first(&cfqd->service_tree);
-	cfqq = rb_entry(n, struct cfq_queue, rb_node);
-
-	if (cfq_class_idle(cfqq)) {
-		/*
-		 * if we have idle queues and no rt or be queues had
-		 * pending requests, either allow immediate service if
-		 * the grace period has passed or arm the idle grace
-		 * timer
-		 */
-		if (start_idle_class_timer(cfqd))
-			cfqq = NULL;
-	}
-
-	return cfqq;
+	return cfq_rb_first(&cfqd->service_tree);
 }
 
 /*
@@ -895,7 +866,7 @@
 	 * task has exited, don't wait
 	 */
 	cic = cfqd->active_cic;
-	if (!cic || !cic->ioc->task)
+	if (!cic || !atomic_read(&cic->ioc->nr_tasks))
 		return;
 
 	/*
@@ -939,7 +910,7 @@
 /*
  * return expired entry, or NULL to just start from scratch in rbtree
  */
-static inline struct request *cfq_check_fifo(struct cfq_queue *cfqq)
+static struct request *cfq_check_fifo(struct cfq_queue *cfqq)
 {
 	struct cfq_data *cfqd = cfqq->cfqd;
 	struct request *rq;
@@ -1068,7 +1039,7 @@
 	return dispatched;
 }
 
-static inline int __cfq_forced_dispatch_cfqq(struct cfq_queue *cfqq)
+static int __cfq_forced_dispatch_cfqq(struct cfq_queue *cfqq)
 {
 	int dispatched = 0;
 
@@ -1087,14 +1058,11 @@
  */
 static int cfq_forced_dispatch(struct cfq_data *cfqd)
 {
+	struct cfq_queue *cfqq;
 	int dispatched = 0;
-	struct rb_node *n;
 
-	while ((n = cfq_rb_first(&cfqd->service_tree)) != NULL) {
-		struct cfq_queue *cfqq = rb_entry(n, struct cfq_queue, rb_node);
-
+	while ((cfqq = cfq_rb_first(&cfqd->service_tree)) != NULL)
 		dispatched += __cfq_forced_dispatch_cfqq(cfqq);
-	}
 
 	cfq_slice_expired(cfqd, 0);
 
@@ -1170,20 +1138,69 @@
 	kmem_cache_free(cfq_pool, cfqq);
 }
 
+/*
+ * Call func for each cic attached to this ioc. Returns number of cic's seen.
+ */
+#define CIC_GANG_NR	16
+static unsigned int
+call_for_each_cic(struct io_context *ioc,
+		  void (*func)(struct io_context *, struct cfq_io_context *))
+{
+	struct cfq_io_context *cics[CIC_GANG_NR];
+	unsigned long index = 0;
+	unsigned int called = 0;
+	int nr;
+
+	rcu_read_lock();
+
+	do {
+		int i;
+
+		/*
+		 * Perhaps there's a better way - this just gang lookups from
+		 * 0 to the end, restarting after each CIC_GANG_NR from the
+		 * last key + 1.
+		 */
+		nr = radix_tree_gang_lookup(&ioc->radix_root, (void **) cics,
+						index, CIC_GANG_NR);
+		if (!nr)
+			break;
+
+		called += nr;
+		index = 1 + (unsigned long) cics[nr - 1]->key;
+
+		for (i = 0; i < nr; i++)
+			func(ioc, cics[i]);
+	} while (nr == CIC_GANG_NR);
+
+	rcu_read_unlock();
+
+	return called;
+}
+
+static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
+{
+	unsigned long flags;
+
+	BUG_ON(!cic->dead_key);
+
+	spin_lock_irqsave(&ioc->lock, flags);
+	radix_tree_delete(&ioc->radix_root, cic->dead_key);
+	spin_unlock_irqrestore(&ioc->lock, flags);
+
+	kmem_cache_free(cfq_ioc_pool, cic);
+}
+
 static void cfq_free_io_context(struct io_context *ioc)
 {
-	struct cfq_io_context *__cic;
-	struct rb_node *n;
-	int freed = 0;
+	int freed;
 
-	ioc->ioc_data = NULL;
-
-	while ((n = rb_first(&ioc->cic_root)) != NULL) {
-		__cic = rb_entry(n, struct cfq_io_context, rb_node);
-		rb_erase(&__cic->rb_node, &ioc->cic_root);
-		kmem_cache_free(cfq_ioc_pool, __cic);
-		freed++;
-	}
+	/*
+	 * ioc->refcount is zero here, so no more cic's are allowed to be
+	 * linked into this ioc. So it should be ok to iterate over the known
+	 * list, we will see all cic's since no new ones are added.
+	 */
+	freed = call_for_each_cic(ioc, cic_free_func);
 
 	elv_ioc_count_mod(ioc_count, -freed);
 
@@ -1205,7 +1222,12 @@
 					 struct cfq_io_context *cic)
 {
 	list_del_init(&cic->queue_list);
+
+	/*
+	 * Make sure key == NULL is seen for dead queues
+	 */
 	smp_wmb();
+	cic->dead_key = (unsigned long) cic->key;
 	cic->key = NULL;
 
 	if (cic->cfqq[ASYNC]) {
@@ -1219,16 +1241,18 @@
 	}
 }
 
-static void cfq_exit_single_io_context(struct cfq_io_context *cic)
+static void cfq_exit_single_io_context(struct io_context *ioc,
+				       struct cfq_io_context *cic)
 {
 	struct cfq_data *cfqd = cic->key;
 
 	if (cfqd) {
 		struct request_queue *q = cfqd->queue;
+		unsigned long flags;
 
-		spin_lock_irq(q->queue_lock);
+		spin_lock_irqsave(q->queue_lock, flags);
 		__cfq_exit_single_io_context(cfqd, cic);
-		spin_unlock_irq(q->queue_lock);
+		spin_unlock_irqrestore(q->queue_lock, flags);
 	}
 }
 
@@ -1238,21 +1262,8 @@
  */
 static void cfq_exit_io_context(struct io_context *ioc)
 {
-	struct cfq_io_context *__cic;
-	struct rb_node *n;
-
-	ioc->ioc_data = NULL;
-
-	/*
-	 * put the reference this task is holding to the various queues
-	 */
-	n = rb_first(&ioc->cic_root);
-	while (n != NULL) {
-		__cic = rb_entry(n, struct cfq_io_context, rb_node);
-
-		cfq_exit_single_io_context(__cic);
-		n = rb_next(n);
-	}
+	rcu_assign_pointer(ioc->ioc_data, NULL);
+	call_for_each_cic(ioc, cfq_exit_single_io_context);
 }
 
 static struct cfq_io_context *
@@ -1273,7 +1284,7 @@
 	return cic;
 }
 
-static void cfq_init_prio_data(struct cfq_queue *cfqq)
+static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc)
 {
 	struct task_struct *tsk = current;
 	int ioprio_class;
@@ -1281,7 +1292,7 @@
 	if (!cfq_cfqq_prio_changed(cfqq))
 		return;
 
-	ioprio_class = IOPRIO_PRIO_CLASS(tsk->ioprio);
+	ioprio_class = IOPRIO_PRIO_CLASS(ioc->ioprio);
 	switch (ioprio_class) {
 		default:
 			printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class);
@@ -1293,11 +1304,11 @@
 			cfqq->ioprio_class = IOPRIO_CLASS_BE;
 			break;
 		case IOPRIO_CLASS_RT:
-			cfqq->ioprio = task_ioprio(tsk);
+			cfqq->ioprio = task_ioprio(ioc);
 			cfqq->ioprio_class = IOPRIO_CLASS_RT;
 			break;
 		case IOPRIO_CLASS_BE:
-			cfqq->ioprio = task_ioprio(tsk);
+			cfqq->ioprio = task_ioprio(ioc);
 			cfqq->ioprio_class = IOPRIO_CLASS_BE;
 			break;
 		case IOPRIO_CLASS_IDLE:
@@ -1316,7 +1327,7 @@
 	cfq_clear_cfqq_prio_changed(cfqq);
 }
 
-static inline void changed_ioprio(struct cfq_io_context *cic)
+static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic)
 {
 	struct cfq_data *cfqd = cic->key;
 	struct cfq_queue *cfqq;
@@ -1330,8 +1341,7 @@
 	cfqq = cic->cfqq[ASYNC];
 	if (cfqq) {
 		struct cfq_queue *new_cfqq;
-		new_cfqq = cfq_get_queue(cfqd, ASYNC, cic->ioc->task,
-					 GFP_ATOMIC);
+		new_cfqq = cfq_get_queue(cfqd, ASYNC, cic->ioc, GFP_ATOMIC);
 		if (new_cfqq) {
 			cic->cfqq[ASYNC] = new_cfqq;
 			cfq_put_queue(cfqq);
@@ -1347,29 +1357,19 @@
 
 static void cfq_ioc_set_ioprio(struct io_context *ioc)
 {
-	struct cfq_io_context *cic;
-	struct rb_node *n;
-
+	call_for_each_cic(ioc, changed_ioprio);
 	ioc->ioprio_changed = 0;
-
-	n = rb_first(&ioc->cic_root);
-	while (n != NULL) {
-		cic = rb_entry(n, struct cfq_io_context, rb_node);
-
-		changed_ioprio(cic);
-		n = rb_next(n);
-	}
 }
 
 static struct cfq_queue *
 cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync,
-		     struct task_struct *tsk, gfp_t gfp_mask)
+		     struct io_context *ioc, gfp_t gfp_mask)
 {
 	struct cfq_queue *cfqq, *new_cfqq = NULL;
 	struct cfq_io_context *cic;
 
 retry:
-	cic = cfq_cic_rb_lookup(cfqd, tsk->io_context);
+	cic = cfq_cic_lookup(cfqd, ioc);
 	/* cic always exists here */
 	cfqq = cic_to_cfqq(cic, is_sync);
 
@@ -1404,15 +1404,16 @@
 		atomic_set(&cfqq->ref, 0);
 		cfqq->cfqd = cfqd;
 
-		if (is_sync) {
-			cfq_mark_cfqq_idle_window(cfqq);
-			cfq_mark_cfqq_sync(cfqq);
-		}
-
 		cfq_mark_cfqq_prio_changed(cfqq);
 		cfq_mark_cfqq_queue_new(cfqq);
 
-		cfq_init_prio_data(cfqq);
+		cfq_init_prio_data(cfqq, ioc);
+
+		if (is_sync) {
+			if (!cfq_class_idle(cfqq))
+				cfq_mark_cfqq_idle_window(cfqq);
+			cfq_mark_cfqq_sync(cfqq);
+		}
 	}
 
 	if (new_cfqq)
@@ -1439,11 +1440,11 @@
 }
 
 static struct cfq_queue *
-cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
+cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc,
 	      gfp_t gfp_mask)
 {
-	const int ioprio = task_ioprio(tsk);
-	const int ioprio_class = task_ioprio_class(tsk);
+	const int ioprio = task_ioprio(ioc);
+	const int ioprio_class = task_ioprio_class(ioc);
 	struct cfq_queue **async_cfqq = NULL;
 	struct cfq_queue *cfqq = NULL;
 
@@ -1453,7 +1454,7 @@
 	}
 
 	if (!cfqq) {
-		cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask);
+		cfqq = cfq_find_alloc_queue(cfqd, is_sync, ioc, gfp_mask);
 		if (!cfqq)
 			return NULL;
 	}
@@ -1470,28 +1471,42 @@
 	return cfqq;
 }
 
+static void cfq_cic_free(struct cfq_io_context *cic)
+{
+	kmem_cache_free(cfq_ioc_pool, cic);
+	elv_ioc_count_dec(ioc_count);
+
+	if (ioc_gone && !elv_ioc_count_read(ioc_count))
+		complete(ioc_gone);
+}
+
 /*
  * We drop cfq io contexts lazily, so we may find a dead one.
  */
 static void
-cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic)
+cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
+		  struct cfq_io_context *cic)
 {
+	unsigned long flags;
+
 	WARN_ON(!list_empty(&cic->queue_list));
 
-	if (ioc->ioc_data == cic)
-		ioc->ioc_data = NULL;
+	spin_lock_irqsave(&ioc->lock, flags);
 
-	rb_erase(&cic->rb_node, &ioc->cic_root);
-	kmem_cache_free(cfq_ioc_pool, cic);
-	elv_ioc_count_dec(ioc_count);
+	if (ioc->ioc_data == cic)
+		rcu_assign_pointer(ioc->ioc_data, NULL);
+
+	radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd);
+	spin_unlock_irqrestore(&ioc->lock, flags);
+
+	cfq_cic_free(cic);
 }
 
 static struct cfq_io_context *
-cfq_cic_rb_lookup(struct cfq_data *cfqd, struct io_context *ioc)
+cfq_cic_lookup(struct cfq_data *cfqd, struct io_context *ioc)
 {
-	struct rb_node *n;
 	struct cfq_io_context *cic;
-	void *k, *key = cfqd;
+	void *k;
 
 	if (unlikely(!ioc))
 		return NULL;
@@ -1499,74 +1514,64 @@
 	/*
 	 * we maintain a last-hit cache, to avoid browsing over the tree
 	 */
-	cic = ioc->ioc_data;
+	cic = rcu_dereference(ioc->ioc_data);
 	if (cic && cic->key == cfqd)
 		return cic;
 
-restart:
-	n = ioc->cic_root.rb_node;
-	while (n) {
-		cic = rb_entry(n, struct cfq_io_context, rb_node);
+	do {
+		rcu_read_lock();
+		cic = radix_tree_lookup(&ioc->radix_root, (unsigned long) cfqd);
+		rcu_read_unlock();
+		if (!cic)
+			break;
 		/* ->key must be copied to avoid race with cfq_exit_queue() */
 		k = cic->key;
 		if (unlikely(!k)) {
-			cfq_drop_dead_cic(ioc, cic);
-			goto restart;
+			cfq_drop_dead_cic(cfqd, ioc, cic);
+			continue;
 		}
 
-		if (key < k)
-			n = n->rb_left;
-		else if (key > k)
-			n = n->rb_right;
-		else {
-			ioc->ioc_data = cic;
-			return cic;
-		}
-	}
+		rcu_assign_pointer(ioc->ioc_data, cic);
+		break;
+	} while (1);
 
-	return NULL;
+	return cic;
 }
 
-static inline void
-cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
-	     struct cfq_io_context *cic)
+/*
+ * Add cic into ioc, using cfqd as the search key. This enables us to lookup
+ * the process specific cfq io context when entered from the block layer.
+ * Also adds the cic to a per-cfqd list, used when this queue is removed.
+ */
+static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
+			struct cfq_io_context *cic, gfp_t gfp_mask)
 {
-	struct rb_node **p;
-	struct rb_node *parent;
-	struct cfq_io_context *__cic;
 	unsigned long flags;
-	void *k;
+	int ret;
 
-	cic->ioc = ioc;
-	cic->key = cfqd;
+	ret = radix_tree_preload(gfp_mask);
+	if (!ret) {
+		cic->ioc = ioc;
+		cic->key = cfqd;
 
-restart:
-	parent = NULL;
-	p = &ioc->cic_root.rb_node;
-	while (*p) {
-		parent = *p;
-		__cic = rb_entry(parent, struct cfq_io_context, rb_node);
-		/* ->key must be copied to avoid race with cfq_exit_queue() */
-		k = __cic->key;
-		if (unlikely(!k)) {
-			cfq_drop_dead_cic(ioc, __cic);
-			goto restart;
+		spin_lock_irqsave(&ioc->lock, flags);
+		ret = radix_tree_insert(&ioc->radix_root,
+						(unsigned long) cfqd, cic);
+		spin_unlock_irqrestore(&ioc->lock, flags);
+
+		radix_tree_preload_end();
+
+		if (!ret) {
+			spin_lock_irqsave(cfqd->queue->queue_lock, flags);
+			list_add(&cic->queue_list, &cfqd->cic_list);
+			spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
 		}
-
-		if (cic->key < k)
-			p = &(*p)->rb_left;
-		else if (cic->key > k)
-			p = &(*p)->rb_right;
-		else
-			BUG();
 	}
 
-	rb_link_node(&cic->rb_node, parent, p);
-	rb_insert_color(&cic->rb_node, &ioc->cic_root);
+	if (ret)
+		printk(KERN_ERR "cfq: cic link failed!\n");
 
-	spin_lock_irqsave(cfqd->queue->queue_lock, flags);
-	list_add(&cic->queue_list, &cfqd->cic_list);
-	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
+	return ret;
 }
 
 /*
@@ -1586,7 +1591,7 @@
 	if (!ioc)
 		return NULL;
 
-	cic = cfq_cic_rb_lookup(cfqd, ioc);
+	cic = cfq_cic_lookup(cfqd, ioc);
 	if (cic)
 		goto out;
 
@@ -1594,13 +1599,17 @@
 	if (cic == NULL)
 		goto err;
 
-	cfq_cic_link(cfqd, ioc, cic);
+	if (cfq_cic_link(cfqd, ioc, cic, gfp_mask))
+		goto err_free;
+
 out:
 	smp_read_barrier_depends();
 	if (unlikely(ioc->ioprio_changed))
 		cfq_ioc_set_ioprio(ioc);
 
 	return cic;
+err_free:
+	cfq_cic_free(cic);
 err:
 	put_io_context(ioc);
 	return NULL;
@@ -1655,12 +1664,15 @@
 {
 	int enable_idle;
 
-	if (!cfq_cfqq_sync(cfqq))
+	/*
+	 * Don't idle for async or idle io prio class
+	 */
+	if (!cfq_cfqq_sync(cfqq) || cfq_class_idle(cfqq))
 		return;
 
 	enable_idle = cfq_cfqq_idle_window(cfqq);
 
-	if (!cic->ioc->task || !cfqd->cfq_slice_idle ||
+	if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
 	    (cfqd->hw_tag && CIC_SEEKY(cic)))
 		enable_idle = 0;
 	else if (sample_valid(cic->ttime_samples)) {
@@ -1793,7 +1805,7 @@
 	struct cfq_data *cfqd = q->elevator->elevator_data;
 	struct cfq_queue *cfqq = RQ_CFQQ(rq);
 
-	cfq_init_prio_data(cfqq);
+	cfq_init_prio_data(cfqq, RQ_CIC(rq)->ioc);
 
 	cfq_add_rq_rb(rq);
 
@@ -1834,7 +1846,7 @@
 			cfq_set_prio_slice(cfqd, cfqq);
 			cfq_clear_cfqq_slice_new(cfqq);
 		}
-		if (cfq_slice_used(cfqq))
+		if (cfq_slice_used(cfqq) || cfq_class_idle(cfqq))
 			cfq_slice_expired(cfqd, 1);
 		else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list))
 			cfq_arm_slice_timer(cfqd);
@@ -1894,13 +1906,13 @@
 	 * so just lookup a possibly existing queue, or return 'may queue'
 	 * if that fails
 	 */
-	cic = cfq_cic_rb_lookup(cfqd, tsk->io_context);
+	cic = cfq_cic_lookup(cfqd, tsk->io_context);
 	if (!cic)
 		return ELV_MQUEUE_MAY;
 
 	cfqq = cic_to_cfqq(cic, rw & REQ_RW_SYNC);
 	if (cfqq) {
-		cfq_init_prio_data(cfqq);
+		cfq_init_prio_data(cfqq, cic->ioc);
 		cfq_prio_boost(cfqq);
 
 		return __cfq_may_queue(cfqq);
@@ -1938,7 +1950,6 @@
 cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
-	struct task_struct *tsk = current;
 	struct cfq_io_context *cic;
 	const int rw = rq_data_dir(rq);
 	const int is_sync = rq_is_sync(rq);
@@ -1956,7 +1967,7 @@
 
 	cfqq = cic_to_cfqq(cic, is_sync);
 	if (!cfqq) {
-		cfqq = cfq_get_queue(cfqd, is_sync, tsk, gfp_mask);
+		cfqq = cfq_get_queue(cfqd, is_sync, cic->ioc, gfp_mask);
 
 		if (!cfqq)
 			goto queue_fail;
@@ -2039,29 +2050,9 @@
 	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
 }
 
-/*
- * Timer running if an idle class queue is waiting for service
- */
-static void cfq_idle_class_timer(unsigned long data)
-{
-	struct cfq_data *cfqd = (struct cfq_data *) data;
-	unsigned long flags;
-
-	spin_lock_irqsave(cfqd->queue->queue_lock, flags);
-
-	/*
-	 * race with a non-idle queue, reset timer
-	 */
-	if (!start_idle_class_timer(cfqd))
-		cfq_schedule_dispatch(cfqd);
-
-	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
-}
-
 static void cfq_shutdown_timer_wq(struct cfq_data *cfqd)
 {
 	del_timer_sync(&cfqd->idle_slice_timer);
-	del_timer_sync(&cfqd->idle_class_timer);
 	kblockd_flush_work(&cfqd->unplug_work);
 }
 
@@ -2126,10 +2117,6 @@
 	cfqd->idle_slice_timer.function = cfq_idle_slice_timer;
 	cfqd->idle_slice_timer.data = (unsigned long) cfqd;
 
-	init_timer(&cfqd->idle_class_timer);
-	cfqd->idle_class_timer.function = cfq_idle_class_timer;
-	cfqd->idle_class_timer.data = (unsigned long) cfqd;
-
 	INIT_WORK(&cfqd->unplug_work, cfq_kick_queue);
 
 	cfqd->last_end_request = jiffies;
@@ -2160,7 +2147,7 @@
 	if (!cfq_pool)
 		goto fail;
 
-	cfq_ioc_pool = KMEM_CACHE(cfq_io_context, 0);
+	cfq_ioc_pool = KMEM_CACHE(cfq_io_context, SLAB_DESTROY_BY_RCU);
 	if (!cfq_ioc_pool)
 		goto fail;
 
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index cae0a85..b733732 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -545,6 +545,7 @@
 	struct blk_user_trace_setup buts;
 	struct compat_blk_user_trace_setup cbuts;
 	struct request_queue *q;
+	char b[BDEVNAME_SIZE];
 	int ret;
 
 	q = bdev_get_queue(bdev);
@@ -554,6 +555,8 @@
 	if (copy_from_user(&cbuts, arg, sizeof(cbuts)))
 		return -EFAULT;
 
+	strcpy(b, bdevname(bdev, b));
+
 	buts = (struct blk_user_trace_setup) {
 		.act_mask = cbuts.act_mask,
 		.buf_size = cbuts.buf_size,
@@ -565,7 +568,7 @@
 	memcpy(&buts.name, &cbuts.name, 32);
 
 	mutex_lock(&bdev->bd_mutex);
-	ret = do_blk_trace_setup(q, bdev, &buts);
+	ret = do_blk_trace_setup(q, b, bdev->bd_dev, &buts);
 	mutex_unlock(&bdev->bd_mutex);
 	if (ret)
 		return ret;
diff --git a/block/elevator.c b/block/elevator.c
index f9736fb..8cd5775 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -741,7 +741,21 @@
 			q->boundary_rq = NULL;
 		}
 
-		if ((rq->cmd_flags & REQ_DONTPREP) || !q->prep_rq_fn)
+		if (rq->cmd_flags & REQ_DONTPREP)
+			break;
+
+		if (q->dma_drain_size && rq->data_len) {
+			/*
+			 * make sure space for the drain appears we
+			 * know we can do this because max_hw_segments
+			 * has been adjusted to be one fewer than the
+			 * device can handle
+			 */
+			rq->nr_phys_segments++;
+			rq->nr_hw_segments++;
+		}
+
+		if (!q->prep_rq_fn)
 			break;
 
 		ret = q->prep_rq_fn(q, rq);
@@ -754,6 +768,16 @@
 			 * avoid resource deadlock.  REQ_STARTED will
 			 * prevent other fs requests from passing this one.
 			 */
+			if (q->dma_drain_size && rq->data_len &&
+			    !(rq->cmd_flags & REQ_DONTPREP)) {
+				/*
+				 * remove the space for the drain we added
+				 * so that we don't add it again
+				 */
+				--rq->nr_phys_segments;
+				--rq->nr_hw_segments;
+			}
+
 			rq = NULL;
 			break;
 		} else if (ret == BLKPREP_KILL) {
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3d0422f..1932a56 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -347,7 +347,6 @@
 void blk_ordered_complete_seq(struct request_queue *q, unsigned seq, int error)
 {
 	struct request *rq;
-	int uptodate;
 
 	if (error && !q->orderr)
 		q->orderr = error;
@@ -361,15 +360,11 @@
 	/*
 	 * Okay, sequence complete.
 	 */
-	uptodate = 1;
-	if (q->orderr)
-		uptodate = q->orderr;
-
 	q->ordseq = 0;
 	rq = q->orig_bar_rq;
 
-	end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
-	end_that_request_last(rq, uptodate);
+	if (__blk_end_request(rq, q->orderr, blk_rq_bytes(rq)))
+		BUG();
 }
 
 static void pre_flush_end_io(struct request *rq, int error)
@@ -486,9 +481,9 @@
 			 * ORDERED_NONE while this request is on it.
 			 */
 			blkdev_dequeue_request(rq);
-			end_that_request_first(rq, -EOPNOTSUPP,
-					       rq->hard_nr_sectors);
-			end_that_request_last(rq, -EOPNOTSUPP);
+			if (__blk_end_request(rq, -EOPNOTSUPP,
+					      blk_rq_bytes(rq)))
+				BUG();
 			*rqp = NULL;
 			return 0;
 		}
@@ -726,6 +721,45 @@
 EXPORT_SYMBOL(blk_queue_stack_limits);
 
 /**
+ * blk_queue_dma_drain - Set up a drain buffer for excess dma.
+ *
+ * @q:  the request queue for the device
+ * @buf:	physically contiguous buffer
+ * @size:	size of the buffer in bytes
+ *
+ * Some devices have excess DMA problems and can't simply discard (or
+ * zero fill) the unwanted piece of the transfer.  They have to have a
+ * real area of memory to transfer it into.  The use case for this is
+ * ATAPI devices in DMA mode.  If the packet command causes a transfer
+ * bigger than the transfer size some HBAs will lock up if there
+ * aren't DMA elements to contain the excess transfer.  What this API
+ * does is adjust the queue so that the buf is always appended
+ * silently to the scatterlist.
+ *
+ * Note: This routine adjusts max_hw_segments to make room for
+ * appending the drain buffer.  If you call
+ * blk_queue_max_hw_segments() or blk_queue_max_phys_segments() after
+ * calling this routine, you must set the limit to one fewer than your
+ * device can support otherwise there won't be room for the drain
+ * buffer.
+ */
+int blk_queue_dma_drain(struct request_queue *q, void *buf,
+				unsigned int size)
+{
+	if (q->max_hw_segments < 2 || q->max_phys_segments < 2)
+		return -EINVAL;
+	/* make room for appending the drain */
+	--q->max_hw_segments;
+	--q->max_phys_segments;
+	q->dma_drain_buffer = buf;
+	q->dma_drain_size = size;
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(blk_queue_dma_drain);
+
+/**
  * blk_queue_segment_boundary - set boundary rules for segment merging
  * @q:  the request queue for the device
  * @mask:  the memory boundary mask
@@ -1379,6 +1413,16 @@
 		bvprv = bvec;
 	} /* segments in rq */
 
+	if (q->dma_drain_size) {
+		sg->page_link &= ~0x02;
+		sg = sg_next(sg);
+		sg_set_page(sg, virt_to_page(q->dma_drain_buffer),
+			    q->dma_drain_size,
+			    ((unsigned long)q->dma_drain_buffer) &
+			    (PAGE_SIZE - 1));
+		nsegs++;
+	}
+
 	if (sg)
 		sg_mark_end(sg);
 
@@ -3437,29 +3481,36 @@
 	}
 }
 
-static int __end_that_request_first(struct request *req, int uptodate,
+/**
+ * __end_that_request_first - end I/O on a request
+ * @req:      the request being processed
+ * @error:    0 for success, < 0 for error
+ * @nr_bytes: number of bytes to complete
+ *
+ * Description:
+ *     Ends I/O on a number of bytes attached to @req, and sets it up
+ *     for the next range of segments (if any) in the cluster.
+ *
+ * Return:
+ *     0 - we are done with this request, call end_that_request_last()
+ *     1 - still buffers pending for this request
+ **/
+static int __end_that_request_first(struct request *req, int error,
 				    int nr_bytes)
 {
-	int total_bytes, bio_nbytes, error, next_idx = 0;
+	int total_bytes, bio_nbytes, next_idx = 0;
 	struct bio *bio;
 
 	blk_add_trace_rq(req->q, req, BLK_TA_COMPLETE);
 
 	/*
-	 * extend uptodate bool to allow < 0 value to be direct io error
-	 */
-	error = 0;
-	if (end_io_error(uptodate))
-		error = !uptodate ? -EIO : uptodate;
-
-	/*
 	 * for a REQ_BLOCK_PC request, we want to carry any eventual
 	 * sense key with us all the way through
 	 */
 	if (!blk_pc_request(req))
 		req->errors = 0;
 
-	if (!uptodate) {
+	if (error) {
 		if (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))
 			printk("end_request: I/O error, dev %s, sector %llu\n",
 				req->rq_disk ? req->rq_disk->disk_name : "?",
@@ -3553,49 +3604,6 @@
 	return 1;
 }
 
-/**
- * end_that_request_first - end I/O on a request
- * @req:      the request being processed
- * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error
- * @nr_sectors: number of sectors to end I/O on
- *
- * Description:
- *     Ends I/O on a number of sectors attached to @req, and sets it up
- *     for the next range of segments (if any) in the cluster.
- *
- * Return:
- *     0 - we are done with this request, call end_that_request_last()
- *     1 - still buffers pending for this request
- **/
-int end_that_request_first(struct request *req, int uptodate, int nr_sectors)
-{
-	return __end_that_request_first(req, uptodate, nr_sectors << 9);
-}
-
-EXPORT_SYMBOL(end_that_request_first);
-
-/**
- * end_that_request_chunk - end I/O on a request
- * @req:      the request being processed
- * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error
- * @nr_bytes: number of bytes to complete
- *
- * Description:
- *     Ends I/O on a number of bytes attached to @req, and sets it up
- *     for the next range of segments (if any). Like end_that_request_first(),
- *     but deals with bytes instead of sectors.
- *
- * Return:
- *     0 - we are done with this request, call end_that_request_last()
- *     1 - still buffers pending for this request
- **/
-int end_that_request_chunk(struct request *req, int uptodate, int nr_bytes)
-{
-	return __end_that_request_first(req, uptodate, nr_bytes);
-}
-
-EXPORT_SYMBOL(end_that_request_chunk);
-
 /*
  * splice the completion data to a local structure and hand off to
  * process_completion_queue() to complete the requests
@@ -3675,17 +3683,15 @@
 /*
  * queue lock must be held
  */
-void end_that_request_last(struct request *req, int uptodate)
+static void end_that_request_last(struct request *req, int error)
 {
 	struct gendisk *disk = req->rq_disk;
-	int error;
 
-	/*
-	 * extend uptodate bool to allow < 0 value to be direct io error
-	 */
-	error = 0;
-	if (end_io_error(uptodate))
-		error = !uptodate ? -EIO : uptodate;
+	if (blk_rq_tagged(req))
+		blk_queue_end_tag(req->q, req);
+
+	if (blk_queued_rq(req))
+		blkdev_dequeue_request(req);
 
 	if (unlikely(laptop_mode) && blk_fs_request(req))
 		laptop_io_completion();
@@ -3704,32 +3710,54 @@
 		disk_round_stats(disk);
 		disk->in_flight--;
 	}
+
 	if (req->end_io)
 		req->end_io(req, error);
-	else
+	else {
+		if (blk_bidi_rq(req))
+			__blk_put_request(req->next_rq->q, req->next_rq);
+
 		__blk_put_request(req->q, req);
-}
-
-EXPORT_SYMBOL(end_that_request_last);
-
-static inline void __end_request(struct request *rq, int uptodate,
-				 unsigned int nr_bytes, int dequeue)
-{
-	if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
-		if (dequeue)
-			blkdev_dequeue_request(rq);
-		add_disk_randomness(rq->rq_disk);
-		end_that_request_last(rq, uptodate);
 	}
 }
 
-static unsigned int rq_byte_size(struct request *rq)
+static inline void __end_request(struct request *rq, int uptodate,
+				 unsigned int nr_bytes)
+{
+	int error = 0;
+
+	if (uptodate <= 0)
+		error = uptodate ? uptodate : -EIO;
+
+	__blk_end_request(rq, error, nr_bytes);
+}
+
+/**
+ * blk_rq_bytes - Returns bytes left to complete in the entire request
+ **/
+unsigned int blk_rq_bytes(struct request *rq)
 {
 	if (blk_fs_request(rq))
 		return rq->hard_nr_sectors << 9;
 
 	return rq->data_len;
 }
+EXPORT_SYMBOL_GPL(blk_rq_bytes);
+
+/**
+ * blk_rq_cur_bytes - Returns bytes left to complete in the current segment
+ **/
+unsigned int blk_rq_cur_bytes(struct request *rq)
+{
+	if (blk_fs_request(rq))
+		return rq->current_nr_sectors << 9;
+
+	if (rq->bio)
+		return rq->bio->bi_size;
+
+	return rq->data_len;
+}
+EXPORT_SYMBOL_GPL(blk_rq_cur_bytes);
 
 /**
  * end_queued_request - end all I/O on a queued request
@@ -3744,7 +3772,7 @@
  **/
 void end_queued_request(struct request *rq, int uptodate)
 {
-	__end_request(rq, uptodate, rq_byte_size(rq), 1);
+	__end_request(rq, uptodate, blk_rq_bytes(rq));
 }
 EXPORT_SYMBOL(end_queued_request);
 
@@ -3761,7 +3789,7 @@
  **/
 void end_dequeued_request(struct request *rq, int uptodate)
 {
-	__end_request(rq, uptodate, rq_byte_size(rq), 0);
+	__end_request(rq, uptodate, blk_rq_bytes(rq));
 }
 EXPORT_SYMBOL(end_dequeued_request);
 
@@ -3787,10 +3815,159 @@
  **/
 void end_request(struct request *req, int uptodate)
 {
-	__end_request(req, uptodate, req->hard_cur_sectors << 9, 1);
+	__end_request(req, uptodate, req->hard_cur_sectors << 9);
 }
 EXPORT_SYMBOL(end_request);
 
+/**
+ * blk_end_io - Generic end_io function to complete a request.
+ * @rq:           the request being processed
+ * @error:        0 for success, < 0 for error
+ * @nr_bytes:     number of bytes to complete @rq
+ * @bidi_bytes:   number of bytes to complete @rq->next_rq
+ * @drv_callback: function called between completion of bios in the request
+ *                and completion of the request.
+ *                If the callback returns non 0, this helper returns without
+ *                completion of the request.
+ *
+ * Description:
+ *     Ends I/O on a number of bytes attached to @rq and @rq->next_rq.
+ *     If @rq has leftover, sets it up for the next range of segments.
+ *
+ * Return:
+ *     0 - we are done with this request
+ *     1 - this request is not freed yet, it still has pending buffers.
+ **/
+static int blk_end_io(struct request *rq, int error, int nr_bytes,
+		      int bidi_bytes, int (drv_callback)(struct request *))
+{
+	struct request_queue *q = rq->q;
+	unsigned long flags = 0UL;
+
+	if (blk_fs_request(rq) || blk_pc_request(rq)) {
+		if (__end_that_request_first(rq, error, nr_bytes))
+			return 1;
+
+		/* Bidi request must be completed as a whole */
+		if (blk_bidi_rq(rq) &&
+		    __end_that_request_first(rq->next_rq, error, bidi_bytes))
+			return 1;
+	}
+
+	/* Special feature for tricky drivers */
+	if (drv_callback && drv_callback(rq))
+		return 1;
+
+	add_disk_randomness(rq->rq_disk);
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	end_that_request_last(rq, error);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+
+	return 0;
+}
+
+/**
+ * blk_end_request - Helper function for drivers to complete the request.
+ * @rq:       the request being processed
+ * @error:    0 for success, < 0 for error
+ * @nr_bytes: number of bytes to complete
+ *
+ * Description:
+ *     Ends I/O on a number of bytes attached to @rq.
+ *     If @rq has leftover, sets it up for the next range of segments.
+ *
+ * Return:
+ *     0 - we are done with this request
+ *     1 - still buffers pending for this request
+ **/
+int blk_end_request(struct request *rq, int error, int nr_bytes)
+{
+	return blk_end_io(rq, error, nr_bytes, 0, NULL);
+}
+EXPORT_SYMBOL_GPL(blk_end_request);
+
+/**
+ * __blk_end_request - Helper function for drivers to complete the request.
+ * @rq:       the request being processed
+ * @error:    0 for success, < 0 for error
+ * @nr_bytes: number of bytes to complete
+ *
+ * Description:
+ *     Must be called with queue lock held unlike blk_end_request().
+ *
+ * Return:
+ *     0 - we are done with this request
+ *     1 - still buffers pending for this request
+ **/
+int __blk_end_request(struct request *rq, int error, int nr_bytes)
+{
+	if (blk_fs_request(rq) || blk_pc_request(rq)) {
+		if (__end_that_request_first(rq, error, nr_bytes))
+			return 1;
+	}
+
+	add_disk_randomness(rq->rq_disk);
+
+	end_that_request_last(rq, error);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__blk_end_request);
+
+/**
+ * blk_end_bidi_request - Helper function for drivers to complete bidi request.
+ * @rq:         the bidi request being processed
+ * @error:      0 for success, < 0 for error
+ * @nr_bytes:   number of bytes to complete @rq
+ * @bidi_bytes: number of bytes to complete @rq->next_rq
+ *
+ * Description:
+ *     Ends I/O on a number of bytes attached to @rq and @rq->next_rq.
+ *
+ * Return:
+ *     0 - we are done with this request
+ *     1 - still buffers pending for this request
+ **/
+int blk_end_bidi_request(struct request *rq, int error, int nr_bytes,
+			 int bidi_bytes)
+{
+	return blk_end_io(rq, error, nr_bytes, bidi_bytes, NULL);
+}
+EXPORT_SYMBOL_GPL(blk_end_bidi_request);
+
+/**
+ * blk_end_request_callback - Special helper function for tricky drivers
+ * @rq:           the request being processed
+ * @error:        0 for success, < 0 for error
+ * @nr_bytes:     number of bytes to complete
+ * @drv_callback: function called between completion of bios in the request
+ *                and completion of the request.
+ *                If the callback returns non 0, this helper returns without
+ *                completion of the request.
+ *
+ * Description:
+ *     Ends I/O on a number of bytes attached to @rq.
+ *     If @rq has leftover, sets it up for the next range of segments.
+ *
+ *     This special helper function is used only for existing tricky drivers.
+ *     (e.g. cdrom_newpc_intr() of ide-cd)
+ *     This interface will be removed when such drivers are rewritten.
+ *     Don't use this interface in other places anymore.
+ *
+ * Return:
+ *     0 - we are done with this request
+ *     1 - this request is not freed yet.
+ *         this request still has pending buffers or
+ *         the driver doesn't want to finish this request yet.
+ **/
+int blk_end_request_callback(struct request *rq, int error, int nr_bytes,
+			     int (drv_callback)(struct request *))
+{
+	return blk_end_io(rq, error, nr_bytes, 0, drv_callback);
+}
+EXPORT_SYMBOL_GPL(blk_end_request_callback);
+
 static void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
 			    struct bio *bio)
 {
@@ -3853,55 +4030,100 @@
 	return 0;
 }
 
+static void cfq_dtor(struct io_context *ioc)
+{
+	struct cfq_io_context *cic[1];
+	int r;
+
+	/*
+	 * We don't have a specific key to lookup with, so use the gang
+	 * lookup to just retrieve the first item stored. The cfq exit
+	 * function will iterate the full tree, so any member will do.
+	 */
+	r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1);
+	if (r > 0)
+		cic[0]->dtor(ioc);
+}
+
 /*
- * IO Context helper functions
+ * IO Context helper functions. put_io_context() returns 1 if there are no
+ * more users of this io context, 0 otherwise.
  */
-void put_io_context(struct io_context *ioc)
+int put_io_context(struct io_context *ioc)
 {
 	if (ioc == NULL)
-		return;
+		return 1;
 
 	BUG_ON(atomic_read(&ioc->refcount) == 0);
 
 	if (atomic_dec_and_test(&ioc->refcount)) {
-		struct cfq_io_context *cic;
-
 		rcu_read_lock();
 		if (ioc->aic && ioc->aic->dtor)
 			ioc->aic->dtor(ioc->aic);
-		if (ioc->cic_root.rb_node != NULL) {
-			struct rb_node *n = rb_first(&ioc->cic_root);
-
-			cic = rb_entry(n, struct cfq_io_context, rb_node);
-			cic->dtor(ioc);
-		}
 		rcu_read_unlock();
+		cfq_dtor(ioc);
 
 		kmem_cache_free(iocontext_cachep, ioc);
+		return 1;
 	}
+	return 0;
 }
 EXPORT_SYMBOL(put_io_context);
 
+static void cfq_exit(struct io_context *ioc)
+{
+	struct cfq_io_context *cic[1];
+	int r;
+
+	rcu_read_lock();
+	/*
+	 * See comment for cfq_dtor()
+	 */
+	r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1);
+	rcu_read_unlock();
+
+	if (r > 0)
+		cic[0]->exit(ioc);
+}
+
 /* Called by the exitting task */
 void exit_io_context(void)
 {
 	struct io_context *ioc;
-	struct cfq_io_context *cic;
 
 	task_lock(current);
 	ioc = current->io_context;
 	current->io_context = NULL;
 	task_unlock(current);
 
-	ioc->task = NULL;
-	if (ioc->aic && ioc->aic->exit)
-		ioc->aic->exit(ioc->aic);
-	if (ioc->cic_root.rb_node != NULL) {
-		cic = rb_entry(rb_first(&ioc->cic_root), struct cfq_io_context, rb_node);
-		cic->exit(ioc);
+	if (atomic_dec_and_test(&ioc->nr_tasks)) {
+		if (ioc->aic && ioc->aic->exit)
+			ioc->aic->exit(ioc->aic);
+		cfq_exit(ioc);
+
+		put_io_context(ioc);
+	}
+}
+
+struct io_context *alloc_io_context(gfp_t gfp_flags, int node)
+{
+	struct io_context *ret;
+
+	ret = kmem_cache_alloc_node(iocontext_cachep, gfp_flags, node);
+	if (ret) {
+		atomic_set(&ret->refcount, 1);
+		atomic_set(&ret->nr_tasks, 1);
+		spin_lock_init(&ret->lock);
+		ret->ioprio_changed = 0;
+		ret->ioprio = 0;
+		ret->last_waited = jiffies; /* doesn't matter... */
+		ret->nr_batch_requests = 0; /* because this is 0 */
+		ret->aic = NULL;
+		INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH);
+		ret->ioc_data = NULL;
 	}
 
-	put_io_context(ioc);
+	return ret;
 }
 
 /*
@@ -3921,16 +4143,8 @@
 	if (likely(ret))
 		return ret;
 
-	ret = kmem_cache_alloc_node(iocontext_cachep, gfp_flags, node);
+	ret = alloc_io_context(gfp_flags, node);
 	if (ret) {
-		atomic_set(&ret->refcount, 1);
-		ret->task = current;
-		ret->ioprio_changed = 0;
-		ret->last_waited = jiffies; /* doesn't matter... */
-		ret->nr_batch_requests = 0; /* because this is 0 */
-		ret->aic = NULL;
-		ret->cic_root.rb_node = NULL;
-		ret->ioc_data = NULL;
 		/* make sure set_task_ioprio() sees the settings above */
 		smp_wmb();
 		tsk->io_context = ret;
@@ -3947,10 +4161,18 @@
  */
 struct io_context *get_io_context(gfp_t gfp_flags, int node)
 {
-	struct io_context *ret;
-	ret = current_io_context(gfp_flags, node);
-	if (likely(ret))
-		atomic_inc(&ret->refcount);
+	struct io_context *ret = NULL;
+
+	/*
+	 * Check for unlikely race with exiting task. ioc ref count is
+	 * zero when ioc is being detached.
+	 */
+	do {
+		ret = current_io_context(gfp_flags, node);
+		if (unlikely(!ret))
+			break;
+	} while (!atomic_inc_not_zero(&ret->refcount));
+
 	return ret;
 }
 EXPORT_SYMBOL(get_io_context);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index ce803d1..bdbd55a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4924,7 +4924,7 @@
  *	@dev: device to target
  *	@buf: data buffer
  *	@buflen: buffer length
- *	@write_data: read/write
+ *	@rw: read/write
  *
  *	Transfer data from/to the device data register by PIO.
  *
@@ -4970,7 +4970,7 @@
  *	@dev: device to target
  *	@buf: data buffer
  *	@buflen: buffer length
- *	@write_data: read/write
+ *	@rw: read/write
  *
  *	Transfer data from/to the device data register by PIO. Do the
  *	transfer with interrupts disabled.
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 9030c37..cd03473 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -3455,19 +3455,12 @@
 						 bool SuccessfulIO)
 {
 	struct request *Request = Command->Request;
-	int UpToDate;
-
-	UpToDate = 0;
-	if (SuccessfulIO)
-		UpToDate = 1;
+	int Error = SuccessfulIO ? 0 : -EIO;
 
 	pci_unmap_sg(Command->Controller->PCIDevice, Command->cmd_sglist,
 		Command->SegmentCount, Command->DmaDirection);
 
-	 if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) {
-		add_disk_randomness(Request->rq_disk);
- 	 	end_that_request_last(Request, UpToDate);
-
+	 if (!__blk_end_request(Request, Error, Command->BlockCount << 9)) {
 		if (Command->Completion) {
 			complete(Command->Completion);
 			Command->Completion = NULL;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 509b649..ef50068 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1187,17 +1187,6 @@
 	}
 }
 
-static inline void complete_buffers(struct bio *bio, int status)
-{
-	while (bio) {
-		struct bio *xbh = bio->bi_next;
-
-		bio->bi_next = NULL;
-		bio_endio(bio, status ? 0 : -EIO);
-		bio = xbh;
-	}
-}
-
 static void cciss_check_queues(ctlr_info_t *h)
 {
 	int start_queue = h->next_to_run;
@@ -1263,21 +1252,14 @@
 		pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
 	}
 
-	complete_buffers(rq->bio, (rq->errors == 0));
-
-	if (blk_fs_request(rq)) {
-		const int rw = rq_data_dir(rq);
-
-		disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
-	}
-
 #ifdef CCISS_DEBUG
 	printk("Done with %p\n", rq);
 #endif				/* CCISS_DEBUG */
 
-	add_disk_randomness(rq->rq_disk);
+	if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq)))
+		BUG();
+
 	spin_lock_irqsave(&h->lock, flags);
-	end_that_request_last(rq, (rq->errors == 0));
 	cmd_free(h, cmd, 1);
 	cciss_check_queues(h);
 	spin_unlock_irqrestore(&h->lock, flags);
@@ -2544,7 +2526,6 @@
 	}
 	cmd->rq->data_len = 0;
 	cmd->rq->completion_data = cmd;
-	blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE);
 	blk_complete_request(cmd->rq);
 }
 
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index c8132d9..6919918 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -167,7 +167,6 @@
 
 static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c);
 static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c);
-static inline void complete_buffers(struct bio *bio, int ok);
 static inline void complete_command(cmdlist_t *cmd, int timeout);
 
 static irqreturn_t do_ida_intr(int irq, void *dev_id);
@@ -980,26 +979,13 @@
 	}
 }
 
-static inline void complete_buffers(struct bio *bio, int ok)
-{
-	struct bio *xbh;
-
-	while (bio) {
-		xbh = bio->bi_next;
-		bio->bi_next = NULL;
-		
-		bio_endio(bio, ok ? 0 : -EIO);
-
-		bio = xbh;
-	}
-}
 /*
  * Mark all buffers that cmd was responsible for
  */
 static inline void complete_command(cmdlist_t *cmd, int timeout)
 {
 	struct request *rq = cmd->rq;
-	int ok=1;
+	int error = 0;
 	int i, ddir;
 
 	if (cmd->req.hdr.rcode & RCODE_NONFATAL &&
@@ -1011,16 +997,17 @@
 	if (cmd->req.hdr.rcode & RCODE_FATAL) {
 		printk(KERN_WARNING "Fatal error on ida/c%dd%d\n",
 				cmd->ctlr, cmd->hdr.unit);
-		ok = 0;
+		error = -EIO;
 	}
 	if (cmd->req.hdr.rcode & RCODE_INVREQ) {
 				printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
 				cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd,
 				cmd->req.hdr.blk, cmd->req.hdr.blk_cnt,
 				cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode);
-		ok = 0;	
+		error = -EIO;
 	}
-	if (timeout) ok = 0;
+	if (timeout)
+		error = -EIO;
 	/* unmap the DMA mapping for all the scatter gather elements */
 	if (cmd->req.hdr.cmd == IDA_READ)
 		ddir = PCI_DMA_FROMDEVICE;
@@ -1030,18 +1017,9 @@
                 pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
 				cmd->req.sg[i].size, ddir);
 
-	complete_buffers(rq->bio, ok);
-
-	if (blk_fs_request(rq)) {
-		const int rw = rq_data_dir(rq);
-
-		disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
-	}
-
-	add_disk_randomness(rq->rq_disk);
-
 	DBGPX(printk("Done with %p\n", rq););
-	end_that_request_last(rq, ok ? 1 : -EIO);
+	if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
+		BUG();
 }
 
 /*
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 639ed14..32c79a5 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -2287,21 +2287,19 @@
  * =============================
  */
 
-static void floppy_end_request(struct request *req, int uptodate)
+static void floppy_end_request(struct request *req, int error)
 {
 	unsigned int nr_sectors = current_count_sectors;
+	unsigned int drive = (unsigned long)req->rq_disk->private_data;
 
 	/* current_count_sectors can be zero if transfer failed */
-	if (!uptodate)
+	if (error)
 		nr_sectors = req->current_nr_sectors;
-	if (end_that_request_first(req, uptodate, nr_sectors))
+	if (__blk_end_request(req, error, nr_sectors << 9))
 		return;
-	add_disk_randomness(req->rq_disk);
-	floppy_off((long)req->rq_disk->private_data);
-	blkdev_dequeue_request(req);
-	end_that_request_last(req, uptodate);
 
 	/* We're done with the request */
+	floppy_off(drive);
 	current_req = NULL;
 }
 
@@ -2332,7 +2330,7 @@
 
 		/* unlock chained buffers */
 		spin_lock_irqsave(q->queue_lock, flags);
-		floppy_end_request(req, 1);
+		floppy_end_request(req, 0);
 		spin_unlock_irqrestore(q->queue_lock, flags);
 	} else {
 		if (rq_data_dir(req) == WRITE) {
@@ -2346,7 +2344,7 @@
 			DRWE->last_error_generation = DRS->generation;
 		}
 		spin_lock_irqsave(q->queue_lock, flags);
-		floppy_end_request(req, 0);
+		floppy_end_request(req, -EIO);
 		spin_unlock_irqrestore(q->queue_lock, flags);
 	}
 }
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index ba9b17e..ae31060 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -100,17 +100,15 @@
 
 static void nbd_end_request(struct request *req)
 {
-	int uptodate = (req->errors == 0) ? 1 : 0;
+	int error = req->errors ? -EIO : 0;
 	struct request_queue *q = req->q;
 	unsigned long flags;
 
 	dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name,
-			req, uptodate? "done": "failed");
+			req, error ? "failed" : "done");
 
 	spin_lock_irqsave(q->queue_lock, flags);
-	if (!end_that_request_first(req, uptodate, req->nr_sectors)) {
-		end_that_request_last(req, uptodate);
-	}
+	__blk_end_request(req, error, req->nr_sectors << 9);
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index e354bfc..7483f94 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -229,7 +229,7 @@
 	struct ps3_storage_device *dev = data;
 	struct ps3disk_private *priv;
 	struct request *req;
-	int res, read, uptodate;
+	int res, read, error;
 	u64 tag, status;
 	unsigned long num_sectors;
 	const char *op;
@@ -270,21 +270,17 @@
 	if (status) {
 		dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
 			__LINE__, op, status);
-		uptodate = 0;
+		error = -EIO;
 	} else {
 		dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
 			__LINE__, op);
-		uptodate = 1;
+		error = 0;
 		if (read)
 			ps3disk_scatter_gather(dev, req, 0);
 	}
 
 	spin_lock(&priv->lock);
-	if (!end_that_request_first(req, uptodate, num_sectors)) {
-		add_disk_randomness(req->rq_disk);
-		blkdev_dequeue_request(req);
-		end_that_request_last(req, uptodate);
-	}
+	__blk_end_request(req, error, num_sectors << 9);
 	priv->req = NULL;
 	ps3disk_do_request(dev, priv->queue);
 	spin_unlock(&priv->lock);
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index fac4c6c..66e3015 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -212,12 +212,9 @@
 	vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD);
 }
 
-static void vdc_end_request(struct request *req, int uptodate, int num_sectors)
+static void vdc_end_request(struct request *req, int error, int num_sectors)
 {
-	if (end_that_request_first(req, uptodate, num_sectors))
-		return;
-	add_disk_randomness(req->rq_disk);
-	end_that_request_last(req, uptodate);
+	__blk_end_request(req, error, num_sectors << 9);
 }
 
 static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
@@ -242,7 +239,7 @@
 
 	rqe->req = NULL;
 
-	vdc_end_request(req, !desc->status, desc->size >> 9);
+	vdc_end_request(req, (desc->status ? -EIO : 0), desc->size >> 9);
 
 	if (blk_queue_stopped(port->disk->queue))
 		blk_start_queue(port->disk->queue);
@@ -456,7 +453,7 @@
 
 		blkdev_dequeue_request(req);
 		if (__send_request(req) < 0)
-			vdc_end_request(req, 0, req->hard_nr_sectors);
+			vdc_end_request(req, -EIO, req->hard_nr_sectors);
 	}
 }
 
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 52dc5e1..cd5674b 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -744,16 +744,14 @@
 
 static inline void carm_end_request_queued(struct carm_host *host,
 					   struct carm_request *crq,
-					   int uptodate)
+					   int error)
 {
 	struct request *req = crq->rq;
 	int rc;
 
-	rc = end_that_request_first(req, uptodate, req->hard_nr_sectors);
+	rc = __blk_end_request(req, error, blk_rq_bytes(req));
 	assert(rc == 0);
 
-	end_that_request_last(req, uptodate);
-
 	rc = carm_put_request(host, crq);
 	assert(rc == 0);
 }
@@ -793,9 +791,9 @@
 }
 
 static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq,
-			int is_ok)
+			       int error)
 {
-	carm_end_request_queued(host, crq, is_ok);
+	carm_end_request_queued(host, crq, error);
 	if (max_queue == 1)
 		carm_round_robin(host);
 	else if ((host->n_msgs <= CARM_MSG_LOW_WATER) &&
@@ -873,14 +871,14 @@
 	sg = &crq->sg[0];
 	n_elem = blk_rq_map_sg(q, rq, sg);
 	if (n_elem <= 0) {
-		carm_end_rq(host, crq, 0);
+		carm_end_rq(host, crq, -EIO);
 		return;		/* request with no s/g entries? */
 	}
 
 	/* map scatterlist to PCI bus addresses */
 	n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir);
 	if (n_elem <= 0) {
-		carm_end_rq(host, crq, 0);
+		carm_end_rq(host, crq, -EIO);
 		return;		/* request with no s/g entries? */
 	}
 	crq->n_elem = n_elem;
@@ -941,7 +939,7 @@
 
 static void carm_handle_array_info(struct carm_host *host,
 				   struct carm_request *crq, u8 *mem,
-				   int is_ok)
+				   int error)
 {
 	struct carm_port *port;
 	u8 *msg_data = mem + sizeof(struct carm_array_info);
@@ -952,9 +950,9 @@
 
 	DPRINTK("ENTER\n");
 
-	carm_end_rq(host, crq, is_ok);
+	carm_end_rq(host, crq, error);
 
-	if (!is_ok)
+	if (error)
 		goto out;
 	if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST)
 		goto out;
@@ -1001,7 +999,7 @@
 
 static void carm_handle_scan_chan(struct carm_host *host,
 				  struct carm_request *crq, u8 *mem,
-				  int is_ok)
+				  int error)
 {
 	u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET;
 	unsigned int i, dev_count = 0;
@@ -1009,9 +1007,9 @@
 
 	DPRINTK("ENTER\n");
 
-	carm_end_rq(host, crq, is_ok);
+	carm_end_rq(host, crq, error);
 
-	if (!is_ok) {
+	if (error) {
 		new_state = HST_ERROR;
 		goto out;
 	}
@@ -1033,23 +1031,23 @@
 }
 
 static void carm_handle_generic(struct carm_host *host,
-				struct carm_request *crq, int is_ok,
+				struct carm_request *crq, int error,
 				int cur_state, int next_state)
 {
 	DPRINTK("ENTER\n");
 
-	carm_end_rq(host, crq, is_ok);
+	carm_end_rq(host, crq, error);
 
 	assert(host->state == cur_state);
-	if (is_ok)
-		host->state = next_state;
-	else
+	if (error)
 		host->state = HST_ERROR;
+	else
+		host->state = next_state;
 	schedule_work(&host->fsm_task);
 }
 
 static inline void carm_handle_rw(struct carm_host *host,
-				  struct carm_request *crq, int is_ok)
+				  struct carm_request *crq, int error)
 {
 	int pci_dir;
 
@@ -1062,7 +1060,7 @@
 
 	pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir);
 
-	carm_end_rq(host, crq, is_ok);
+	carm_end_rq(host, crq, error);
 }
 
 static inline void carm_handle_resp(struct carm_host *host,
@@ -1071,7 +1069,7 @@
 	u32 handle = le32_to_cpu(ret_handle_le);
 	unsigned int msg_idx;
 	struct carm_request *crq;
-	int is_ok = (status == RMSG_OK);
+	int error = (status == RMSG_OK) ? 0 : -EIO;
 	u8 *mem;
 
 	VPRINTK("ENTER, handle == 0x%x\n", handle);
@@ -1090,7 +1088,7 @@
 	/* fast path */
 	if (likely(crq->msg_type == CARM_MSG_READ ||
 		   crq->msg_type == CARM_MSG_WRITE)) {
-		carm_handle_rw(host, crq, is_ok);
+		carm_handle_rw(host, crq, error);
 		return;
 	}
 
@@ -1100,7 +1098,7 @@
 	case CARM_MSG_IOCTL: {
 		switch (crq->msg_subtype) {
 		case CARM_IOC_SCAN_CHAN:
-			carm_handle_scan_chan(host, crq, mem, is_ok);
+			carm_handle_scan_chan(host, crq, mem, error);
 			break;
 		default:
 			/* unknown / invalid response */
@@ -1112,21 +1110,21 @@
 	case CARM_MSG_MISC: {
 		switch (crq->msg_subtype) {
 		case MISC_ALLOC_MEM:
-			carm_handle_generic(host, crq, is_ok,
+			carm_handle_generic(host, crq, error,
 					    HST_ALLOC_BUF, HST_SYNC_TIME);
 			break;
 		case MISC_SET_TIME:
-			carm_handle_generic(host, crq, is_ok,
+			carm_handle_generic(host, crq, error,
 					    HST_SYNC_TIME, HST_GET_FW_VER);
 			break;
 		case MISC_GET_FW_VER: {
 			struct carm_fw_ver *ver = (struct carm_fw_ver *)
 				mem + sizeof(struct carm_msg_get_fw_ver);
-			if (is_ok) {
+			if (!error) {
 				host->fw_ver = le32_to_cpu(ver->version);
 				host->flags |= (ver->features & FL_FW_VER_MASK);
 			}
-			carm_handle_generic(host, crq, is_ok,
+			carm_handle_generic(host, crq, error,
 					    HST_GET_FW_VER, HST_PORT_SCAN);
 			break;
 		}
@@ -1140,7 +1138,7 @@
 	case CARM_MSG_ARRAY: {
 		switch (crq->msg_subtype) {
 		case CARM_ARRAY_INFO:
-			carm_handle_array_info(host, crq, mem, is_ok);
+			carm_handle_array_info(host, crq, mem, error);
 			break;
 		default:
 			/* unknown / invalid response */
@@ -1159,7 +1157,7 @@
 err_out:
 	printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n",
 	       pci_name(host->pdev), crq->msg_type, crq->msg_subtype);
-	carm_end_rq(host, crq, 0);
+	carm_end_rq(host, crq, -EIO);
 }
 
 static inline void carm_handle_responses(struct carm_host *host)
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 08e909d..c6179d6 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -808,16 +808,16 @@
 
 static void ub_end_rq(struct request *rq, unsigned int scsi_status)
 {
-	int uptodate;
+	int error;
 
 	if (scsi_status == 0) {
-		uptodate = 1;
+		error = 0;
 	} else {
-		uptodate = 0;
+		error = -EIO;
 		rq->errors = scsi_status;
 	}
-	end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
-	end_that_request_last(rq, uptodate);
+	if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
+		BUG();
 }
 
 static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index ab5d404..9e61fca 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -229,13 +229,10 @@
 /*
  * End a request
  */
-static void viodasd_end_request(struct request *req, int uptodate,
+static void viodasd_end_request(struct request *req, int error,
 		int num_sectors)
 {
-	if (end_that_request_first(req, uptodate, num_sectors))
-		return;
-	add_disk_randomness(req->rq_disk);
-	end_that_request_last(req, uptodate);
+	__blk_end_request(req, error, num_sectors << 9);
 }
 
 /*
@@ -374,12 +371,12 @@
 		blkdev_dequeue_request(req);
 		/* check that request contains a valid command */
 		if (!blk_fs_request(req)) {
-			viodasd_end_request(req, 0, req->hard_nr_sectors);
+			viodasd_end_request(req, -EIO, req->hard_nr_sectors);
 			continue;
 		}
 		/* Try sending the request */
 		if (send_request(req) != 0)
-			viodasd_end_request(req, 0, req->hard_nr_sectors);
+			viodasd_end_request(req, -EIO, req->hard_nr_sectors);
 	}
 }
 
@@ -591,7 +588,7 @@
 	num_req_outstanding--;
 	spin_unlock_irqrestore(&viodasd_spinlock, irq_flags);
 
-	error = event->xRc != HvLpEvent_Rc_Good;
+	error = (event->xRc == HvLpEvent_Rc_Good) ? 0 : -EIO;
 	if (error) {
 		const struct vio_error_entry *err;
 		err = vio_lookup_rc(viodasd_err_table, bevent->sub_result);
@@ -601,7 +598,7 @@
 	}
 	qlock = req->q->queue_lock;
 	spin_lock_irqsave(qlock, irq_flags);
-	viodasd_end_request(req, !error, num_sect);
+	viodasd_end_request(req, error, num_sect);
 	spin_unlock_irqrestore(qlock, irq_flags);
 
 	/* Finally, try to get more requests off of this device's queue */
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 2bdebcb..8afce67 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -452,7 +452,7 @@
 	RING_IDX i, rp;
 	unsigned long flags;
 	struct blkfront_info *info = (struct blkfront_info *)dev_id;
-	int uptodate;
+	int error;
 
 	spin_lock_irqsave(&blkif_io_lock, flags);
 
@@ -477,13 +477,13 @@
 
 		add_id_to_freelist(info, id);
 
-		uptodate = (bret->status == BLKIF_RSP_OKAY);
+		error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO;
 		switch (bret->operation) {
 		case BLKIF_OP_WRITE_BARRIER:
 			if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
 				printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
 				       info->gd->disk_name);
-				uptodate = -EOPNOTSUPP;
+				error = -EOPNOTSUPP;
 				info->feature_barrier = 0;
 				xlvbd_barrier(info);
 			}
@@ -494,10 +494,8 @@
 				dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
 					"request: %x\n", bret->status);
 
-			ret = end_that_request_first(req, uptodate,
-				req->hard_nr_sectors);
+			ret = __blk_end_request(req, error, blk_rq_bytes(req));
 			BUG_ON(ret);
-			end_that_request_last(req, uptodate);
 			break;
 		default:
 			BUG();
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 82effce..2c81465 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -703,7 +703,7 @@
 
 		/* bio finished; is there another one? */
 		i = ace->req->current_nr_sectors;
-		if (end_that_request_first(ace->req, 1, i)) {
+		if (__blk_end_request(ace->req, 0, i)) {
 			/* dev_dbg(ace->dev, "next block; h=%li c=%i\n",
 			 *      ace->req->hard_nr_sectors,
 			 *      ace->req->current_nr_sectors);
@@ -718,9 +718,6 @@
 		break;
 
 	case ACE_FSM_STATE_REQ_COMPLETE:
-		/* Complete the block request */
-		blkdev_dequeue_request(ace->req);
-		end_that_request_last(ace->req, 1);
 		ace->req = NULL;
 
 		/* Finished request; go to idle state */
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index d8bb44b..8473b9f 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -289,7 +289,7 @@
 	return 0;
 }
 
-static void viocd_end_request(struct request *req, int uptodate)
+static void viocd_end_request(struct request *req, int error)
 {
 	int nsectors = req->hard_nr_sectors;
 
@@ -302,11 +302,8 @@
 	if (!nsectors)
 		nsectors = 1;
 
-	if (end_that_request_first(req, uptodate, nsectors))
+	if (__blk_end_request(req, error, nsectors << 9))
 		BUG();
-	add_disk_randomness(req->rq_disk);
-	blkdev_dequeue_request(req);
-	end_that_request_last(req, uptodate);
 }
 
 static int rwreq;
@@ -317,11 +314,11 @@
 
 	while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) {
 		if (!blk_fs_request(req))
-			viocd_end_request(req, 0);
+			viocd_end_request(req, -EIO);
 		else if (send_request(req) < 0) {
 			printk(VIOCD_KERN_WARNING
 					"unable to send message to OS/400!");
-			viocd_end_request(req, 0);
+			viocd_end_request(req, -EIO);
 		} else
 			rwreq++;
 	}
@@ -532,9 +529,9 @@
 					"with rc %d:0x%04X: %s\n",
 					req, event->xRc,
 					bevent->sub_result, err->msg);
-			viocd_end_request(req, 0);
+			viocd_end_request(req, -EIO);
 		} else
-			viocd_end_request(req, 1);
+			viocd_end_request(req, 0);
 
 		/* restart handling of incoming requests */
 		spin_unlock_irqrestore(&viocd_reqlock, flags);
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 1ac5103..275dc52 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for the HID driver
 #
-hid-objs			:= hid-core.o hid-input.o
+hid-objs			:= hid-core.o hid-input.o hid-input-quirks.o
 
 obj-$(CONFIG_HID)		+= hid.o
 
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 2884b03..d73a768 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -26,6 +26,7 @@
 #include <linux/input.h>
 #include <linux/wait.h>
 #include <linux/vmalloc.h>
+#include <linux/sched.h>
 
 #include <linux/hid.h>
 #include <linux/hiddev.h>
@@ -758,7 +759,9 @@
 {
 	u64 x;
 
-	WARN_ON(n > 32);
+	if (n > 32)
+		printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n",
+				n, current->comm);
 
 	report += offset >> 3;  /* adjust byte index */
 	offset &= 7;            /* now only need bit offset into one byte */
@@ -780,8 +783,13 @@
 	__le64 x;
 	u64 m = (1ULL << n) - 1;
 
-	WARN_ON(n > 32);
+	if (n > 32)
+		printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n",
+				n, current->comm);
 
+	if (value > m)
+		printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n",
+				value, current->comm);
 	WARN_ON(value > m);
 	value &= m;
 
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c
new file mode 100644
index 0000000..a870ba5
--- /dev/null
+++ b/drivers/hid/hid-input-quirks.c
@@ -0,0 +1,423 @@
+/*
+ *  HID-input usage mapping quirks
+ *
+ *  This is used to handle HID-input mappings for devices violating
+ *  HUT 1.12 specification.
+ *
+ * Copyright (c) 2007-2008 Jiri Kosina
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License
+ */
+
+#include <linux/input.h>
+#include <linux/hid.h>
+
+#define map_abs(c)      do { usage->code = c; usage->type = EV_ABS; *bit = input->absbit; *max = ABS_MAX; } while (0)
+#define map_rel(c)      do { usage->code = c; usage->type = EV_REL; *bit = input->relbit; *max = REL_MAX; } while (0)
+#define map_key(c)      do { usage->code = c; usage->type = EV_KEY; *bit = input->keybit; *max = KEY_MAX; } while (0)
+#define map_led(c)      do { usage->code = c; usage->type = EV_LED; *bit = input->ledbit; *max = LED_MAX; } while (0)
+
+#define map_abs_clear(c)        do { map_abs(c); clear_bit(c, *bit); } while (0)
+#define map_key_clear(c)        do { map_key(c); clear_bit(c, *bit); } while (0)
+
+static int quirk_belkin_wkbd(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+		case 0x03a: map_key_clear(KEY_SOUND);		break;
+		case 0x03b: map_key_clear(KEY_CAMERA);		break;
+		case 0x03c: map_key_clear(KEY_DOCUMENTS);	break;
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+static int quirk_cherry_cymotion(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+		case 0x301: map_key_clear(KEY_PROG1);		break;
+		case 0x302: map_key_clear(KEY_PROG2);		break;
+		case 0x303: map_key_clear(KEY_PROG3);		break;
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
+		return 0;
+
+	set_bit(EV_REP, input->evbit);
+	switch(usage->hid & HID_USAGE) {
+		/* Reported on Logitech Ultra X Media Remote */
+		case 0x004: map_key_clear(KEY_AGAIN);		break;
+		case 0x00d: map_key_clear(KEY_HOME);		break;
+		case 0x024: map_key_clear(KEY_SHUFFLE);		break;
+		case 0x025: map_key_clear(KEY_TV);		break;
+		case 0x026: map_key_clear(KEY_MENU);		break;
+		case 0x031: map_key_clear(KEY_AUDIO);		break;
+		case 0x032: map_key_clear(KEY_TEXT);		break;
+		case 0x033: map_key_clear(KEY_LAST);		break;
+		case 0x047: map_key_clear(KEY_MP3);		break;
+		case 0x048: map_key_clear(KEY_DVD);		break;
+		case 0x049: map_key_clear(KEY_MEDIA);		break;
+		case 0x04a: map_key_clear(KEY_VIDEO);		break;
+		case 0x04b: map_key_clear(KEY_ANGLE);		break;
+		case 0x04c: map_key_clear(KEY_LANGUAGE);	break;
+		case 0x04d: map_key_clear(KEY_SUBTITLE);	break;
+		case 0x051: map_key_clear(KEY_RED);		break;
+		case 0x052: map_key_clear(KEY_CLOSE);		break;
+
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+		return 0;
+
+	set_bit(EV_REP, input->evbit);
+	switch (usage->hid & HID_USAGE) {
+		case 0xff01: map_key_clear(BTN_1);		break;
+		case 0xff02: map_key_clear(BTN_2);		break;
+		case 0xff03: map_key_clear(BTN_3);		break;
+		case 0xff04: map_key_clear(BTN_4);		break;
+		case 0xff05: map_key_clear(BTN_5);		break;
+		case 0xff06: map_key_clear(BTN_6);		break;
+		case 0xff07: map_key_clear(BTN_7);		break;
+		case 0xff08: map_key_clear(BTN_8);		break;
+		case 0xff09: map_key_clear(BTN_9);		break;
+		case 0xff0a: map_key_clear(BTN_A);		break;
+		case 0xff0b: map_key_clear(BTN_B);		break;
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+		return 0;
+
+	switch(usage->hid & HID_USAGE) {
+		case 0xfd06: map_key_clear(KEY_CHAT);		break;
+		case 0xfd07: map_key_clear(KEY_PHONE);		break;
+		case 0xff05:
+			set_bit(EV_REP, input->evbit);
+			map_key_clear(KEY_F13);
+			set_bit(KEY_F14, input->keybit);
+			set_bit(KEY_F15, input->keybit);
+			set_bit(KEY_F16, input->keybit);
+			set_bit(KEY_F17, input->keybit);
+			set_bit(KEY_F18, input->keybit);
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+static int quirk_microsoft_presenter_8k(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+		return 0;
+
+	set_bit(EV_REP, input->evbit);
+	switch(usage->hid & HID_USAGE) {
+		case 0xfd08: map_key_clear(KEY_FORWARD);	break;
+		case 0xfd09: map_key_clear(KEY_BACK);		break;
+		case 0xfd0b: map_key_clear(KEY_PLAYPAUSE);	break;
+		case 0xfd0e: map_key_clear(KEY_CLOSE);		break;
+		case 0xfd0f: map_key_clear(KEY_PLAY);		break;
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+static int quirk_petalynx_remote(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if (((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) &&
+			((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER))
+		return 0;
+
+	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR)
+		switch(usage->hid & HID_USAGE) {
+			case 0x05a: map_key_clear(KEY_TEXT);		break;
+			case 0x05b: map_key_clear(KEY_RED);		break;
+			case 0x05c: map_key_clear(KEY_GREEN);		break;
+			case 0x05d: map_key_clear(KEY_YELLOW);		break;
+			case 0x05e: map_key_clear(KEY_BLUE);		break;
+			default:
+				return 0;
+		}
+
+	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
+		switch(usage->hid & HID_USAGE) {
+			case 0x0f6: map_key_clear(KEY_NEXT);            break;
+			case 0x0fa: map_key_clear(KEY_BACK);            break;
+			default:
+				return 0;
+		}
+	return 1;
+}
+
+static int quirk_logitech_wireless(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+		case 0x1001: map_key_clear(KEY_MESSENGER);	break;
+		case 0x1003: map_key_clear(KEY_SOUND);		break;
+		case 0x1004: map_key_clear(KEY_VIDEO);		break;
+		case 0x1005: map_key_clear(KEY_AUDIO);		break;
+		case 0x100a: map_key_clear(KEY_DOCUMENTS);	break;
+		case 0x1011: map_key_clear(KEY_PREVIOUSSONG);	break;
+		case 0x1012: map_key_clear(KEY_NEXTSONG);	break;
+		case 0x1013: map_key_clear(KEY_CAMERA);		break;
+		case 0x1014: map_key_clear(KEY_MESSENGER);	break;
+		case 0x1015: map_key_clear(KEY_RECORD);		break;
+		case 0x1016: map_key_clear(KEY_PLAYER);		break;
+		case 0x1017: map_key_clear(KEY_EJECTCD);	break;
+		case 0x1018: map_key_clear(KEY_MEDIA);		break;
+		case 0x1019: map_key_clear(KEY_PROG1);		break;
+		case 0x101a: map_key_clear(KEY_PROG2);		break;
+		case 0x101b: map_key_clear(KEY_PROG3);		break;
+		case 0x101f: map_key_clear(KEY_ZOOMIN);		break;
+		case 0x1020: map_key_clear(KEY_ZOOMOUT);	break;
+		case 0x1021: map_key_clear(KEY_ZOOMRESET);	break;
+		case 0x1023: map_key_clear(KEY_CLOSE);		break;
+		case 0x1027: map_key_clear(KEY_MENU);		break;
+		/* this one is marked as 'Rotate' */
+		case 0x1028: map_key_clear(KEY_ANGLE);		break;
+		case 0x1029: map_key_clear(KEY_SHUFFLE);	break;
+		case 0x102a: map_key_clear(KEY_BACK);		break;
+		case 0x102b: map_key_clear(KEY_CYCLEWINDOWS);	break;
+		case 0x1041: map_key_clear(KEY_BATTERY);	break;
+		case 0x1042: map_key_clear(KEY_WORDPROCESSOR);	break;
+		case 0x1043: map_key_clear(KEY_SPREADSHEET);	break;
+		case 0x1044: map_key_clear(KEY_PRESENTATION);	break;
+		case 0x1045: map_key_clear(KEY_UNDO);		break;
+		case 0x1046: map_key_clear(KEY_REDO);		break;
+		case 0x1047: map_key_clear(KEY_PRINT);		break;
+		case 0x1048: map_key_clear(KEY_SAVE);		break;
+		case 0x1049: map_key_clear(KEY_PROG1);		break;
+		case 0x104a: map_key_clear(KEY_PROG2);		break;
+		case 0x104b: map_key_clear(KEY_PROG3);		break;
+		case 0x104c: map_key_clear(KEY_PROG4);		break;
+
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+		case 0x156: map_key_clear(KEY_WORDPROCESSOR);	break;
+		case 0x157: map_key_clear(KEY_SPREADSHEET);	break;
+		case 0x158: map_key_clear(KEY_PRESENTATION);	break;
+		case 0x15c: map_key_clear(KEY_STOP);		break;
+
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input,
+			      unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+		case 0x230: map_key(BTN_MOUSE);			break;
+		case 0x231: map_rel(REL_WHEEL);			break;
+		/* 
+		 * this keyboard has a scrollwheel implemented in
+		 * totally broken way. We map this usage temporarily
+		 * to HWHEEL and handle it in the event quirk handler
+		 */
+		case 0x232: map_rel(REL_HWHEEL);		break;
+
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+#define VENDOR_ID_BELKIN			0x1020
+#define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD	0x0006
+
+#define VENDOR_ID_CHERRY			0x046a
+#define DEVICE_ID_CHERRY_CYMOTION		0x0023
+
+#define VENDOR_ID_CHICONY			0x04f2
+#define DEVICE_ID_CHICONY_TACTICAL_PAD		0x0418
+
+#define VENDOR_ID_EZKEY				0x0518
+#define DEVICE_ID_BTC_8193			0x0002
+
+#define VENDOR_ID_LOGITECH			0x046d
+#define DEVICE_ID_LOGITECH_RECEIVER		0xc101
+#define DEVICE_ID_S510_RECEIVER			0xc50c
+#define DEVICE_ID_S510_RECEIVER_2		0xc517
+#define DEVICE_ID_MX3000_RECEIVER		0xc513
+
+#define VENDOR_ID_MICROSOFT			0x045e
+#define DEVICE_ID_MS4K				0x00db
+#define DEVICE_ID_MS6K				0x00f9
+#define DEVICE_IS_MS_PRESENTER_8K_BT		0x0701
+#define DEVICE_ID_MS_PRESENTER_8K_USB		0x0713
+
+#define VENDOR_ID_MONTEREY			0x0566
+#define DEVICE_ID_GENIUS_KB29E			0x3004
+
+#define VENDOR_ID_PETALYNX			0x18b1
+#define DEVICE_ID_PETALYNX_MAXTER_REMOTE	0x0037
+
+static const struct hid_input_blacklist {
+	__u16 idVendor;
+	__u16 idProduct;
+	int (*quirk)(struct hid_usage *, struct input_dev *, unsigned long **, int *);
+} hid_input_blacklist[] = {
+	{ VENDOR_ID_BELKIN, DEVICE_ID_BELKIN_WIRELESS_KEYBOARD, quirk_belkin_wkbd },
+
+	{ VENDOR_ID_CHERRY, DEVICE_ID_CHERRY_CYMOTION, quirk_cherry_cymotion },
+
+	{ VENDOR_ID_CHICONY, DEVICE_ID_CHICONY_TACTICAL_PAD, quirk_chicony_tactical_pad },
+
+	{ VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 },
+
+	{ VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote },
+	{ VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless },
+	{ VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless },
+	{ VENDOR_ID_LOGITECH, DEVICE_ID_MX3000_RECEIVER, quirk_logitech_wireless },
+
+	{ VENDOR_ID_MICROSOFT, DEVICE_ID_MS4K, quirk_microsoft_ergonomy_kb },
+	{ VENDOR_ID_MICROSOFT, DEVICE_ID_MS6K, quirk_microsoft_ergonomy_kb },
+	{ VENDOR_ID_MICROSOFT, DEVICE_IS_MS_PRESENTER_8K_BT, quirk_microsoft_presenter_8k },
+	{ VENDOR_ID_MICROSOFT, DEVICE_ID_MS_PRESENTER_8K_USB, quirk_microsoft_presenter_8k },
+
+	{ VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e },
+
+	{ VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote },
+	
+	{ 0, 0, 0 }
+};
+
+int hidinput_mapping_quirks(struct hid_usage *usage, 
+				   struct input_dev *input, 
+				   unsigned long **bit, int *max)
+{
+	struct hid_device *device = input_get_drvdata(input);
+	int i = 0;
+	
+	while (hid_input_blacklist[i].quirk) {
+		if (hid_input_blacklist[i].idVendor == device->vendor &&
+				hid_input_blacklist[i].idProduct == device->product)
+			return hid_input_blacklist[i].quirk(usage, input, bit, max);
+		i++;
+	}
+	return 0;
+}
+
+void hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
+{
+	struct input_dev *input;
+
+	input = field->hidinput->input;
+
+	if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
+		|| ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) {
+		if (value) hid->quirks |=  HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
+		else       hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
+		return;
+	}
+
+	if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
+			(usage->type == EV_REL) &&
+			(usage->code == REL_WHEEL)) {
+		hid->delayed_value = value;
+		return;
+	}
+
+	if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
+			(usage->hid == 0x000100b8)) {
+		input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value);
+		return;
+	}
+
+	if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) {
+		input_event(input, usage->type, usage->code, -value);
+		return;
+	}
+
+	if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
+		input_event(input, usage->type, REL_HWHEEL, value);
+		return;
+	}
+
+	if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value))
+		return;
+
+	/* Handling MS keyboards special buttons */
+	if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS && 
+			usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
+		int key = 0;
+		static int last_key = 0;
+		switch (value) {
+			case 0x01: key = KEY_F14; break;
+			case 0x02: key = KEY_F15; break;
+			case 0x04: key = KEY_F16; break;
+			case 0x08: key = KEY_F17; break;
+			case 0x10: key = KEY_F18; break;
+			default: break;
+		}
+		if (key) {
+			input_event(input, usage->type, key, 1);
+			last_key = key;
+		} else {
+			input_event(input, usage->type, last_key, 0);
+		}
+	}
+
+	/* handle the temporary quirky mapping to HWHEEL */
+	if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT &&
+			usage->type == EV_REL && usage->code == REL_HWHEEL) {
+		input_event(input, usage->type, REL_WHEEL, -value);
+		return;
+	}
+}
+
+
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 0b27da7..5325d98 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -34,10 +34,10 @@
 #include <linux/hid.h>
 #include <linux/hid-debug.h>
 
-static int hid_pb_fnmode = 1;
-module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644);
+static int hid_apple_fnmode = 1;
+module_param_named(pb_fnmode, hid_apple_fnmode, int, 0644);
 MODULE_PARM_DESC(pb_fnmode,
-		"Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)");
+		"Mode of fn key on Apple keyboards (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)");
 
 #define unk	KEY_UNKNOWN
 
@@ -86,10 +86,6 @@
 #define map_abs_clear(c)	do { map_abs(c); clear_bit(c, bit); } while (0)
 #define map_key_clear(c)	do { map_key(c); clear_bit(c, bit); } while (0)
 
-/* hardware needing special handling due to colliding MSVENDOR page usages */
-#define IS_CHICONY_TACTICAL_PAD(x) (x->vendor == 0x04f2 && device->product == 0x0418)
-#define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9))
-
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
 
 struct hidinput_key_translation {
@@ -98,20 +94,36 @@
 	u8 flags;
 };
 
-#define POWERBOOK_FLAG_FKEY 0x01
+#define APPLE_FLAG_FKEY 0x01
+
+static struct hidinput_key_translation apple_fn_keys[] = {
+	{ KEY_F1,       KEY_BRIGHTNESSDOWN,     APPLE_FLAG_FKEY },
+	{ KEY_F2,       KEY_BRIGHTNESSUP,       APPLE_FLAG_FKEY },
+	{ KEY_F3,       KEY_CYCLEWINDOWS,       APPLE_FLAG_FKEY }, /* Exposé */
+	{ KEY_F4,       KEY_FN_F4,              APPLE_FLAG_FKEY }, /* Dashboard */
+	{ KEY_F5,       KEY_FN_F5 },
+	{ KEY_F6,       KEY_FN_F6 },
+	{ KEY_F7,       KEY_BACK,               APPLE_FLAG_FKEY },
+	{ KEY_F8,       KEY_PLAYPAUSE,          APPLE_FLAG_FKEY },
+	{ KEY_F9,       KEY_FORWARD,            APPLE_FLAG_FKEY },
+	{ KEY_F10,      KEY_MUTE,               APPLE_FLAG_FKEY },
+	{ KEY_F11,      KEY_VOLUMEDOWN,         APPLE_FLAG_FKEY },
+	{ KEY_F12,      KEY_VOLUMEUP,           APPLE_FLAG_FKEY },
+	{ }
+};
 
 static struct hidinput_key_translation powerbook_fn_keys[] = {
 	{ KEY_BACKSPACE, KEY_DELETE },
-	{ KEY_F1,       KEY_BRIGHTNESSDOWN,     POWERBOOK_FLAG_FKEY },
-	{ KEY_F2,       KEY_BRIGHTNESSUP,       POWERBOOK_FLAG_FKEY },
-	{ KEY_F3,       KEY_MUTE,               POWERBOOK_FLAG_FKEY },
-	{ KEY_F4,       KEY_VOLUMEDOWN,         POWERBOOK_FLAG_FKEY },
-	{ KEY_F5,       KEY_VOLUMEUP,           POWERBOOK_FLAG_FKEY },
-	{ KEY_F6,       KEY_NUMLOCK,            POWERBOOK_FLAG_FKEY },
-	{ KEY_F7,       KEY_SWITCHVIDEOMODE,    POWERBOOK_FLAG_FKEY },
-	{ KEY_F8,       KEY_KBDILLUMTOGGLE,     POWERBOOK_FLAG_FKEY },
-	{ KEY_F9,       KEY_KBDILLUMDOWN,       POWERBOOK_FLAG_FKEY },
-	{ KEY_F10,      KEY_KBDILLUMUP,         POWERBOOK_FLAG_FKEY },
+	{ KEY_F1,       KEY_BRIGHTNESSDOWN,     APPLE_FLAG_FKEY },
+	{ KEY_F2,       KEY_BRIGHTNESSUP,       APPLE_FLAG_FKEY },
+	{ KEY_F3,       KEY_MUTE,               APPLE_FLAG_FKEY },
+	{ KEY_F4,       KEY_VOLUMEDOWN,         APPLE_FLAG_FKEY },
+	{ KEY_F5,       KEY_VOLUMEUP,           APPLE_FLAG_FKEY },
+	{ KEY_F6,       KEY_NUMLOCK,            APPLE_FLAG_FKEY },
+	{ KEY_F7,       KEY_SWITCHVIDEOMODE,    APPLE_FLAG_FKEY },
+	{ KEY_F8,       KEY_KBDILLUMTOGGLE,     APPLE_FLAG_FKEY },
+	{ KEY_F9,       KEY_KBDILLUMDOWN,       APPLE_FLAG_FKEY },
+	{ KEY_F10,      KEY_KBDILLUMUP,         APPLE_FLAG_FKEY },
 	{ KEY_UP,       KEY_PAGEUP },
 	{ KEY_DOWN,     KEY_PAGEDOWN },
 	{ KEY_LEFT,     KEY_HOME },
@@ -142,7 +154,7 @@
 	{ }
 };
 
-static struct hidinput_key_translation powerbook_iso_keyboard[] = {
+static struct hidinput_key_translation apple_iso_keyboard[] = {
 	{ KEY_GRAVE,    KEY_102ND },
 	{ KEY_102ND,    KEY_GRAVE },
 	{ }
@@ -160,39 +172,42 @@
 	return NULL;
 }
 
-static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
+int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
 		struct hid_usage *usage, __s32 value)
 {
 	struct hidinput_key_translation *trans;
 
 	if (usage->code == KEY_FN) {
-		if (value) hid->quirks |=  HID_QUIRK_POWERBOOK_FN_ON;
-		else       hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON;
+		if (value) hid->quirks |=  HID_QUIRK_APPLE_FN_ON;
+		else       hid->quirks &= ~HID_QUIRK_APPLE_FN_ON;
 
 		input_event(input, usage->type, usage->code, value);
 
 		return 1;
 	}
 
-	if (hid_pb_fnmode) {
+	if (hid_apple_fnmode) {
 		int do_translate;
 
-		trans = find_translation(powerbook_fn_keys, usage->code);
+		trans = find_translation((hid->product < 0x220 ||
+					  hid->product >= 0x300) ?
+					 powerbook_fn_keys : apple_fn_keys,
+					 usage->code);
 		if (trans) {
-			if (test_bit(usage->code, hid->pb_pressed_fn))
+			if (test_bit(usage->code, hid->apple_pressed_fn))
 				do_translate = 1;
-			else if (trans->flags & POWERBOOK_FLAG_FKEY)
+			else if (trans->flags & APPLE_FLAG_FKEY)
 				do_translate =
-					(hid_pb_fnmode == 2 &&  (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) ||
-					(hid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON));
+					(hid_apple_fnmode == 2 &&  (hid->quirks & HID_QUIRK_APPLE_FN_ON)) ||
+					(hid_apple_fnmode == 1 && !(hid->quirks & HID_QUIRK_APPLE_FN_ON));
 			else
-				do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON);
+				do_translate = (hid->quirks & HID_QUIRK_APPLE_FN_ON);
 
 			if (do_translate) {
 				if (value)
-					set_bit(usage->code, hid->pb_pressed_fn);
+					set_bit(usage->code, hid->apple_pressed_fn);
 				else
-					clear_bit(usage->code, hid->pb_pressed_fn);
+					clear_bit(usage->code, hid->apple_pressed_fn);
 
 				input_event(input, usage->type, trans->to, value);
 
@@ -217,8 +232,8 @@
 		}
 	}
 
-	if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) {
-		trans = find_translation(powerbook_iso_keyboard, usage->code);
+	if (hid->quirks & HID_QUIRK_APPLE_ISO_KEYBOARD) {
+		trans = find_translation(apple_iso_keyboard, usage->code);
 		if (trans) {
 			input_event(input, usage->type, trans->to, value);
 			return 1;
@@ -228,31 +243,35 @@
 	return 0;
 }
 
-static void hidinput_pb_setup(struct input_dev *input)
+static void hidinput_apple_setup(struct input_dev *input)
 {
 	struct hidinput_key_translation *trans;
 
 	set_bit(KEY_NUMLOCK, input->keybit);
 
 	/* Enable all needed keys */
+	for (trans = apple_fn_keys; trans->from; trans++)
+		set_bit(trans->to, input->keybit);
+
 	for (trans = powerbook_fn_keys; trans->from; trans++)
 		set_bit(trans->to, input->keybit);
 
 	for (trans = powerbook_numlock_keys; trans->from; trans++)
 		set_bit(trans->to, input->keybit);
 
-	for (trans = powerbook_iso_keyboard; trans->from; trans++)
+	for (trans = apple_iso_keyboard; trans->from; trans++)
 		set_bit(trans->to, input->keybit);
 
 }
 #else
-static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
-		struct hid_usage *usage, __s32 value)
+inline int hidinput_apple_event(struct hid_device *hid,
+				       struct input_dev *input,
+				       struct hid_usage *usage, __s32 value)
 {
 	return 0;
 }
 
-static inline void hidinput_pb_setup(struct input_dev *input)
+static inline void hidinput_apple_setup(struct input_dev *input)
 {
 }
 #endif
@@ -343,7 +362,7 @@
 {
 	struct input_dev *input = hidinput->input;
 	struct hid_device *device = input_get_drvdata(input);
-	int max = 0, code;
+	int max = 0, code, ret;
 	unsigned long *bit = NULL;
 
 	field->hidinput = hidinput;
@@ -362,6 +381,11 @@
 		goto ignore;
 	}
 
+	/* handle input mappings for quirky devices */
+	ret = hidinput_mapping_quirks(usage, input, &bit, &max);
+	if (ret)
+		goto mapped;
+
 	switch (usage->hid & HID_USAGE_PAGE) {
 
 		case HID_UP_UNDEFINED:
@@ -549,14 +573,6 @@
 				case 0x000: goto ignore;
 				case 0x034: map_key_clear(KEY_SLEEP);		break;
 				case 0x036: map_key_clear(BTN_MISC);		break;
-				/*
-				 * The next three are reported by Belkin wireless
-				 * keyboard (1020:0006). These values are "reserved"
-				 * in HUT 1.12.
-				 */
-				case 0x03a: map_key_clear(KEY_SOUND);           break;
-				case 0x03b: map_key_clear(KEY_CAMERA);          break;
-				case 0x03c: map_key_clear(KEY_DOCUMENTS);       break;
 
 				case 0x040: map_key_clear(KEY_MENU);		break;
 				case 0x045: map_key_clear(KEY_RADIO);		break;
@@ -602,10 +618,6 @@
 				case 0x0e9: map_key_clear(KEY_VOLUMEUP);	break;
 				case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);	break;
 
-				/* reserved in HUT 1.12. Reported on Petalynx remote */
-				case 0x0f6: map_key_clear(KEY_NEXT);		break;
-				case 0x0fa: map_key_clear(KEY_BACK);		break;
-
 				case 0x182: map_key_clear(KEY_BOOKMARKS);	break;
 				case 0x183: map_key_clear(KEY_CONFIG);		break;
 				case 0x184: map_key_clear(KEY_WORDPROCESSOR);	break;
@@ -665,51 +677,6 @@
 				case 0x28b: map_key_clear(KEY_FORWARDMAIL);	break;
 				case 0x28c: map_key_clear(KEY_SEND);		break;
 
-				/* Reported on a Cherry Cymotion keyboard */
-				case 0x301: map_key_clear(KEY_PROG1);		break;
-				case 0x302: map_key_clear(KEY_PROG2);		break;
-				case 0x303: map_key_clear(KEY_PROG3);		break;
-
-				/* Reported on certain Logitech wireless keyboards */
-				case 0x1001: map_key_clear(KEY_MESSENGER);	break;
-				case 0x1003: map_key_clear(KEY_SOUND);		break;
-				case 0x1004: map_key_clear(KEY_VIDEO);		break;
-				case 0x1005: map_key_clear(KEY_AUDIO);		break;
-				case 0x100a: map_key_clear(KEY_DOCUMENTS);	break;
-				case 0x1011: map_key_clear(KEY_PREVIOUSSONG);	break;
-				case 0x1012: map_key_clear(KEY_NEXTSONG);	break;
-				case 0x1013: map_key_clear(KEY_CAMERA);		break;
-				case 0x1014: map_key_clear(KEY_MESSENGER);	break;
-				case 0x1015: map_key_clear(KEY_RECORD);		break;
-				case 0x1016: map_key_clear(KEY_PLAYER);		break;
-				case 0x1017: map_key_clear(KEY_EJECTCD);	break;
-				case 0x1018: map_key_clear(KEY_MEDIA);          break;
-				case 0x1019: map_key_clear(KEY_PROG1);		break;
-				case 0x101a: map_key_clear(KEY_PROG2);		break;
-				case 0x101b: map_key_clear(KEY_PROG3);		break;
-				case 0x101f: map_key_clear(KEY_ZOOMIN);		break;
-				case 0x1020: map_key_clear(KEY_ZOOMOUT);	break;
-				case 0x1021: map_key_clear(KEY_ZOOMRESET);	break;
-				case 0x1023: map_key_clear(KEY_CLOSE);		break;
-				case 0x1027: map_key_clear(KEY_MENU);           break;
-				/* this one is marked as 'Rotate' */
-				case 0x1028: map_key_clear(KEY_ANGLE);		break;
-				case 0x1029: map_key_clear(KEY_SHUFFLE);	break;
-				case 0x102a: map_key_clear(KEY_BACK);           break;
-				case 0x102b: map_key_clear(KEY_CYCLEWINDOWS);   break;
-				case 0x1041: map_key_clear(KEY_BATTERY);	break;
-				case 0x1042: map_key_clear(KEY_WORDPROCESSOR);	break;
-				case 0x1043: map_key_clear(KEY_SPREADSHEET);	break;
-				case 0x1044: map_key_clear(KEY_PRESENTATION);	break;
-				case 0x1045: map_key_clear(KEY_UNDO);		break;
-				case 0x1046: map_key_clear(KEY_REDO);		break;
-				case 0x1047: map_key_clear(KEY_PRINT);		break;
-				case 0x1048: map_key_clear(KEY_SAVE);		break;
-				case 0x1049: map_key_clear(KEY_PROG1);		break;
-				case 0x104a: map_key_clear(KEY_PROG2);		break;
-				case 0x104b: map_key_clear(KEY_PROG3);		break;
-				case 0x104c: map_key_clear(KEY_PROG4);		break;
-
 				default:    goto ignore;
 			}
 			break;
@@ -736,63 +703,16 @@
 
 		case HID_UP_MSVENDOR:
 
-			/* Unfortunately, there are multiple devices which
-			 * emit usages from MSVENDOR page that require different
-			 * handling. If this list grows too much in the future,
-			 * more general handling will have to be introduced here
-			 * (i.e. another blacklist).
-			 */
+			goto ignore;
 
-			/* Chicony Chicony KU-0418 tactical pad */
-			if (IS_CHICONY_TACTICAL_PAD(device)) {
-				set_bit(EV_REP, input->evbit);
-				switch(usage->hid & HID_USAGE) {
-					case 0xff01: map_key_clear(BTN_1);		break;
-					case 0xff02: map_key_clear(BTN_2);		break;
-					case 0xff03: map_key_clear(BTN_3);		break;
-					case 0xff04: map_key_clear(BTN_4);		break;
-					case 0xff05: map_key_clear(BTN_5);		break;
-					case 0xff06: map_key_clear(BTN_6);		break;
-					case 0xff07: map_key_clear(BTN_7);		break;
-					case 0xff08: map_key_clear(BTN_8);		break;
-					case 0xff09: map_key_clear(BTN_9);		break;
-					case 0xff0a: map_key_clear(BTN_A);		break;
-					case 0xff0b: map_key_clear(BTN_B);		break;
-					default:    goto ignore;
-				}
-
-			/* Microsoft Natural Ergonomic Keyboard 4000 */
-			} else if (IS_MS_KB(device)) {
-				switch(usage->hid & HID_USAGE) {
-					case 0xfd06:
-						map_key_clear(KEY_CHAT);
-						break;
-					case 0xfd07:
-						map_key_clear(KEY_PHONE);
-						break;
-					case 0xff05:
-						set_bit(EV_REP, input->evbit);
-						map_key_clear(KEY_F13);
-						set_bit(KEY_F14, input->keybit);
-						set_bit(KEY_F15, input->keybit);
-						set_bit(KEY_F16, input->keybit);
-						set_bit(KEY_F17, input->keybit);
-						set_bit(KEY_F18, input->keybit);
-					default:	goto ignore;
-				}
-			} else {
-				goto ignore;
-			}
-			break;
-
-		case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
+		case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */
 
 			set_bit(EV_REP, input->evbit);
 			switch(usage->hid & HID_USAGE) {
 				case 0x003:
-					/* The fn key on Apple PowerBooks */
+					/* The fn key on Apple USB keyboards */
 					map_key_clear(KEY_FN);
-					hidinput_pb_setup(input);
+					hidinput_apple_setup(input);
 					break;
 
 				default:    goto ignore;
@@ -800,38 +720,9 @@
 			break;
 
 		case HID_UP_LOGIVENDOR:
-			set_bit(EV_REP, input->evbit);
-			switch(usage->hid & HID_USAGE) {
-				/* Reported on Logitech Ultra X Media Remote */
-				case 0x004: map_key_clear(KEY_AGAIN);		break;
-				case 0x00d: map_key_clear(KEY_HOME);		break;
-				case 0x024: map_key_clear(KEY_SHUFFLE);		break;
-				case 0x025: map_key_clear(KEY_TV);		break;
-				case 0x026: map_key_clear(KEY_MENU);		break;
-				case 0x031: map_key_clear(KEY_AUDIO);		break;
-				case 0x032: map_key_clear(KEY_TEXT);		break;
-				case 0x033: map_key_clear(KEY_LAST);		break;
-				case 0x047: map_key_clear(KEY_MP3);		break;
-				case 0x048: map_key_clear(KEY_DVD);		break;
-				case 0x049: map_key_clear(KEY_MEDIA);		break;
-				case 0x04a: map_key_clear(KEY_VIDEO);		break;
-				case 0x04b: map_key_clear(KEY_ANGLE);		break;
-				case 0x04c: map_key_clear(KEY_LANGUAGE);	break;
-				case 0x04d: map_key_clear(KEY_SUBTITLE);	break;
-				case 0x051: map_key_clear(KEY_RED);		break;
-				case 0x052: map_key_clear(KEY_CLOSE);		break;
 
-				/* Reported on Petalynx Maxter remote */
-				case 0x05a: map_key_clear(KEY_TEXT);		break;
-				case 0x05b: map_key_clear(KEY_RED);		break;
-				case 0x05c: map_key_clear(KEY_GREEN);		break;
-				case 0x05d: map_key_clear(KEY_YELLOW);		break;
-				case 0x05e: map_key_clear(KEY_BLUE);		break;
-
-				default:    goto ignore;
-			}
-			break;
-
+			goto ignore;
+		
 		case HID_UP_PID:
 
 			switch(usage->hid & HID_USAGE) {
@@ -858,6 +749,7 @@
 			break;
 	}
 
+mapped:
 	if (device->quirks & HID_QUIRK_MIGHTYMOUSE) {
 		if (usage->hid == HID_GD_Z)
 			map_rel(REL_HWHEEL);
@@ -867,9 +759,10 @@
 			map_key(BTN_1);
 	}
 
-	if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) &&
-		 (usage->type == EV_REL) && (usage->code == REL_WHEEL))
-			set_bit(REL_HWHEEL, bit);
+	if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5 |
+			HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) &&
+			(usage->code == REL_WHEEL))
+		set_bit(REL_HWHEEL, bit);
 
 	if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
 		|| ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
@@ -960,25 +853,8 @@
 	if (!usage->type)
 		return;
 
-	if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
-		|| ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) {
-		if (value) hid->quirks |=  HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
-		else       hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
-		return;
-	}
-
-	if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) {
-		input_event(input, usage->type, usage->code, -value);
-		return;
-	}
-
-	if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
-		input_event(input, usage->type, REL_HWHEEL, value);
-		return;
-	}
-
-	if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value))
-		return;
+	/* handle input events for quirky devices */
+	hidinput_event_quirks(hid, field, usage, value);
 
 	if (usage->hat_min < usage->hat_max || usage->hat_dir) {
 		int hat_dir = usage->hat_dir;
@@ -1039,25 +915,6 @@
 		return;
 	}
 
-	/* Handling MS keyboards special buttons */
-	if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
-		int key = 0;
-		static int last_key = 0;
-		switch (value) {
-			case 0x01: key = KEY_F14; break;
-			case 0x02: key = KEY_F15; break;
-			case 0x04: key = KEY_F16; break;
-			case 0x08: key = KEY_F17; break;
-			case 0x10: key = KEY_F18; break;
-			default: break;
-		}
-		if (key) {
-			input_event(input, usage->type, key, 1);
-			last_key = key;
-		} else {
-			input_event(input, usage->type, last_key, 0);
-		}
-	}
 	/* report the usage code as scancode if the key status has changed */
 	if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
 		input_event(input, EV_MSC, MSC_SCAN, usage->hid);
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index c557d70..7160fa6 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -25,12 +25,13 @@
 	depends on USB_HID && INPUT=n
 
 config USB_HIDINPUT_POWERBOOK
-	bool "Enable support for iBook/PowerBook/MacBook/MacBookPro special keys"
+	bool "Enable support for Apple laptop/aluminum USB special keys"
 	default n
 	depends on USB_HID
 	help
 	  Say Y here if you want support for the special keys (Fn, Numlock) on
-	  Apple iBooks, PowerBooks, MacBooks and MacBook Pros.
+	  Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB
+	  keyboards.
 
 	  If unsure, say N.
 
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index a255285..b77b61e 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -19,6 +19,7 @@
 
 #define USB_VENDOR_ID_A4TECH		0x09da
 #define USB_DEVICE_ID_A4TECH_WCP32PU	0x0006
+#define USB_DEVICE_ID_A4TECH_X5_005D	0x000a
 
 #define USB_VENDOR_ID_AASHIMA		0x06d6
 #define USB_DEVICE_ID_AASHIMA_GAMEPAD	0x0025
@@ -28,6 +29,9 @@
 #define USB_DEVICE_ID_ACECAD_FLAIR	0x0004
 #define USB_DEVICE_ID_ACECAD_302	0x0008
 
+#define USB_VENDOR_ID_ADS_TECH 		0x06e1
+#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X	0xa155
+
 #define USB_VENDOR_ID_AIPTEK		0x08ca
 #define USB_DEVICE_ID_AIPTEK_01		0x0001
 #define USB_DEVICE_ID_AIPTEK_10		0x0010
@@ -59,6 +63,9 @@
 #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI	0x021a
 #define USB_DEVICE_ID_APPLE_GEYSER4_ISO	0x021b
 #define USB_DEVICE_ID_APPLE_GEYSER4_JIS	0x021c
+#define USB_DEVICE_ID_APPLE_ALU_ANSI	0x0220
+#define USB_DEVICE_ID_APPLE_ALU_ISO	0x0221
+#define USB_DEVICE_ID_APPLE_ALU_JIS	0x0222
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY	0x030a
 #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY	0x030b
 #define USB_DEVICE_ID_APPLE_IRCONTROL4	0x8242
@@ -94,6 +101,9 @@
 #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST	0x1500
 #define USB_DEVICE_ID_CODEMERCS_IOW_LAST	0x15ff
 
+#define USB_VENDOR_ID_CYGNAL		0x10c4
+#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X	0x818a
+
 #define USB_VENDOR_ID_CYPRESS		0x04b4
 #define USB_DEVICE_ID_CYPRESS_MOUSE	0x0001
 #define USB_DEVICE_ID_CYPRESS_HIDCOM	0x5500
@@ -114,6 +124,9 @@
 #define USB_VENDOR_ID_ESSENTIAL_REALITY	0x0d7f
 #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
 
+#define USB_VENDOR_ID_EZKEY 		0x0518
+#define USB_DEVICE_ID_BTC_8193		0x0002
+
 #define USB_VENDOR_ID_GAMERON		0x0810
 #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR	0x0001
 
@@ -134,6 +147,9 @@
 #define USB_DEVICE_ID_GOGOPEN		0x00ce
 #define USB_DEVICE_ID_PENPOWER		0x00f4
 
+#define USB_VENDOR_ID_GRETAGMACBETH	0x0971
+#define USB_DEVICE_ID_GRETAGMACBETH_HUEY	0x2005
+
 #define USB_VENDOR_ID_GRIFFIN		0x077d
 #define USB_DEVICE_ID_POWERMATE		0x0410
 #define USB_DEVICE_ID_SOUNDKNOB		0x04AA
@@ -278,7 +294,9 @@
 #define USB_DEVICE_ID_LOGITECH_HARMONY_62 0xc14d
 #define USB_DEVICE_ID_LOGITECH_HARMONY_63 0xc14e
 #define USB_DEVICE_ID_LOGITECH_HARMONY_64 0xc14f
+#define USB_DEVICE_ID_LOGITECH_EXTREME_3D	0xc215
 #define USB_DEVICE_ID_LOGITECH_WHEEL	0xc294
+#define USB_DEVICE_ID_LOGITECH_ELITE_KBD	0xc30a
 #define USB_DEVICE_ID_LOGITECH_KBD	0xc311
 #define USB_DEVICE_ID_S510_RECEIVER	0xc50c
 #define USB_DEVICE_ID_S510_RECEIVER_2	0xc517
@@ -296,6 +314,12 @@
 
 #define USB_VENDOR_ID_MICROSOFT		0x045e
 #define USB_DEVICE_ID_SIDEWINDER_GV	0x003b
+#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
+#define USB_DEVICE_ID_MS_NE4K		0x00db
+#define USB_DEVICE_ID_MS_LK6K		0x00f9
+
+#define USB_VENDOR_ID_MONTEREY		0x0566
+#define USB_DEVICE_ID_GENIUS_KB29E	0x3004
 
 #define USB_VENDOR_ID_NCR		0x0404
 #define USB_DEVICE_ID_NCR_FIRST		0x0300
@@ -324,6 +348,9 @@
 #define USB_VENDOR_ID_SAITEK		0x06a3
 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD	0xff17
 
+#define USB_VENDOR_ID_SAMSUNG		0x0419
+#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE	0x0001
+
 #define USB_VENDOR_ID_SONY			0x054c
 #define USB_DEVICE_ID_SONY_PS3_CONTROLLER	0x0268
 
@@ -368,6 +395,7 @@
 } hid_blacklist[] = {
 
 	{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
+	{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D, HID_QUIRK_2WHEEL_MOUSE_HACK_B8 },
 	{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
 
 	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS },
@@ -390,6 +418,9 @@
 	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
 	{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },
 
+	{ USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT },
+
+	{ USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE },
@@ -402,6 +433,7 @@
 	{ USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE},
 	{ USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE },
@@ -423,6 +455,7 @@
 	{ USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE },
@@ -516,14 +549,18 @@
 	{ USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
 
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
 	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
 
+	{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS },
+	{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS },
+
 	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
 
 	{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
 	{ USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
 
-	{ USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER },
+	{ USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER | HID_QUIRK_HIDDEV },
 
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
@@ -531,7 +568,9 @@
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
@@ -540,19 +579,22 @@
 
 	{ USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
 
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
-	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
 
 	{ USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
 	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS },
@@ -638,10 +680,14 @@
 	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
 	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH },
 
+	{ USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER },
+
 	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_RDESC_MACBOOK_JIS },
 
 	{ USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX },
 
+	{ USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE },
+
 	{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
 	{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
 
@@ -884,6 +930,8 @@
 	return quirks;
 }
 
+EXPORT_SYMBOL_GPL(usbhid_lookup_quirk);
+
 /*
  * Cherry Cymotion keyboard have an invalid HID report descriptor,
  * that needs fixing before we can parse it.
@@ -914,6 +962,33 @@
 	}
 }
 
+/*
+ * Samsung IrDA remote controller (reports as Cypress USB Mouse).
+ *
+ * Vendor specific report #4 has a size of 48 bit,
+ * and therefore is not accepted when inspecting the descriptors.
+ * As a workaround we reinterpret the report as:
+ *   Variable type, count 6, size 8 bit, log. maximum 255
+ * The burden to reconstruct the data is moved into user space.
+ */
+static void usbhid_fixup_samsung_irda_descriptor(unsigned char *rdesc,
+						  int rsize)
+{
+	if (rsize >= 182 && rdesc[175] == 0x25
+			 && rdesc[176] == 0x40
+			 && rdesc[177] == 0x75
+			 && rdesc[178] == 0x30
+			 && rdesc[179] == 0x95
+			 && rdesc[180] == 0x01
+			 && rdesc[182] == 0x40) {
+		printk(KERN_INFO "Fixing up Samsung IrDA report descriptor\n");
+		rdesc[176] = 0xff;
+		rdesc[178] = 0x08;
+		rdesc[180] = 0x06;
+		rdesc[182] = 0x42;
+	}
+}
+
 /* Petalynx Maxter Remote has maximum for consumer page set too low */
 static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize)
 {
@@ -965,6 +1040,14 @@
 	}
 }
 
+static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rsize)
+{
+	if (rsize >= 30 && rdesc[29] == 0x05
+			&& rdesc[30] == 0x09) {
+		printk(KERN_INFO "Fixing up button/consumer in HID report descriptor\n");
+		rdesc[30] = 0x0c;
+	}
+}
 
 static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize)
 {
@@ -982,6 +1065,13 @@
 
 	if (quirks & HID_QUIRK_RDESC_MACBOOK_JIS)
 		usbhid_fixup_macbook_descriptor(rdesc, rsize);
+
+	if (quirks & HID_QUIRK_RDESC_BUTTON_CONSUMER)
+		usbhid_fixup_button_consumer_descriptor(rdesc, rsize);
+
+	if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE)
+		usbhid_fixup_samsung_irda_descriptor(rdesc, rsize);
+
 }
 
 /**
diff --git a/drivers/hid/usbhid/hid-tmff.c b/drivers/hid/usbhid/hid-tmff.c
index 69882a7..144578b 100644
--- a/drivers/hid/usbhid/hid-tmff.c
+++ b/drivers/hid/usbhid/hid-tmff.c
@@ -137,7 +137,8 @@
 int hid_tmff_init(struct hid_device *hid)
 {
 	struct tmff_device *tmff;
-	struct list_head *pos;
+	struct hid_report *report;
+	struct list_head *report_list;
 	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
 	struct input_dev *input_dev = hidinput->input;
 	const signed short *ff_bits = ff_joystick;
@@ -149,8 +150,8 @@
 		return -ENOMEM;
 
 	/* Find the report to use */
-	list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) {
-		struct hid_report *report = (struct hid_report *)pos;
+	report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	list_for_each_entry(report, report_list, list) {
 		int fieldnum;
 
 		for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) {
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index 775a1ef..5d9dbb4 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -235,6 +235,14 @@
 	if (!usb_endpoint_is_int_in(endpoint))
 		return -ENODEV;
 
+#ifdef CONFIG_USB_HID
+	if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
+				le16_to_cpu(dev->descriptor.idProduct))
+			& HID_QUIRK_IGNORE) {
+		return -ENODEV;
+	}
+#endif
+
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c
index f8ad691..df0d96d 100644
--- a/drivers/hid/usbhid/usbmouse.c
+++ b/drivers/hid/usbhid/usbmouse.c
@@ -131,6 +131,14 @@
 	if (!usb_endpoint_is_int_in(endpoint))
 		return -ENODEV;
 
+#ifdef CONFIG_USB_HID
+	if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
+				le16_to_cpu(dev->descriptor.idProduct))
+			& (HID_QUIRK_IGNORE|HID_QUIRK_IGNORE_MOUSE)) {
+		return -ENODEV;
+	}
+#endif
+
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 8d12b26..b61f56b 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -643,7 +643,7 @@
 
 config I2C_MV64XXX
 	tristate "Marvell mv64xxx I2C Controller"
-	depends on MV64X60 && EXPERIMENTAL
+	depends on (MV64X60 || ARCH_ORION) && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the
 	  built-in I2C interface on the Marvell 64xxx line of host bridges.
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index bb7bf68..036e6a8 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -1,6 +1,6 @@
 /*
- * Driver for the i2c controller on the Marvell line of host bridges for MIPS
- * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0).
+ * Driver for the i2c controller on the Marvell line of host bridges
+ * (e.g, gt642[46]0, mv643[46]0, mv644[46]0, and Orion SoC family).
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
@@ -14,7 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
-#include <linux/mv643xx.h>
+#include <linux/mv643xx_i2c.h>
 #include <linux/platform_device.h>
 
 #include <asm/io.h>
@@ -86,6 +86,7 @@
 	u32			cntl_bits;
 	void __iomem		*reg_base;
 	u32			reg_base_p;
+	u32			reg_size;
 	u32			addr1;
 	u32			addr2;
 	u32			bytes_left;
@@ -463,17 +464,20 @@
 mv64xxx_i2c_map_regs(struct platform_device *pd,
 	struct mv64xxx_i2c_data *drv_data)
 {
-	struct resource	*r;
+	int size;
+	struct resource	*r = platform_get_resource(pd, IORESOURCE_MEM, 0);
 
-	if ((r = platform_get_resource(pd, IORESOURCE_MEM, 0)) &&
-		request_mem_region(r->start, MV64XXX_I2C_REG_BLOCK_SIZE,
-			drv_data->adapter.name)) {
+	if (!r)
+		return -ENODEV;
 
-		drv_data->reg_base = ioremap(r->start,
-			MV64XXX_I2C_REG_BLOCK_SIZE);
-		drv_data->reg_base_p = r->start;
-	} else
-		return -ENOMEM;
+	size = r->end - r->start + 1;
+
+	if (!request_mem_region(r->start, size, drv_data->adapter.name))
+		return -EBUSY;
+
+	drv_data->reg_base = ioremap(r->start, size);
+	drv_data->reg_base_p = r->start;
+	drv_data->reg_size = size;
 
 	return 0;
 }
@@ -483,8 +487,7 @@
 {
 	if (drv_data->reg_base) {
 		iounmap(drv_data->reg_base);
-		release_mem_region(drv_data->reg_base_p,
-			MV64XXX_I2C_REG_BLOCK_SIZE);
+		release_mem_region(drv_data->reg_base_p, drv_data->reg_size);
 	}
 
 	drv_data->reg_base = NULL;
@@ -529,7 +532,6 @@
 	drv_data->adapter.owner = THIS_MODULE;
 	drv_data->adapter.class = I2C_CLASS_HWMON;
 	drv_data->adapter.timeout = pdata->timeout;
-	drv_data->adapter.retries = pdata->retries;
 	drv_data->adapter.nr = pd->id;
 	platform_set_drvdata(pd, drv_data);
 	i2c_set_adapdata(&drv_data->adapter, drv_data);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 44b033e..74c6087 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -655,9 +655,9 @@
 					BUG();
 			} else {
 				spin_lock_irqsave(&ide_lock, flags);
-				end_that_request_chunk(failed, 0,
-							failed->data_len);
-				end_that_request_last(failed, 0);
+				if (__blk_end_request(failed, -EIO,
+						      failed->data_len))
+					BUG();
 				spin_unlock_irqrestore(&ide_lock, flags);
 			}
 		} else
@@ -1647,6 +1647,17 @@
 	return 1;
 }
 
+/*
+ * Called from blk_end_request_callback() after the data of the request
+ * is completed and before the request is completed.
+ * By returning value '1', blk_end_request_callback() returns immediately
+ * without completing the request.
+ */
+static int cdrom_newpc_intr_dummy_cb(struct request *rq)
+{
+	return 1;
+}
+
 typedef void (xfer_func_t)(ide_drive_t *, void *, u32);
 
 /*
@@ -1685,9 +1696,13 @@
 			return ide_error(drive, "dma error", stat);
 		}
 
-		end_that_request_chunk(rq, 1, rq->data_len);
-		rq->data_len = 0;
-		goto end_request;
+		spin_lock_irqsave(&ide_lock, flags);
+		if (__blk_end_request(rq, 0, rq->data_len))
+			BUG();
+		HWGROUP(drive)->rq = NULL;
+		spin_unlock_irqrestore(&ide_lock, flags);
+
+		return ide_stopped;
 	}
 
 	/*
@@ -1705,8 +1720,15 @@
 	/*
 	 * If DRQ is clear, the command has completed.
 	 */
-	if ((stat & DRQ_STAT) == 0)
-		goto end_request;
+	if ((stat & DRQ_STAT) == 0) {
+		spin_lock_irqsave(&ide_lock, flags);
+		if (__blk_end_request(rq, 0, 0))
+			BUG();
+		HWGROUP(drive)->rq = NULL;
+		spin_unlock_irqrestore(&ide_lock, flags);
+
+		return ide_stopped;
+	}
 
 	/*
 	 * check which way to transfer data
@@ -1759,7 +1781,14 @@
 		rq->data_len -= blen;
 
 		if (rq->bio)
-			end_that_request_chunk(rq, 1, blen);
+			/*
+			 * The request can't be completed until DRQ is cleared.
+			 * So complete the data, but don't complete the request
+			 * using the dummy function for the callback feature
+			 * of blk_end_request_callback().
+			 */
+			blk_end_request_callback(rq, 0, blen,
+						 cdrom_newpc_intr_dummy_cb);
 		else
 			rq->data += blen;
 	}
@@ -1780,14 +1809,6 @@
 
 	ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL);
 	return ide_started;
-
-end_request:
-	spin_lock_irqsave(&ide_lock, flags);
-	blkdev_dequeue_request(rq);
-	end_that_request_last(rq, 1);
-	HWGROUP(drive)->rq = NULL;
-	spin_unlock_irqrestore(&ide_lock, flags);
-	return ide_stopped;
 }
 
 static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 6f8f544..e6bb9cf 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -58,15 +58,19 @@
 			     int uptodate, unsigned int nr_bytes, int dequeue)
 {
 	int ret = 1;
+	int error = 0;
+
+	if (uptodate <= 0)
+		error = uptodate ? uptodate : -EIO;
 
 	/*
 	 * if failfast is set on a request, override number of sectors and
 	 * complete the whole request right now
 	 */
-	if (blk_noretry_request(rq) && end_io_error(uptodate))
+	if (blk_noretry_request(rq) && error)
 		nr_bytes = rq->hard_nr_sectors << 9;
 
-	if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors)
+	if (!blk_fs_request(rq) && error && !rq->errors)
 		rq->errors = -EIO;
 
 	/*
@@ -78,14 +82,9 @@
 		ide_dma_on(drive);
 	}
 
-	if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
-		add_disk_randomness(rq->rq_disk);
-		if (dequeue) {
-			if (!list_empty(&rq->queuelist))
-				blkdev_dequeue_request(rq);
+	if (!__blk_end_request(rq, error, nr_bytes)) {
+		if (dequeue)
 			HWGROUP(drive)->rq = NULL;
-		}
-		end_that_request_last(rq, uptodate);
 		ret = 0;
 	}
 
@@ -290,9 +289,9 @@
 		drive->blocked = 0;
 		blk_start_queue(drive->queue);
 	}
-	blkdev_dequeue_request(rq);
 	HWGROUP(drive)->rq = NULL;
-	end_that_request_last(rq, 1);
+	if (__blk_end_request(rq, 0, 0))
+		BUG();
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
@@ -387,10 +386,10 @@
 	}
 
 	spin_lock_irqsave(&ide_lock, flags);
-	blkdev_dequeue_request(rq);
 	HWGROUP(drive)->rq = NULL;
 	rq->errors = err;
-	end_that_request_last(rq, !rq->errors);
+	if (__blk_end_request(rq, (rq->errors ? -EIO : 0), 0))
+		BUG();
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index b1b2e07..99d92f5 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -74,10 +74,10 @@
 
 static unsigned long calc_waittime(struct corgi_ts *corgi_ts)
 {
-	unsigned long hsync_len = corgi_ts->machinfo->get_hsync_len();
+	unsigned long hsync_invperiod = corgi_ts->machinfo->get_hsync_invperiod();
 
-	if (hsync_len)
-		return get_clk_frequency_khz(0)*1000/hsync_len;
+	if (hsync_invperiod)
+		return get_clk_frequency_khz(0)*1000/hsync_invperiod;
 	else
 		return 0;
 }
@@ -114,7 +114,7 @@
 			if (timer2-timer1 > wait_time) {
 				/* too slow - timeout, try again */
 				corgi_ts->machinfo->wait_hsync();
-				/* get OSCR */
+				/* get CCNT */
 				CCNT(timer1);
 				/* Wait after HSync */
 				CCNT(timer2);
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index e4ad7a1..a953148 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -412,13 +412,13 @@
 /**
  *	i2o_block_end_request - Post-processing of completed commands
  *	@req: request which should be completed
- *	@uptodate: 1 for success, 0 for I/O error, < 0 for specific error
+ *	@error: 0 for success, < 0 for error
  *	@nr_bytes: number of bytes to complete
  *
  *	Mark the request as complete. The lock must not be held when entering.
  *
  */
-static void i2o_block_end_request(struct request *req, int uptodate,
+static void i2o_block_end_request(struct request *req, int error,
 				  int nr_bytes)
 {
 	struct i2o_block_request *ireq = req->special;
@@ -426,22 +426,18 @@
 	struct request_queue *q = req->q;
 	unsigned long flags;
 
-	if (end_that_request_chunk(req, uptodate, nr_bytes)) {
+	if (blk_end_request(req, error, nr_bytes)) {
 		int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT);
 
 		if (blk_pc_request(req))
 			leftover = req->data_len;
 
-		if (end_io_error(uptodate))
-			end_that_request_chunk(req, 0, leftover);
+		if (error)
+			blk_end_request(req, -EIO, leftover);
 	}
 
-	add_disk_randomness(req->rq_disk);
-
 	spin_lock_irqsave(q->queue_lock, flags);
 
-	end_that_request_last(req, uptodate);
-
 	if (likely(dev)) {
 		dev->open_queue_depth--;
 		list_del(&ireq->queue);
@@ -468,7 +464,7 @@
 			   struct i2o_message *msg)
 {
 	struct request *req;
-	int uptodate = 1;
+	int error = 0;
 
 	req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
 	if (unlikely(!req)) {
@@ -501,10 +497,10 @@
 
 		req->errors++;
 
-		uptodate = 0;
+		error = -EIO;
 	}
 
-	i2o_block_end_request(req, uptodate, le32_to_cpu(msg->body[1]));
+	i2o_block_end_request(req, error, le32_to_cpu(msg->body[1]));
 
 	return 1;
 };
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c
index b7c8e78..61aeaf7 100644
--- a/drivers/mfd/ucb1x00-assabet.c
+++ b/drivers/mfd/ucb1x00-assabet.c
@@ -20,7 +20,7 @@
 #include "ucb1x00.h"
 
 #define UCB1X00_ATTR(name,input)\
-static ssize_t name##_show(struct device *dev, struct device_attribute *attr,
+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
 			   char *buf)	\
 {								\
 	struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);		\
@@ -38,17 +38,17 @@
 
 static int ucb1x00_assabet_add(struct ucb1x00_dev *dev)
 {
-	device_create_file(&dev->ucb->dev, &device_attr_vbatt);
-	device_create_file(&dev->ucb->dev, &device_attr_vcharger);
-	device_create_file(&dev->ucb->dev, &device_attr_batt_temp);
+	device_create_file(&dev->ucb->dev, &dev_attr_vbatt);
+	device_create_file(&dev->ucb->dev, &dev_attr_vcharger);
+	device_create_file(&dev->ucb->dev, &dev_attr_batt_temp);
 	return 0;
 }
 
 static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev)
 {
-	device_remove_file(&dev->ucb->cdev, &device_attr_batt_temp);
-	device_remove_file(&dev->ucb->cdev, &device_attr_vcharger);
-	device_remove_file(&dev->ucb->cdev, &device_attr_vbatt);
+	device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp);
+	device_remove_file(&dev->ucb->dev, &dev_attr_vcharger);
+	device_remove_file(&dev->ucb->dev, &dev_attr_vbatt);
 }
 
 static struct ucb1x00_driver ucb1x00_assabet_driver = {
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index aeb32a9..91ded3e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -348,15 +348,7 @@
 		 * A block was successfully transferred.
 		 */
 		spin_lock_irq(&md->lock);
-		ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered);
-		if (!ret) {
-			/*
-			 * The whole request completed successfully.
-			 */
-			add_disk_randomness(req->rq_disk);
-			blkdev_dequeue_request(req);
-			end_that_request_last(req, 1);
-		}
+		ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
 		spin_unlock_irq(&md->lock);
 	} while (ret);
 
@@ -386,27 +378,21 @@
 			else
 				bytes = blocks << 9;
 			spin_lock_irq(&md->lock);
-			ret = end_that_request_chunk(req, 1, bytes);
+			ret = __blk_end_request(req, 0, bytes);
 			spin_unlock_irq(&md->lock);
 		}
 	} else if (rq_data_dir(req) != READ &&
 		   (card->host->caps & MMC_CAP_MULTIWRITE)) {
 		spin_lock_irq(&md->lock);
-		ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered);
+		ret = __blk_end_request(req, 0, brq.data.bytes_xfered);
 		spin_unlock_irq(&md->lock);
 	}
 
 	mmc_release_host(card->host);
 
 	spin_lock_irq(&md->lock);
-	while (ret) {
-		ret = end_that_request_chunk(req, 0,
-				req->current_nr_sectors << 9);
-	}
-
-	add_disk_randomness(req->rq_disk);
-	blkdev_dequeue_request(req);
-	end_that_request_last(req, 0);
+	while (ret)
+		ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
 	spin_unlock_irq(&md->lock);
 
 	return 0;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 30cd13b..7731dde 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -94,8 +94,8 @@
 		printk(KERN_ERR "MMC: killing requests for dead queue\n");
 		while ((req = elv_next_request(q)) != NULL) {
 			do {
-				ret = end_that_request_chunk(req, 0,
-					req->current_nr_sectors << 9);
+				ret = __blk_end_request(req, -EIO,
+							blk_rq_cur_bytes(req));
 			} while (ret);
 		}
 		return;
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 1654a33..1ea8482 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -65,6 +65,8 @@
 	unsigned int		dma_len;
 
 	unsigned int		dma_dir;
+	unsigned int		dma_drcmrrx;
+	unsigned int		dma_drcmrtx;
 };
 
 static void pxamci_stop_clock(struct pxamci_host *host)
@@ -131,13 +133,13 @@
 	if (data->flags & MMC_DATA_READ) {
 		host->dma_dir = DMA_FROM_DEVICE;
 		dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG;
-		DRCMRTXMMC = 0;
-		DRCMRRXMMC = host->dma | DRCMR_MAPVLD;
+		DRCMR(host->dma_drcmrtx) = 0;
+		DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD;
 	} else {
 		host->dma_dir = DMA_TO_DEVICE;
 		dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC;
-		DRCMRRXMMC = 0;
-		DRCMRTXMMC = host->dma | DRCMR_MAPVLD;
+		DRCMR(host->dma_drcmrrx) = 0;
+		DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD;
 	}
 
 	dcmd |= DCMD_BURST32 | DCMD_WIDTH1;
@@ -375,14 +377,23 @@
 		if (host->clkrt == CLKRT_OFF)
 			clk_enable(host->clk);
 
-		/*
-		 * clk might result in a lower divisor than we
-		 * desire.  check for that condition and adjust
-		 * as appropriate.
-		 */
-		if (rate / clk > ios->clock)
-			clk <<= 1;
-		host->clkrt = fls(clk) - 1;
+		if (ios->clock == 26000000) {
+			/* to support 26MHz on pxa300/pxa310 */
+			host->clkrt = 7;
+		} else {
+			/* to handle (19.5MHz, 26MHz) */
+			if (!clk)
+				clk = 1;
+
+			/*
+			 * clk might result in a lower divisor than we
+			 * desire.  check for that condition and adjust
+			 * as appropriate.
+			 */
+			if (rate / clk > ios->clock)
+				clk <<= 1;
+			host->clkrt = fls(clk) - 1;
+		}
 
 		/*
 		 * we write clkrt on the next command
@@ -459,7 +470,7 @@
 {
 	struct mmc_host *mmc;
 	struct pxamci_host *host = NULL;
-	struct resource *r;
+	struct resource *r, *dmarx, *dmatx;
 	int ret, irq;
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -519,7 +530,8 @@
 	 * Calculate minimum clock rate, rounding up.
 	 */
 	mmc->f_min = (host->clkrate + 63) / 64;
-	mmc->f_max = host->clkrate;
+	mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000
+							  : host->clkrate;
 
 	mmc->ocr_avail = host->pdata ?
 			 host->pdata->ocr_mask :
@@ -529,6 +541,9 @@
 	if (!cpu_is_pxa21x() && !cpu_is_pxa25x()) {
 		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
 		host->cmdat |= CMDAT_SDIO_INT_EN;
+		if (cpu_is_pxa300() || cpu_is_pxa310())
+			mmc->caps |= MMC_CAP_MMC_HIGHSPEED |
+				     MMC_CAP_SD_HIGHSPEED;
 	}
 
 	host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
@@ -570,6 +585,20 @@
 
 	platform_set_drvdata(pdev, mmc);
 
+	dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (!dmarx) {
+		ret = -ENXIO;
+		goto out;
+	}
+	host->dma_drcmrrx = dmarx->start;
+
+	dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+	if (!dmatx) {
+		ret = -ENXIO;
+		goto out;
+	}
+	host->dma_drcmrtx = dmatx->start;
+
 	if (host->pdata && host->pdata->init)
 		host->pdata->init(&pdev->dev, pxamci_detect_irq, mmc);
 
@@ -613,8 +642,8 @@
 		       END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
 		       host->base + MMC_I_MASK);
 
-		DRCMRRXMMC = 0;
-		DRCMRTXMMC = 0;
+		DRCMR(host->dma_drcmrrx) = 0;
+		DRCMR(host->dma_drcmrtx) = 0;
 
 		free_irq(host->irq, host);
 		pxa_free_dma(host->dma);
diff --git a/drivers/mmc/host/pxamci.h b/drivers/mmc/host/pxamci.h
index 748c770..f6c2e2f 100644
--- a/drivers/mmc/host/pxamci.h
+++ b/drivers/mmc/host/pxamci.h
@@ -68,7 +68,7 @@
 #define PRG_DONE		(1 << 1)
 #define DATA_TRAN_DONE		(1 << 0)
 
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #define MMC_I_MASK_ALL          0x00001fff
 #else
 #define MMC_I_MASK_ALL          0x0000007f
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9af05a2..a672866 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -212,7 +212,7 @@
 
 config MACB
 	tristate "Atmel MACB support"
-	depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263
+	depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91CAP9
 	select PHYLIB
 	help
 	  The Atmel MACB ethernet interface is found on many AT32 and AT91
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 3286d2a..6a20a54 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -66,6 +66,7 @@
 #include <linux/dm9000.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/irq.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
@@ -113,7 +114,7 @@
 #define writesl	outsl
 #define DM9000_IRQ_FLAGS	(IRQF_SHARED | IRQF_TRIGGER_HIGH)
 #else
-#define DM9000_IRQ_FLAGS	IRQF_SHARED
+#define DM9000_IRQ_FLAGS	(IRQF_SHARED | IRQT_RISING)
 #endif
 
 /*
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 7da7589..4020e9e 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1775,7 +1775,8 @@
  * o  actually GRAB the irq.
  * o  GRAB the region
  */
-static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
+static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
+			    unsigned long irq_flags)
 {
 	struct smc_local *lp = netdev_priv(dev);
 	static int version_printed = 0;
@@ -1941,7 +1942,7 @@
 	}
 
 	/* Grab the IRQ */
-      	retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
+	retval = request_irq(dev->irq, &smc_interrupt, irq_flags, dev->name, dev);
       	if (retval)
       		goto err_out;
 
@@ -2123,8 +2124,9 @@
 static int smc_drv_probe(struct platform_device *pdev)
 {
 	struct net_device *ndev;
-	struct resource *res;
+	struct resource *res, *ires;
 	unsigned int __iomem *addr;
+	unsigned long irq_flags = SMC_IRQ_FLAGS;
 	int ret;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
@@ -2150,12 +2152,17 @@
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 
 	ndev->dma = (unsigned char)-1;
-	ndev->irq = platform_get_irq(pdev, 0);
-	if (ndev->irq < 0) {
+
+	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!ires) {
 		ret = -ENODEV;
 		goto out_free_netdev;
 	}
 
+	ndev->irq = ires->start;
+	if (SMC_IRQ_FLAGS == -1)
+		irq_flags = ires->flags & IRQF_TRIGGER_MASK;
+
 	ret = smc_request_attrib(pdev);
 	if (ret)
 		goto out_free_netdev;
@@ -2181,7 +2188,7 @@
 #endif
 
 	platform_set_drvdata(pdev, ndev);
-	ret = smc_probe(ndev, addr);
+	ret = smc_probe(ndev, addr, irq_flags);
 	if (ret != 0)
 		goto out_iounmap;
 
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 07b7f71..271c28d 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -54,6 +54,7 @@
 #define SMC_outw(v, a, r)	writew(v, (a) + (r))
 #define SMC_insw(a, r, p, l)	readsw((a) + (r), p, l)
 #define SMC_outsw(a, r, p, l)	writesw((a) + (r), p, l)
+#define SMC_IRQ_FLAGS		(-1)	/* from resource */
 
 #elif defined(CONFIG_BLACKFIN)
 
@@ -158,7 +159,7 @@
 #define SMC_outw(v, a, r)	writew(v, (a) + (r))
 #define SMC_outsw(a, r, p, l)	writesw((a) + (r), p, l)
 
-#define SMC_IRQ_FLAGS		(0)
+#define SMC_IRQ_FLAGS		(-1)
 
 #elif defined(CONFIG_SA1100_ASSABET)
 
@@ -177,6 +178,7 @@
 #define SMC_outb(v, a, r)	writeb(v, (a) + (r))
 #define SMC_insb(a, r, p, l)	readsb((a) + (r), p, (l))
 #define SMC_outsb(a, r, p, l)	writesb((a) + (r), p, (l))
+#define SMC_IRQ_FLAGS		(-1)	/* from resource */
 
 #elif	defined(CONFIG_MACH_LOGICPD_PXA270)
 
@@ -194,7 +196,8 @@
 #elif	defined(CONFIG_ARCH_INNOKOM) || \
 	defined(CONFIG_MACH_MAINSTONE) || \
 	defined(CONFIG_ARCH_PXA_IDP) || \
-	defined(CONFIG_ARCH_RAMSES)
+	defined(CONFIG_ARCH_RAMSES) || \
+	defined(CONFIG_ARCH_PCM027)
 
 #define SMC_CAN_USE_8BIT	1
 #define SMC_CAN_USE_16BIT	1
@@ -210,6 +213,7 @@
 #define SMC_outl(v, a, r)	writel(v, (a) + (r))
 #define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
 #define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
+#define SMC_IRQ_FLAGS		(-1)	/* from resource */
 
 /* We actually can't write halfwords properly if not word aligned */
 static inline void
@@ -238,6 +242,7 @@
 #define SMC_outsw(a, r, p, l)   outsw((a) + (r), p, l)
 #define SMC_outb(v, a, r)       writeb(v, (a) + (r))
 #define SMC_outw(v, a, r)       writew(v, (a) + (r))
+#define SMC_IRQ_FLAGS		(-1)	/* from resource */
 
 #elif	defined(CONFIG_ARCH_OMAP)
 
@@ -252,17 +257,7 @@
 #define SMC_outw(v, a, r)	writew(v, (a) + (r))
 #define SMC_insw(a, r, p, l)	readsw((a) + (r), p, l)
 #define SMC_outsw(a, r, p, l)	writesw((a) + (r), p, l)
-
-#include <asm/mach-types.h>
-#include <asm/arch/cpu.h>
-
-#define	SMC_IRQ_FLAGS (( \
-		   machine_is_omap_h2() \
-		|| machine_is_omap_h3() \
-		|| machine_is_omap_h4() \
-		|| (machine_is_omap_innovator() && !cpu_is_omap1510()) \
-	) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING)
-
+#define	SMC_IRQ_FLAGS		(-1)	/* from resource */
 
 #elif	defined(CONFIG_SH_SH4202_MICRODEV)
 
@@ -453,8 +448,7 @@
 #define SMC_outl(v, a, r)	writel(v, (a) + (r))
 #define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
 #define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
-
-#define SMC_IRQ_FLAGS		(0)
+#define SMC_IRQ_FLAGS		(-1)	/* from resource */
 
 #else
 
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 874923f..e439044 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -29,6 +29,7 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 6f1e9a9..2eb3852 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -337,6 +337,8 @@
 	if (IS_ERR(rtc))
 		return PTR_ERR(rtc);
 
+	device_init_wakeup(&pdev->dev, 1);
+
 	platform_set_drvdata(pdev, rtc);
 
 	return 0;
@@ -352,9 +354,38 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int sa1100_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	if (pdev->dev.power.power_state.event != state.event) {
+		if (state.event == PM_EVENT_SUSPEND &&
+		    device_may_wakeup(&pdev->dev))
+			enable_irq_wake(IRQ_RTCAlrm);
+
+		pdev->dev.power.power_state = state;
+	}
+	return 0;
+}
+
+static int sa1100_rtc_resume(struct platform_device *pdev)
+{
+	if (pdev->dev.power.power_state.event != PM_EVENT_ON) {
+		if (device_may_wakeup(&pdev->dev))
+			disable_irq_wake(IRQ_RTCAlrm);
+		pdev->dev.power.power_state = PMSG_ON;
+	}
+	return 0;
+}
+#else
+#define sa1100_rtc_suspend	NULL
+#define sa1100_rtc_resume	NULL
+#endif
+
 static struct platform_driver sa1100_rtc_driver = {
 	.probe		= sa1100_rtc_probe,
 	.remove		= sa1100_rtc_remove,
+	.suspend	= sa1100_rtc_suspend,
+	.resume		= sa1100_rtc_resume,
 	.driver		= {
 		.name		= "sa1100-rtc",
 	},
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 1db15f3..d640427 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1595,12 +1595,10 @@
 /*
  * posts the buffer_cache about a finalized request
  */
-static inline void dasd_end_request(struct request *req, int uptodate)
+static inline void dasd_end_request(struct request *req, int error)
 {
-	if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
+	if (__blk_end_request(req, error, blk_rq_bytes(req)))
 		BUG();
-	add_disk_randomness(req->rq_disk);
-	end_that_request_last(req, uptodate);
 }
 
 /*
@@ -1657,7 +1655,7 @@
 				      "Rejecting write request %p",
 				      req);
 			blkdev_dequeue_request(req);
-			dasd_end_request(req, 0);
+			dasd_end_request(req, -EIO);
 			continue;
 		}
 		cqr = basedev->discipline->build_cp(basedev, block, req);
@@ -1686,7 +1684,7 @@
 				      "on request %p",
 				      PTR_ERR(cqr), req);
 			blkdev_dequeue_request(req);
-			dasd_end_request(req, 0);
+			dasd_end_request(req, -EIO);
 			continue;
 		}
 		/*
@@ -1705,11 +1703,14 @@
 {
 	struct request *req;
 	int status;
+	int error = 0;
 
 	req = (struct request *) cqr->callback_data;
 	dasd_profile_end(cqr->block, cqr, req);
 	status = cqr->memdev->discipline->free_cp(cqr, req);
-	dasd_end_request(req, status);
+	if (status <= 0)
+		error = status ? status : -EIO;
+	dasd_end_request(req, error);
 }
 
 /*
@@ -2009,7 +2010,7 @@
 	spin_lock_irq(&block->request_queue_lock);
 	while ((req = elv_next_request(block->request_queue))) {
 		blkdev_dequeue_request(req);
-		dasd_end_request(req, 0);
+		dasd_end_request(req, -EIO);
 	}
 	spin_unlock_irq(&block->request_queue_lock);
 }
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index eeb92e2..ddc4a11 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -74,11 +74,10 @@
  * Post finished request.
  */
 static void
-tapeblock_end_request(struct request *req, int uptodate)
+tapeblock_end_request(struct request *req, int error)
 {
-	if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
+	if (__blk_end_request(req, error, blk_rq_bytes(req)))
 		BUG();
-	end_that_request_last(req, uptodate);
 }
 
 static void
@@ -91,7 +90,7 @@
 
 	device = ccw_req->device;
 	req = (struct request *) data;
-	tapeblock_end_request(req, ccw_req->rc == 0);
+	tapeblock_end_request(req, (ccw_req->rc == 0) ? 0 : -EIO);
 	if (ccw_req->rc == 0)
 		/* Update position. */
 		device->blk_data.block_position =
@@ -119,7 +118,7 @@
 	ccw_req = device->discipline->bread(device, req);
 	if (IS_ERR(ccw_req)) {
 		DBF_EVENT(1, "TBLOCK: bread failed\n");
-		tapeblock_end_request(req, 0);
+		tapeblock_end_request(req, -EIO);
 		return PTR_ERR(ccw_req);
 	}
 	ccw_req->callback = __tapeblock_end_request;
@@ -132,7 +131,7 @@
 		 * Start/enqueueing failed. No retries in
 		 * this case.
 		 */
-		tapeblock_end_request(req, 0);
+		tapeblock_end_request(req, -EIO);
 		device->discipline->free_bread(ccw_req);
 	}
 
@@ -177,7 +176,7 @@
 		if (rq_data_dir(req) == WRITE) {
 			DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
 			blkdev_dequeue_request(req);
-			tapeblock_end_request(req, 0);
+			tapeblock_end_request(req, -EIO);
 			continue;
 		}
 		spin_unlock_irq(&device->blk_data.request_queue_lock);
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 02e9189..db8bc20 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -919,8 +919,8 @@
 	}
 
 	/* kill current request */
-	blkdev_dequeue_request(req);
-	end_that_request_last(req, 0);
+	if (__blk_end_request(req, -EIO, 0))
+		BUG();
 	if (blk_sense_request(req))
 		kfree(scsi->pc->buffer);
 	kfree(scsi->pc);
@@ -929,8 +929,8 @@
 
 	/* now nuke the drive queue */
 	while ((req = elv_next_request(drive->queue))) {
-		blkdev_dequeue_request(req);
-		end_that_request_last(req, 0);
+		if (__blk_end_request(req, -EIO, 0))
+			BUG();
 	}
 
 	HWGROUP(drive)->rq = NULL;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 4cf902e..7c4c889 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -634,7 +634,7 @@
  *		of upper level post-processing and scsi_io_completion).
  *
  * Arguments:   cmd	 - command that is complete.
- *              uptodate - 1 if I/O indicates success, <= 0 for I/O error.
+ *              error    - 0 if I/O indicates success, < 0 for I/O error.
  *              bytes    - number of bytes of completed I/O
  *		requeue  - indicates whether we should requeue leftovers.
  *
@@ -649,26 +649,25 @@
  *		at some point during this call.
  * Notes:	If cmd was requeued, upon return it will be a stale pointer.
  */
-static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
+static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
 					  int bytes, int requeue)
 {
 	struct request_queue *q = cmd->device->request_queue;
 	struct request *req = cmd->request;
-	unsigned long flags;
 
 	/*
 	 * If there are blocks left over at the end, set up the command
 	 * to queue the remainder of them.
 	 */
-	if (end_that_request_chunk(req, uptodate, bytes)) {
+	if (blk_end_request(req, error, bytes)) {
 		int leftover = (req->hard_nr_sectors << 9);
 
 		if (blk_pc_request(req))
 			leftover = req->data_len;
 
 		/* kill remainder if no retrys */
-		if (!uptodate && blk_noretry_request(req))
-			end_that_request_chunk(req, 0, leftover);
+		if (error && blk_noretry_request(req))
+			blk_end_request(req, error, leftover);
 		else {
 			if (requeue) {
 				/*
@@ -683,14 +682,6 @@
 		}
 	}
 
-	add_disk_randomness(req->rq_disk);
-
-	spin_lock_irqsave(q->queue_lock, flags);
-	if (blk_rq_tagged(req))
-		blk_queue_end_tag(q, req);
-	end_that_request_last(req, uptodate);
-	spin_unlock_irqrestore(q->queue_lock, flags);
-
 	/*
 	 * This will goose the queue request function at the end, so we don't
 	 * need to worry about launching another command.
@@ -739,138 +730,43 @@
 	return index;
 }
 
-struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+static void scsi_sg_free(struct scatterlist *sgl, unsigned int nents)
 {
 	struct scsi_host_sg_pool *sgp;
-	struct scatterlist *sgl, *prev, *ret;
-	unsigned int index;
-	int this, left;
+
+	sgp = scsi_sg_pools + scsi_sgtable_index(nents);
+	mempool_free(sgl, sgp->pool);
+}
+
+static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask)
+{
+	struct scsi_host_sg_pool *sgp;
+
+	sgp = scsi_sg_pools + scsi_sgtable_index(nents);
+	return mempool_alloc(sgp->pool, gfp_mask);
+}
+
+int scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+{
+	int ret;
 
 	BUG_ON(!cmd->use_sg);
 
-	left = cmd->use_sg;
-	ret = prev = NULL;
-	do {
-		this = left;
-		if (this > SCSI_MAX_SG_SEGMENTS) {
-			this = SCSI_MAX_SG_SEGMENTS - 1;
-			index = SG_MEMPOOL_NR - 1;
-		} else
-			index = scsi_sgtable_index(this);
+	ret = __sg_alloc_table(&cmd->sg_table, cmd->use_sg,
+			       SCSI_MAX_SG_SEGMENTS, gfp_mask, scsi_sg_alloc);
+	if (unlikely(ret))
+		__sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS,
+				scsi_sg_free);
 
-		left -= this;
-
-		sgp = scsi_sg_pools + index;
-
-		sgl = mempool_alloc(sgp->pool, gfp_mask);
-		if (unlikely(!sgl))
-			goto enomem;
-
-		sg_init_table(sgl, sgp->size);
-
-		/*
-		 * first loop through, set initial index and return value
-		 */
-		if (!ret)
-			ret = sgl;
-
-		/*
-		 * chain previous sglist, if any. we know the previous
-		 * sglist must be the biggest one, or we would not have
-		 * ended up doing another loop.
-		 */
-		if (prev)
-			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
-
-		/*
-		 * if we have nothing left, mark the last segment as
-		 * end-of-list
-		 */
-		if (!left)
-			sg_mark_end(&sgl[this - 1]);
-
-		/*
-		 * don't allow subsequent mempool allocs to sleep, it would
-		 * violate the mempool principle.
-		 */
-		gfp_mask &= ~__GFP_WAIT;
-		gfp_mask |= __GFP_HIGH;
-		prev = sgl;
-	} while (left);
-
-	/*
-	 * ->use_sg may get modified after dma mapping has potentially
-	 * shrunk the number of segments, so keep a copy of it for free.
-	 */
-	cmd->__use_sg = cmd->use_sg;
+	cmd->request_buffer = cmd->sg_table.sgl;
 	return ret;
-enomem:
-	if (ret) {
-		/*
-		 * Free entries chained off ret. Since we were trying to
-		 * allocate another sglist, we know that all entries are of
-		 * the max size.
-		 */
-		sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
-		prev = ret;
-		ret = &ret[SCSI_MAX_SG_SEGMENTS - 1];
-
-		while ((sgl = sg_chain_ptr(ret)) != NULL) {
-			ret = &sgl[SCSI_MAX_SG_SEGMENTS - 1];
-			mempool_free(sgl, sgp->pool);
-		}
-
-		mempool_free(prev, sgp->pool);
-	}
-	return NULL;
 }
 
 EXPORT_SYMBOL(scsi_alloc_sgtable);
 
 void scsi_free_sgtable(struct scsi_cmnd *cmd)
 {
-	struct scatterlist *sgl = cmd->request_buffer;
-	struct scsi_host_sg_pool *sgp;
-
-	/*
-	 * if this is the biggest size sglist, check if we have
-	 * chained parts we need to free
-	 */
-	if (cmd->__use_sg > SCSI_MAX_SG_SEGMENTS) {
-		unsigned short this, left;
-		struct scatterlist *next;
-		unsigned int index;
-
-		left = cmd->__use_sg - (SCSI_MAX_SG_SEGMENTS - 1);
-		next = sg_chain_ptr(&sgl[SCSI_MAX_SG_SEGMENTS - 1]);
-		while (left && next) {
-			sgl = next;
-			this = left;
-			if (this > SCSI_MAX_SG_SEGMENTS) {
-				this = SCSI_MAX_SG_SEGMENTS - 1;
-				index = SG_MEMPOOL_NR - 1;
-			} else
-				index = scsi_sgtable_index(this);
-
-			left -= this;
-
-			sgp = scsi_sg_pools + index;
-
-			if (left)
-				next = sg_chain_ptr(&sgl[sgp->size - 1]);
-
-			mempool_free(sgl, sgp->pool);
-		}
-
-		/*
-		 * Restore original, will be freed below
-		 */
-		sgl = cmd->request_buffer;
-		sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
-	} else
-		sgp = scsi_sg_pools + scsi_sgtable_index(cmd->__use_sg);
-
-	mempool_free(sgl, sgp->pool);
+	__sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free);
 }
 
 EXPORT_SYMBOL(scsi_free_sgtable);
@@ -987,7 +883,7 @@
 	 * are leftovers and there is some kind of error
 	 * (result != 0), retry the rest.
 	 */
-	if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL)
+	if (scsi_end_request(cmd, 0, good_bytes, result == 0) == NULL)
 		return;
 
 	/* good_bytes = 0, or (inclusive) there were leftovers and
@@ -1001,7 +897,7 @@
 				 * and quietly refuse further access.
 				 */
 				cmd->device->changed = 1;
-				scsi_end_request(cmd, 0, this_count, 1);
+				scsi_end_request(cmd, -EIO, this_count, 1);
 				return;
 			} else {
 				/* Must have been a power glitch, or a
@@ -1033,7 +929,7 @@
 				scsi_requeue_command(q, cmd);
 				return;
 			} else {
-				scsi_end_request(cmd, 0, this_count, 1);
+				scsi_end_request(cmd, -EIO, this_count, 1);
 				return;
 			}
 			break;
@@ -1061,7 +957,7 @@
 							 "Device not ready",
 							 &sshdr);
 
-			scsi_end_request(cmd, 0, this_count, 1);
+			scsi_end_request(cmd, -EIO, this_count, 1);
 			return;
 		case VOLUME_OVERFLOW:
 			if (!(req->cmd_flags & REQ_QUIET)) {
@@ -1071,7 +967,7 @@
 				scsi_print_sense("", cmd);
 			}
 			/* See SSC3rXX or current. */
-			scsi_end_request(cmd, 0, this_count, 1);
+			scsi_end_request(cmd, -EIO, this_count, 1);
 			return;
 		default:
 			break;
@@ -1092,7 +988,7 @@
 				scsi_print_sense("", cmd);
 		}
 	}
-	scsi_end_request(cmd, 0, this_count, !result);
+	scsi_end_request(cmd, -EIO, this_count, !result);
 }
 
 /*
@@ -1120,8 +1016,7 @@
 	/*
 	 * If sg table allocation fails, requeue request later.
 	 */
-	cmd->request_buffer = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
-	if (unlikely(!cmd->request_buffer)) {
+	if (unlikely(scsi_alloc_sgtable(cmd, GFP_ATOMIC))) {
 		scsi_unprep_request(req);
 		return BLKPREP_DEFER;
 	}
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 93ece8f..01e03f3 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -359,8 +359,7 @@
 	int count;
 
 	cmd->use_sg = rq->nr_phys_segments;
-	cmd->request_buffer = scsi_alloc_sgtable(cmd, gfp_mask);
-	if (!cmd->request_buffer)
+	if (scsi_alloc_sgtable(cmd, gfp_mask))
 		return -ENOMEM;
 
 	cmd->request_bufflen = rq->data_len;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 17216b7..aba28f3 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -48,6 +48,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/scatterlist.h>
+#include <linux/blktrace_api.h>
 
 #include "scsi.h"
 #include <scsi/scsi_dbg.h>
@@ -1067,6 +1068,17 @@
 	case BLKSECTGET:
 		return put_user(sdp->device->request_queue->max_sectors * 512,
 				ip);
+	case BLKTRACESETUP:
+		return blk_trace_setup(sdp->device->request_queue,
+				       sdp->disk->disk_name,
+				       sdp->device->sdev_gendev.devt,
+				       (char *)arg);
+	case BLKTRACESTART:
+		return blk_trace_startstop(sdp->device->request_queue, 1);
+	case BLKTRACESTOP:
+		return blk_trace_startstop(sdp->device->request_queue, 0);
+	case BLKTRACETEARDOWN:
+		return blk_trace_remove(sdp->device->request_queue);
 	default:
 		if (read_only)
 			return -EPERM;	/* don't know so take safe approach */
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index facb678..6a48dfa 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -277,6 +277,8 @@
 	if (termios->c_iflag & INPCK)
 		port->read_status_mask |= RXSTAT_FRAME | RXSTAT_PARITY;
 
+	tty_encode_baud_rate(tty,  baud, baud);
+
 	/*
 	 * Which character status flags should we ignore?
 	 */
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index abf0504..aaaea81 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -153,6 +153,7 @@
 config SPI_PXA2XX
 	tristate "PXA2xx SSP SPI master"
 	depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
+	select PXA_SSP
 	help
 	  This enables using a PXA2xx SSP port as a SPI master controller.
 	  The driver can be configured to use any SSP port and additional
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 1c2ab54..eb817b8 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -27,6 +27,7 @@
 #include <linux/spi/spi.h>
 #include <linux/workqueue.h>
 #include <linux/delay.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -36,6 +37,8 @@
 
 #include <asm/arch/hardware.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/regs-ssp.h>
+#include <asm/arch/ssp.h>
 #include <asm/arch/pxa2xx_spi.h>
 
 MODULE_AUTHOR("Stephen Street");
@@ -80,6 +83,9 @@
 	/* Driver model hookup */
 	struct platform_device *pdev;
 
+	/* SSP Info */
+	struct ssp_device *ssp;
+
 	/* SPI framework hookup */
 	enum pxa_ssp_type ssp_type;
 	struct spi_master *master;
@@ -778,6 +784,16 @@
 	return retval;
 }
 
+static unsigned int ssp_get_clk_div(struct ssp_device *ssp, int rate)
+{
+	unsigned long ssp_clk = clk_get_rate(ssp->clk);
+
+	if (ssp->type == PXA25x_SSP)
+		return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8;
+	else
+		return ((ssp_clk / rate - 1) & 0xfff) << 8;
+}
+
 static void pump_transfers(unsigned long data)
 {
 	struct driver_data *drv_data = (struct driver_data *)data;
@@ -785,6 +801,7 @@
 	struct spi_transfer *transfer = NULL;
 	struct spi_transfer *previous = NULL;
 	struct chip_data *chip = NULL;
+	struct ssp_device *ssp = drv_data->ssp;
 	void *reg = drv_data->ioaddr;
 	u32 clk_div = 0;
 	u8 bits = 0;
@@ -866,12 +883,7 @@
 		if (transfer->bits_per_word)
 			bits = transfer->bits_per_word;
 
-		if (reg == SSP1_VIRT)
-			clk_div = SSP1_SerClkDiv(speed);
-		else if (reg == SSP2_VIRT)
-			clk_div = SSP2_SerClkDiv(speed);
-		else if (reg == SSP3_VIRT)
-			clk_div = SSP3_SerClkDiv(speed);
+		clk_div = ssp_get_clk_div(ssp, speed);
 
 		if (bits <= 8) {
 			drv_data->n_bytes = 1;
@@ -1074,6 +1086,7 @@
 	struct pxa2xx_spi_chip *chip_info = NULL;
 	struct chip_data *chip;
 	struct driver_data *drv_data = spi_master_get_devdata(spi->master);
+	struct ssp_device *ssp = drv_data->ssp;
 	unsigned int clk_div;
 
 	if (!spi->bits_per_word)
@@ -1157,18 +1170,7 @@
 		}
 	}
 
-	if (drv_data->ioaddr == SSP1_VIRT)
-		clk_div = SSP1_SerClkDiv(spi->max_speed_hz);
-	else if (drv_data->ioaddr == SSP2_VIRT)
-		clk_div = SSP2_SerClkDiv(spi->max_speed_hz);
-	else if (drv_data->ioaddr == SSP3_VIRT)
-		clk_div = SSP3_SerClkDiv(spi->max_speed_hz);
-	else
-	{
-		dev_err(&spi->dev, "failed setup: unknown IO address=0x%p\n",
-			drv_data->ioaddr);
-		return -ENODEV;
-	}
+	clk_div = ssp_get_clk_div(ssp, spi->max_speed_hz);
 	chip->speed_hz = spi->max_speed_hz;
 
 	chip->cr0 = clk_div
@@ -1183,15 +1185,15 @@
 
 	/* NOTE:  PXA25x_SSP _could_ use external clocking ... */
 	if (drv_data->ssp_type != PXA25x_SSP)
-		dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n",
+		dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
 				spi->bits_per_word,
-				(CLOCK_SPEED_HZ)
+				clk_get_rate(ssp->clk)
 					/ (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
 				spi->mode & 0x3);
 	else
-		dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n",
+		dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
 				spi->bits_per_word,
-				(CLOCK_SPEED_HZ/2)
+				clk_get_rate(ssp->clk)
 					/ (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
 				spi->mode & 0x3);
 
@@ -1323,14 +1325,14 @@
 	struct pxa2xx_spi_master *platform_info;
 	struct spi_master *master;
 	struct driver_data *drv_data = 0;
-	struct resource *memory_resource;
-	int irq;
+	struct ssp_device *ssp;
 	int status = 0;
 
 	platform_info = dev->platform_data;
 
-	if (platform_info->ssp_type == SSP_UNDEFINED) {
-		dev_err(&pdev->dev, "undefined SSP\n");
+	ssp = ssp_request(pdev->id, pdev->name);
+	if (ssp == NULL) {
+		dev_err(&pdev->dev, "failed to request SSP%d\n", pdev->id);
 		return -ENODEV;
 	}
 
@@ -1338,12 +1340,14 @@
 	master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
 	if (!master) {
 		dev_err(&pdev->dev, "can not alloc spi_master\n");
+		ssp_free(ssp);
 		return -ENOMEM;
 	}
 	drv_data = spi_master_get_devdata(master);
 	drv_data->master = master;
 	drv_data->master_info = platform_info;
 	drv_data->pdev = pdev;
+	drv_data->ssp = ssp;
 
 	master->bus_num = pdev->id;
 	master->num_chipselect = platform_info->num_chipselect;
@@ -1351,21 +1355,13 @@
 	master->setup = setup;
 	master->transfer = transfer;
 
-	drv_data->ssp_type = platform_info->ssp_type;
+	drv_data->ssp_type = ssp->type;
 	drv_data->null_dma_buf = (u32 *)ALIGN((u32)(drv_data +
 						sizeof(struct driver_data)), 8);
 
-	/* Setup register addresses */
-	memory_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!memory_resource) {
-		dev_err(&pdev->dev, "memory resources not defined\n");
-		status = -ENODEV;
-		goto out_error_master_alloc;
-	}
-
-	drv_data->ioaddr = (void *)io_p2v((unsigned long)(memory_resource->start));
-	drv_data->ssdr_physical = memory_resource->start + 0x00000010;
-	if (platform_info->ssp_type == PXA25x_SSP) {
+	drv_data->ioaddr = ssp->mmio_base;
+	drv_data->ssdr_physical = ssp->phys_base + SSDR;
+	if (ssp->type == PXA25x_SSP) {
 		drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
 		drv_data->dma_cr1 = 0;
 		drv_data->clear_sr = SSSR_ROR;
@@ -1377,15 +1373,7 @@
 		drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR;
 	}
 
-	/* Attach to IRQ */
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "irq resource not defined\n");
-		status = -ENODEV;
-		goto out_error_master_alloc;
-	}
-
-	status = request_irq(irq, ssp_int, 0, dev->bus_id, drv_data);
+	status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data);
 	if (status < 0) {
 		dev_err(&pdev->dev, "can not get IRQ\n");
 		goto out_error_master_alloc;
@@ -1418,29 +1406,12 @@
 			goto out_error_dma_alloc;
 		}
 
-		if (drv_data->ioaddr == SSP1_VIRT) {
-				DRCMRRXSSDR = DRCMR_MAPVLD
-						| drv_data->rx_channel;
-				DRCMRTXSSDR = DRCMR_MAPVLD
-						| drv_data->tx_channel;
-		} else if (drv_data->ioaddr == SSP2_VIRT) {
-				DRCMRRXSS2DR = DRCMR_MAPVLD
-						| drv_data->rx_channel;
-				DRCMRTXSS2DR = DRCMR_MAPVLD
-						| drv_data->tx_channel;
-		} else if (drv_data->ioaddr == SSP3_VIRT) {
-				DRCMRRXSS3DR = DRCMR_MAPVLD
-						| drv_data->rx_channel;
-				DRCMRTXSS3DR = DRCMR_MAPVLD
-						| drv_data->tx_channel;
-		} else {
-			dev_err(dev, "bad SSP type\n");
-			goto out_error_dma_alloc;
-		}
+		DRCMR(ssp->drcmr_rx) = DRCMR_MAPVLD | drv_data->rx_channel;
+		DRCMR(ssp->drcmr_tx) = DRCMR_MAPVLD | drv_data->tx_channel;
 	}
 
 	/* Enable SOC clock */
-	pxa_set_cken(platform_info->clock_enable, 1);
+	clk_enable(ssp->clk);
 
 	/* Load default SSP configuration */
 	write_SSCR0(0, drv_data->ioaddr);
@@ -1479,7 +1450,7 @@
 	destroy_queue(drv_data);
 
 out_error_clock_enabled:
-	pxa_set_cken(platform_info->clock_enable, 0);
+	clk_disable(ssp->clk);
 
 out_error_dma_alloc:
 	if (drv_data->tx_channel != -1)
@@ -1488,17 +1459,18 @@
 		pxa_free_dma(drv_data->rx_channel);
 
 out_error_irq_alloc:
-	free_irq(irq, drv_data);
+	free_irq(ssp->irq, drv_data);
 
 out_error_master_alloc:
 	spi_master_put(master);
+	ssp_free(ssp);
 	return status;
 }
 
 static int pxa2xx_spi_remove(struct platform_device *pdev)
 {
 	struct driver_data *drv_data = platform_get_drvdata(pdev);
-	int irq;
+	struct ssp_device *ssp = drv_data->ssp;
 	int status = 0;
 
 	if (!drv_data)
@@ -1520,28 +1492,21 @@
 
 	/* Disable the SSP at the peripheral and SOC level */
 	write_SSCR0(0, drv_data->ioaddr);
-	pxa_set_cken(drv_data->master_info->clock_enable, 0);
+	clk_disable(ssp->clk);
 
 	/* Release DMA */
 	if (drv_data->master_info->enable_dma) {
-		if (drv_data->ioaddr == SSP1_VIRT) {
-			DRCMRRXSSDR = 0;
-			DRCMRTXSSDR = 0;
-		} else if (drv_data->ioaddr == SSP2_VIRT) {
-			DRCMRRXSS2DR = 0;
-			DRCMRTXSS2DR = 0;
-		} else if (drv_data->ioaddr == SSP3_VIRT) {
-			DRCMRRXSS3DR = 0;
-			DRCMRTXSS3DR = 0;
-		}
+		DRCMR(ssp->drcmr_rx) = 0;
+		DRCMR(ssp->drcmr_tx) = 0;
 		pxa_free_dma(drv_data->tx_channel);
 		pxa_free_dma(drv_data->rx_channel);
 	}
 
 	/* Release IRQ */
-	irq = platform_get_irq(pdev, 0);
-	if (irq >= 0)
-		free_irq(irq, drv_data);
+	free_irq(ssp->irq, drv_data);
+
+	/* Release SSP */
+	ssp_free(ssp);
 
 	/* Disconnect from the SPI framework */
 	spi_unregister_master(drv_data->master);
@@ -1576,6 +1541,7 @@
 static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct driver_data *drv_data = platform_get_drvdata(pdev);
+	struct ssp_device *ssp = drv_data->ssp;
 	int status = 0;
 
 	/* Check all childern for current power state */
@@ -1588,7 +1554,7 @@
 	if (status != 0)
 		return status;
 	write_SSCR0(0, drv_data->ioaddr);
-	pxa_set_cken(drv_data->master_info->clock_enable, 0);
+	clk_disable(ssp->clk);
 
 	return 0;
 }
@@ -1596,10 +1562,11 @@
 static int pxa2xx_spi_resume(struct platform_device *pdev)
 {
 	struct driver_data *drv_data = platform_get_drvdata(pdev);
+	struct ssp_device *ssp = drv_data->ssp;
 	int status = 0;
 
 	/* Enable the SSP clock */
-	pxa_set_cken(drv_data->master_info->clock_enable, 1);
+	clk_disable(ssp->clk);
 
 	/* Start the queue running */
 	status = start_queue(drv_data);
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 7580aa5d..7a64990 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -33,6 +33,7 @@
 	default y if ARCH_LH7A404
 	default y if ARCH_S3C2410
 	default y if PXA27x
+	default y if PXA3xx
 	default y if ARCH_EP93XX
 	default y if ARCH_AT91
 	default y if ARCH_PNX4008
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index f81d08d..77a3759 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -308,7 +308,7 @@
 
 config USB_GADGET_AT91
 	boolean "AT91 USB Device Port"
-	depends on ARCH_AT91 && !ARCH_AT91SAM9RL
+	depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9
 	select USB_GADGET_SELECTED
 	help
 	   Many Atmel AT91 processors (such as the AT91RM2000) have a
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index ecfe800..ddd4ee1 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -997,7 +997,7 @@
 #define PLATFORM_DRIVER		ohci_hcd_lh7a404_driver
 #endif
 
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
 #endif
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 23d2fe5..ff9a798 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -22,6 +22,7 @@
 #include <linux/device.h>
 #include <linux/signal.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
@@ -32,6 +33,8 @@
 
 #define UHCRHPS(x)              __REG2( 0x4C000050, (x)<<2 )
 
+static struct clk *usb_clk;
+
 /*
   PMM_NPS_MODE -- PMM Non-power switching mode
       Ports are powered continuously.
@@ -80,7 +83,7 @@
 
 	inf = dev->platform_data;
 
-	pxa_set_cken(CKEN_USBHOST, 1);
+	clk_enable(usb_clk);
 
 	UHCHR |= UHCHR_FHR;
 	udelay(11);
@@ -123,7 +126,7 @@
 	UHCCOMS |= 1;
 	udelay(10);
 
-	pxa_set_cken(CKEN_USBHOST, 0);
+	clk_disable(usb_clk);
 }
 
 
@@ -158,6 +161,10 @@
 		return -ENOMEM;
 	}
 
+	usb_clk = clk_get(&pdev->dev, "USBCLK");
+	if (IS_ERR(usb_clk))
+		return PTR_ERR(usb_clk);
+
 	hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
 	if (!hcd)
 		return -ENOMEM;
@@ -201,6 +208,7 @@
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  err1:
 	usb_put_hcd(hcd);
+	clk_put(usb_clk);
 	return retval;
 }
 
@@ -225,6 +233,7 @@
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
+	clk_put(usb_clk);
 }
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 5b3dbcf..758435f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -889,7 +889,7 @@
 
 config FB_ATMEL
 	tristate "AT91/AT32 LCD Controller support"
-	depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || AVR32)
+	depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 7c30cc8..f8e7111 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -30,7 +30,7 @@
 #define ATMEL_LCDC_CVAL_DEFAULT		0xc8
 #define ATMEL_LCDC_DMA_BURST_LEN	8
 
-#if defined(CONFIG_ARCH_AT91SAM9263)
+#if defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9)
 #define ATMEL_LCDC_FIFO_SIZE		2048
 #else
 #define ATMEL_LCDC_FIFO_SIZE		512
diff --git a/fs/bio.c b/fs/bio.c
index d59ddbf..242e409 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -248,11 +248,13 @@
  */
 void __bio_clone(struct bio *bio, struct bio *bio_src)
 {
-	struct request_queue *q = bdev_get_queue(bio_src->bi_bdev);
-
 	memcpy(bio->bi_io_vec, bio_src->bi_io_vec,
 		bio_src->bi_max_vecs * sizeof(struct bio_vec));
 
+	/*
+	 * most users will be overriding ->bi_bdev with a new target,
+	 * so we don't set nor calculate new physical/hw segment counts here
+	 */
 	bio->bi_sector = bio_src->bi_sector;
 	bio->bi_bdev = bio_src->bi_bdev;
 	bio->bi_flags |= 1 << BIO_CLONED;
@@ -260,8 +262,6 @@
 	bio->bi_vcnt = bio_src->bi_vcnt;
 	bio->bi_size = bio_src->bi_size;
 	bio->bi_idx = bio_src->bi_idx;
-	bio_phys_segments(q, bio);
-	bio_hw_segments(q, bio);
 }
 
 /**
diff --git a/fs/ioprio.c b/fs/ioprio.c
index e4e01bc..c4a1c3c 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -41,18 +41,28 @@
 		return err;
 
 	task_lock(task);
+	do {
+		ioc = task->io_context;
+		/* see wmb() in current_io_context() */
+		smp_read_barrier_depends();
+		if (ioc)
+			break;
 
-	task->ioprio = ioprio;
+		ioc = alloc_io_context(GFP_ATOMIC, -1);
+		if (!ioc) {
+			err = -ENOMEM;
+			break;
+		}
+		task->io_context = ioc;
+	} while (1);
 
-	ioc = task->io_context;
-	/* see wmb() in current_io_context() */
-	smp_read_barrier_depends();
-
-	if (ioc)
+	if (!err) {
+		ioc->ioprio = ioprio;
 		ioc->ioprio_changed = 1;
+	}
 
 	task_unlock(task);
-	return 0;
+	return err;
 }
 
 asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
@@ -75,8 +85,6 @@
 
 			break;
 		case IOPRIO_CLASS_IDLE:
-			if (!capable(CAP_SYS_ADMIN))
-				return -EPERM;
 			break;
 		case IOPRIO_CLASS_NONE:
 			if (data)
@@ -148,7 +156,9 @@
 	ret = security_task_getioprio(p);
 	if (ret)
 		goto out;
-	ret = p->ioprio;
+	ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM);
+	if (p->io_context)
+		ret = p->io_context->ioprio;
 out:
 	return ret;
 }
diff --git a/include/asm-arm/arch-at91/at91_lcdc.h b/include/asm-arm/arch-at91/at91_lcdc.h
deleted file mode 100644
index ab040a4..0000000
--- a/include/asm-arm/arch-at91/at91_lcdc.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * include/asm-arm/arch-at91/at91_lcdc.h
- *
- * LCD Controller (LCDC).
- * Based on AT91SAM9261 datasheet revision E.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef AT91_LCDC_H
-#define AT91_LCDC_H
-
-#define AT91_LCDC_DMABADDR1	0x00		/* DMA Base Address Register 1 */
-#define AT91_LCDC_DMABADDR2	0x04		/* DMA Base Address Register 2 */
-#define AT91_LCDC_DMAFRMPT1	0x08		/* DMA Frame Pointer Register 1 */
-#define AT91_LCDC_DMAFRMPT2	0x0c		/* DMA Frame Pointer Register 2 */
-#define AT91_LCDC_DMAFRMADD1	0x10		/* DMA Frame Address Register 1 */
-#define AT91_LCDC_DMAFRMADD2	0x14		/* DMA Frame Address Register 2 */
-
-#define AT91_LCDC_DMAFRMCFG	0x18		/* DMA Frame Configuration Register */
-#define		AT91_LCDC_FRSIZE	(0x7fffff <<  0)	/* Frame Size */
-#define		AT91_LCDC_BLENGTH	(0x7f     << 24)	/* Burst Length */
-
-#define AT91_LCDC_DMACON	0x1c		/* DMA Control Register */
-#define		AT91_LCDC_DMAEN		(0x1 << 0)	/* DMA Enable */
-#define		AT91_LCDC_DMARST	(0x1 << 1)	/* DMA Reset */
-#define		AT91_LCDC_DMABUSY	(0x1 << 2)	/* DMA Busy */
-
-#define AT91_LCDC_LCDCON1	0x0800		/* LCD Control Register 1 */
-#define		AT91_LCDC_BYPASS	(1     <<  0)	/* Bypass lcd_dotck divider */
-#define		AT91_LCDC_CLKVAL	(0x1ff << 12)	/* Clock Divider */
-#define		AT91_LCDC_LINCNT	(0x7ff << 21)	/* Line Counter */
-
-#define AT91_LCDC_LCDCON2	0x0804		/* LCD Control Register 2 */
-#define		AT91_LCDC_DISTYPE	(3 << 0)	/* Display Type */
-#define			AT91_LCDC_DISTYPE_STNMONO	(0 << 0)
-#define			AT91_LCDC_DISTYPE_STNCOLOR	(1 << 0)
-#define			AT91_LCDC_DISTYPE_TFT		(2 << 0)
-#define		AT91_LCDC_SCANMOD	(1 << 2)	/* Scan Mode */
-#define			AT91_LCDC_SCANMOD_SINGLE	(0 << 2)
-#define			AT91_LCDC_SCANMOD_DUAL		(1 << 2)
-#define		AT91_LCDC_IFWIDTH	(3 << 3)	/*Interface Width */
-#define			AT91_LCDC_IFWIDTH_4		(0 << 3)
-#define			AT91_LCDC_IFWIDTH_8		(1 << 3)
-#define			AT91_LCDC_IFWIDTH_16		(2 << 3)
-#define		AT91_LCDC_PIXELSIZE	(7 << 5)	/* Bits per pixel */
-#define			AT91_LCDC_PIXELSIZE_1		(0 << 5)
-#define			AT91_LCDC_PIXELSIZE_2		(1 << 5)
-#define			AT91_LCDC_PIXELSIZE_4		(2 << 5)
-#define			AT91_LCDC_PIXELSIZE_8		(3 << 5)
-#define			AT91_LCDC_PIXELSIZE_16		(4 << 5)
-#define			AT91_LCDC_PIXELSIZE_24		(5 << 5)
-#define		AT91_LCDC_INVVD		(1 << 8)	/* LCD Data polarity */
-#define			AT91_LCDC_INVVD_NORMAL		(0 << 8)
-#define			AT91_LCDC_INVVD_INVERTED	(1 << 8)
-#define		AT91_LCDC_INVFRAME	(1 << 9 )	/* LCD VSync polarity */
-#define			AT91_LCDC_INVFRAME_NORMAL	(0 << 9)
-#define			AT91_LCDC_INVFRAME_INVERTED	(1 << 9)
-#define		AT91_LCDC_INVLINE	(1 << 10)	/* LCD HSync polarity */
-#define			AT91_LCDC_INVLINE_NORMAL	(0 << 10)
-#define			AT91_LCDC_INVLINE_INVERTED	(1 << 10)
-#define		AT91_LCDC_INVCLK	(1 << 11)	/* LCD dotclk polarity */
-#define			AT91_LCDC_INVCLK_NORMAL		(0 << 11)
-#define			AT91_LCDC_INVCLK_INVERTED	(1 << 11)
-#define		AT91_LCDC_INVDVAL	(1 << 12)	/* LCD dval polarity */
-#define			AT91_LCDC_INVDVAL_NORMAL	(0 << 12)
-#define			AT91_LCDC_INVDVAL_INVERTED	(1 << 12)
-#define		AT91_LCDC_CLKMOD	(1 << 15)	/* LCD dotclk mode */
-#define			AT91_LCDC_CLKMOD_ACTIVEDISPLAY	(0 << 15)
-#define			AT91_LCDC_CLKMOD_ALWAYSACTIVE	(1 << 15)
-#define		AT91_LCDC_MEMOR		(1 << 31)	/* Memory Ordering Format */
-#define			AT91_LCDC_MEMOR_BIG		(0 << 31)
-#define			AT91_LCDC_MEMOR_LITTLE		(1 << 31)
-
-#define AT91_LCDC_TIM1		0x0808		/* LCD Timing Register 1 */
-#define		AT91_LCDC_VFP		(0xff <<  0)	/* Vertical Front Porch */
-#define		AT91_LCDC_VBP		(0xff <<  8)	/* Vertical Back Porch */
-#define		AT91_LCDC_VPW		(0x3f << 16)	/* Vertical Synchronization Pulse Width */
-#define		AT91_LCDC_VHDLY		(0xf  << 24)	/* Vertical to Horizontal Delay */
-
-#define AT91_LCDC_TIM2		0x080c		/* LCD Timing Register 2 */
-#define		AT91_LCDC_HBP		(0xff  <<  0)	/* Horizontal Back Porch */
-#define		AT91_LCDC_HPW		(0x3f  <<  8)	/* Horizontal Synchronization Pulse Width */
-#define		AT91_LCDC_HFP		(0x7ff << 21)	/* Horizontal Front Porch */
-
-#define AT91_LCDC_LCDFRMCFG	0x0810		/* LCD Frame Configuration Register */
-#define		AT91_LCDC_LINEVAL	(0x7ff <<  0)	/* Vertical Size of LCD Module */
-#define		AT91_LCDC_HOZVAL	(0x7ff << 21)	/* Horizontal Size of LCD Module */
-
-#define AT91_LCDC_FIFO		0x0814		/* LCD FIFO Register */
-#define		AT91_LCDC_FIFOTH	(0xffff)	/* FIFO Threshold */
-
-#define AT91_LCDC_DP1_2		0x081c		/* Dithering Pattern DP1_2 Register */
-#define AT91_LCDC_DP4_7		0x0820		/* Dithering Pattern DP4_7 Register */
-#define AT91_LCDC_DP3_5		0x0824		/* Dithering Pattern DP3_5 Register */
-#define AT91_LCDC_DP2_3		0x0828		/* Dithering Pattern DP2_3 Register */
-#define AT91_LCDC_DP5_7		0x082c		/* Dithering Pattern DP5_7 Register */
-#define AT91_LCDC_DP3_4		0x0830		/* Dithering Pattern DP3_4 Register */
-#define AT91_LCDC_DP4_5		0x0834		/* Dithering Pattern DP4_5 Register */
-#define AT91_LCDC_DP6_7		0x0838		/* Dithering Pattern DP6_7 Register */
-#define		AT91_LCDC_DP1_2_VAL	(0xff)
-#define		AT91_LCDC_DP4_7_VAL	(0xfffffff)
-#define		AT91_LCDC_DP3_5_VAL	(0xfffff)
-#define		AT91_LCDC_DP2_3_VAL	(0xfff)
-#define		AT91_LCDC_DP5_7_VAL	(0xfffffff)
-#define		AT91_LCDC_DP3_4_VAL	(0xffff)
-#define		AT91_LCDC_DP4_5_VAL	(0xfffff)
-#define		AT91_LCDC_DP6_7_VAL	(0xfffffff)
-
-#define AT91_LCDC_PWRCON	0x083c		/* Power Control Register */
-#define		AT91_LCDC_PWR		(1    <<  0)	/* LCD Module Power Control */
-#define		AT91_LCDC_GUARDT	(0x7f <<  1)	/* Delay in Frame Period */
-#define		AT91_LCDC_BUSY		(1    << 31)	/* LCD Busy */
-
-#define AT91_LCDC_CONTRAST_CTR	0x0840		/* Contrast Control Register */
-#define		AT91_LCDC_PS		(3 << 0)	/* Contrast Counter Prescaler */
-#define			AT91_LCDC_PS_DIV1		(0 << 0)
-#define			AT91_LCDC_PS_DIV2		(1 << 0)
-#define			AT91_LCDC_PS_DIV4		(2 << 0)
-#define			AT91_LCDC_PS_DIV8		(3 << 0)
-#define		AT91_LCDC_POL		(1 << 2)	/* Polarity of output Pulse */
-#define			AT91_LCDC_POL_NEGATIVE		(0 << 2)
-#define			AT91_LCDC_POL_POSITIVE		(1 << 2)
-#define		AT91_LCDC_ENA		(1 << 3)	/* PWM generator Control */
-#define			AT91_LCDC_ENA_PWMDISABLE	(0 << 3)
-#define			AT91_LCDC_ENA_PWMENABLE		(1 << 3)
-
-#define AT91_LCDC_CONTRAST_VAL	0x0844		/* Contrast Value Register */
-#define		AT91_LCDC_CVAL		(0xff)		/* PWM compare value */
-
-#define AT91_LCDC_IER		0x0848		/* Interrupt Enable Register */
-#define AT91_LCDC_IDR		0x084c		/* Interrupt Disable Register */
-#define AT91_LCDC_IMR		0x0850		/* Interrupt Mask Register */
-#define AT91_LCDC_ISR		0x0854		/* Interrupt Enable Register */
-#define AT91_LCDC_ICR		0x0858		/* Interrupt Clear Register */
-#define		AT91_LCDC_LNI		(1 << 0)	/* Line Interrupt */
-#define		AT91_LCDC_LSTLNI	(1 << 1)	/* Last Line Interrupt */
-#define		AT91_LCDC_EOFI		(1 << 2)	/* DMA End Of Frame Interrupt */
-#define		AT91_LCDC_UFLWI		(1 << 4)	/* FIFO Underflow Interrupt */
-#define		AT91_LCDC_OWRI		(1 << 5)	/* FIFO Overwrite Interrupt */
-#define		AT91_LCDC_MERI		(1 << 6)	/* DMA Memory Error Interrupt */
-
-#define AT91_LCDC_LUT_(n)	(0x0c00 + ((n)*4))	/* Palette Entry 0..255 */
-
-#endif
diff --git a/include/asm-arm/arch-at91/at91_pmc.h b/include/asm-arm/arch-at91/at91_pmc.h
index 33ff5b6..52cd8e5 100644
--- a/include/asm-arm/arch-at91/at91_pmc.h
+++ b/include/asm-arm/arch-at91/at91_pmc.h
@@ -25,6 +25,7 @@
 #define		AT91RM9200_PMC_MCKUDP	(1 <<  2)		/* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
 #define		AT91RM9200_PMC_UHP	(1 <<  4)		/* USB Host Port Clock [AT91RM9200 only] */
 #define		AT91SAM926x_PMC_UHP	(1 <<  6)		/* USB Host Port Clock [AT91SAM926x only] */
+#define		AT91CAP9_PMC_UHP	(1 <<  6)		/* USB Host Port Clock [AT91CAP9 only] */
 #define		AT91SAM926x_PMC_UDP	(1 <<  7)		/* USB Devcice Port Clock [AT91SAM926x only] */
 #define		AT91_PMC_PCK0		(1 <<  8)		/* Programmable Clock 0 */
 #define		AT91_PMC_PCK1		(1 <<  9)		/* Programmable Clock 1 */
@@ -37,7 +38,9 @@
 #define	AT91_PMC_PCDR		(AT91_PMC + 0x14)	/* Peripheral Clock Disable Register */
 #define	AT91_PMC_PCSR		(AT91_PMC + 0x18)	/* Peripheral Clock Status Register */
 
-#define	AT91_CKGR_MOR		(AT91_PMC + 0x20)	/* Main Oscillator Register */
+#define	AT91_CKGR_UCKR		(AT91_PMC + 0x1C)	/* UTMI Clock Register [SAM9RL, CAP9] */
+
+#define	AT91_CKGR_MOR		(AT91_PMC + 0x20)	/* Main Oscillator Register [not on SAM9RL] */
 #define		AT91_PMC_MOSCEN		(1    << 0)		/* Main Oscillator Enable */
 #define		AT91_PMC_OSCBYPASS	(1    << 1)		/* Oscillator Bypass [AT91SAM926x only] */
 #define		AT91_PMC_OSCOUNT	(0xff << 8)		/* Main Oscillator Start-up Time */
@@ -52,6 +55,10 @@
 #define		AT91_PMC_PLLCOUNT	(0x3f  <<  8)		/* PLL Counter */
 #define		AT91_PMC_OUT		(3     << 14)		/* PLL Clock Frequency Range */
 #define		AT91_PMC_MUL		(0x7ff << 16)		/* PLL Multiplier */
+#define		AT91_PMC_USBDIV		(3     << 28)		/* USB Divisor (PLLB only) */
+#define			AT91_PMC_USBDIV_1		(0 << 28)
+#define			AT91_PMC_USBDIV_2		(1 << 28)
+#define			AT91_PMC_USBDIV_4		(2 << 28)
 #define		AT91_PMC_USB96M		(1     << 28)		/* Divider by 2 Enable (PLLB only) */
 
 #define	AT91_PMC_MCKR		(AT91_PMC + 0x30)	/* Master Clock Register */
diff --git a/include/asm-arm/arch-at91/at91_rtt.h b/include/asm-arm/arch-at91/at91_rtt.h
index bae1103..39a3263 100644
--- a/include/asm-arm/arch-at91/at91_rtt.h
+++ b/include/asm-arm/arch-at91/at91_rtt.h
@@ -13,19 +13,19 @@
 #ifndef AT91_RTT_H
 #define AT91_RTT_H
 
-#define AT91_RTT_MR		(AT91_RTT + 0x00)	/* Real-time Mode Register */
+#define AT91_RTT_MR		0x00			/* Real-time Mode Register */
 #define		AT91_RTT_RTPRES		(0xffff << 0)		/* Real-time Timer Prescaler Value */
 #define		AT91_RTT_ALMIEN		(1 << 16)		/* Alarm Interrupt Enable */
 #define		AT91_RTT_RTTINCIEN	(1 << 17)		/* Real Time Timer Increment Interrupt Enable */
 #define		AT91_RTT_RTTRST		(1 << 18)		/* Real Time Timer Restart */
 
-#define AT91_RTT_AR		(AT91_RTT + 0x04)	/* Real-time Alarm Register */
+#define AT91_RTT_AR		0x04			/* Real-time Alarm Register */
 #define		AT91_RTT_ALMV		(0xffffffff)		/* Alarm Value */
 
-#define AT91_RTT_VR		(AT91_RTT + 0x08)	/* Real-time Value Register */
+#define AT91_RTT_VR		0x08			/* Real-time Value Register */
 #define		AT91_RTT_CRTV		(0xffffffff)		/* Current Real-time Value */
 
-#define AT91_RTT_SR		(AT91_RTT + 0x0c)	/* Real-time Status Register */
+#define AT91_RTT_SR		0x0c			/* Real-time Status Register */
 #define		AT91_RTT_ALMS		(1 << 0)		/* Real-time Alarm Status */
 #define		AT91_RTT_RTTINC		(1 << 1)		/* Real-time Timer Increment */
 
diff --git a/include/asm-arm/arch-at91/at91_twi.h b/include/asm-arm/arch-at91/at91_twi.h
index ca9a907..f9f2e3c 100644
--- a/include/asm-arm/arch-at91/at91_twi.h
+++ b/include/asm-arm/arch-at91/at91_twi.h
@@ -21,6 +21,8 @@
 #define		AT91_TWI_STOP		(1 <<  1)	/* Send a Stop Condition */
 #define		AT91_TWI_MSEN		(1 <<  2)	/* Master Transfer Enable */
 #define		AT91_TWI_MSDIS		(1 <<  3)	/* Master Transfer Disable */
+#define		AT91_TWI_SVEN		(1 <<  4)	/* Slave Transfer Enable [SAM9260 only] */
+#define		AT91_TWI_SVDIS		(1 <<  5)	/* Slave Transfer Disable [SAM9260 only] */
 #define		AT91_TWI_SWRST		(1 <<  7)	/* Software Reset */
 
 #define	AT91_TWI_MMR		0x04		/* Master Mode Register */
@@ -32,6 +34,9 @@
 #define		AT91_TWI_MREAD		(1    << 12)	/* Master Read Direction */
 #define		AT91_TWI_DADR		(0x7f << 16)	/* Device Address */
 
+#define	AT91_TWI_SMR		0x08		/* Slave Mode Register [SAM9260 only] */
+#define		AT91_TWI_SADR		(0x7f << 16)	/* Slave Address */
+
 #define	AT91_TWI_IADR		0x0c		/* Internal Address Register */
 
 #define	AT91_TWI_CWGR		0x10		/* Clock Waveform Generator Register */
@@ -43,9 +48,15 @@
 #define		AT91_TWI_TXCOMP		(1 <<  0)	/* Transmission Complete */
 #define		AT91_TWI_RXRDY		(1 <<  1)	/* Receive Holding Register Ready */
 #define		AT91_TWI_TXRDY		(1 <<  2)	/* Transmit Holding Register Ready */
+#define		AT91_TWI_SVREAD		(1 <<  3)	/* Slave Read [SAM9260 only] */
+#define		AT91_TWI_SVACC		(1 <<  4)	/* Slave Access [SAM9260 only] */
+#define		AT91_TWI_GACC		(1 <<  5)	/* General Call Access [SAM9260 only] */
 #define		AT91_TWI_OVRE		(1 <<  6)	/* Overrun Error [AT91RM9200 only] */
 #define		AT91_TWI_UNRE		(1 <<  7)	/* Underrun Error [AT91RM9200 only] */
 #define		AT91_TWI_NACK		(1 <<  8)	/* Not Acknowledged */
+#define		AT91_TWI_ARBLST		(1 <<  9)	/* Arbitration Lost [SAM9260 only] */
+#define		AT91_TWI_SCLWS		(1 << 10)	/* Clock Wait State [SAM9260 only] */
+#define		AT91_TWI_EOSACC		(1 << 11)	/* End of Slave Address [SAM9260 only] */
 
 #define	AT91_TWI_IER		0x24		/* Interrupt Enable Register */
 #define	AT91_TWI_IDR		0x28		/* Interrupt Disable Register */
diff --git a/include/asm-arm/arch-at91/at91cap9.h b/include/asm-arm/arch-at91/at91cap9.h
new file mode 100644
index 0000000..73e1fcf
--- /dev/null
+++ b/include/asm-arm/arch-at91/at91cap9.h
@@ -0,0 +1,121 @@
+/*
+ * include/asm-arm/arch-at91/at91cap9.h
+ *
+ *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ *  Copyright (C) 2007 Atmel Corporation.
+ *
+ * Common definitions.
+ * Based on AT91CAP9 datasheet revision B (Preliminary).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef AT91CAP9_H
+#define AT91CAP9_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS		1	/* System Peripherals */
+#define AT91CAP9_ID_PIOABCD	2	/* Parallel IO Controller A, B, C and D */
+#define AT91CAP9_ID_MPB0	3	/* MP Block Peripheral 0 */
+#define AT91CAP9_ID_MPB1	4	/* MP Block Peripheral 1 */
+#define AT91CAP9_ID_MPB2	5	/* MP Block Peripheral 2 */
+#define AT91CAP9_ID_MPB3	6	/* MP Block Peripheral 3 */
+#define AT91CAP9_ID_MPB4	7	/* MP Block Peripheral 4 */
+#define AT91CAP9_ID_US0		8	/* USART 0 */
+#define AT91CAP9_ID_US1		9	/* USART 1 */
+#define AT91CAP9_ID_US2		10	/* USART 2 */
+#define AT91CAP9_ID_MCI0	11	/* Multimedia Card Interface 0 */
+#define AT91CAP9_ID_MCI1	12	/* Multimedia Card Interface 1 */
+#define AT91CAP9_ID_CAN		13	/* CAN */
+#define AT91CAP9_ID_TWI		14	/* Two-Wire Interface */
+#define AT91CAP9_ID_SPI0	15	/* Serial Peripheral Interface 0 */
+#define AT91CAP9_ID_SPI1	16	/* Serial Peripheral Interface 0 */
+#define AT91CAP9_ID_SSC0	17	/* Serial Synchronous Controller 0 */
+#define AT91CAP9_ID_SSC1	18	/* Serial Synchronous Controller 1 */
+#define AT91CAP9_ID_AC97C	19	/* AC97 Controller */
+#define AT91CAP9_ID_TCB		20	/* Timer Counter 0, 1 and 2 */
+#define AT91CAP9_ID_PWMC	21	/* Pulse Width Modulation Controller */
+#define AT91CAP9_ID_EMAC	22	/* Ethernet */
+#define AT91CAP9_ID_AESTDES	23	/* Advanced Encryption Standard, Triple DES */
+#define AT91CAP9_ID_ADC		24	/* Analog-to-Digital Converter */
+#define AT91CAP9_ID_ISI		25	/* Image Sensor Interface */
+#define AT91CAP9_ID_LCDC	26	/* LCD Controller */
+#define AT91CAP9_ID_DMA		27	/* DMA Controller */
+#define AT91CAP9_ID_UDPHS	28	/* USB High Speed Device Port */
+#define AT91CAP9_ID_UHP		29	/* USB Host Port */
+#define AT91CAP9_ID_IRQ0	30	/* Advanced Interrupt Controller (IRQ0) */
+#define AT91CAP9_ID_IRQ1	31	/* Advanced Interrupt Controller (IRQ1) */
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91CAP9_BASE_UDPHS		0xfff78000
+#define AT91CAP9_BASE_TCB0		0xfff7c000
+#define AT91CAP9_BASE_TC0		0xfff7c000
+#define AT91CAP9_BASE_TC1		0xfff7c040
+#define AT91CAP9_BASE_TC2		0xfff7c080
+#define AT91CAP9_BASE_MCI0		0xfff80000
+#define AT91CAP9_BASE_MCI1		0xfff84000
+#define AT91CAP9_BASE_TWI		0xfff88000
+#define AT91CAP9_BASE_US0		0xfff8c000
+#define AT91CAP9_BASE_US1		0xfff90000
+#define AT91CAP9_BASE_US2		0xfff94000
+#define AT91CAP9_BASE_SSC0		0xfff98000
+#define AT91CAP9_BASE_SSC1		0xfff9c000
+#define AT91CAP9_BASE_AC97C		0xfffa0000
+#define AT91CAP9_BASE_SPI0		0xfffa4000
+#define AT91CAP9_BASE_SPI1		0xfffa8000
+#define AT91CAP9_BASE_CAN		0xfffac000
+#define AT91CAP9_BASE_PWMC		0xfffb8000
+#define AT91CAP9_BASE_EMAC		0xfffbc000
+#define AT91CAP9_BASE_ADC		0xfffc0000
+#define AT91CAP9_BASE_ISI		0xfffc4000
+#define AT91_BASE_SYS			0xffffe200
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_ECC	(0xffffe200 - AT91_BASE_SYS)
+#define AT91_BCRAMC	(0xffffe400 - AT91_BASE_SYS)
+#define AT91_DDRSDRC	(0xffffe600 - AT91_BASE_SYS)
+#define AT91_SMC	(0xffffe800 - AT91_BASE_SYS)
+#define AT91_MATRIX	(0xffffea00 - AT91_BASE_SYS)
+#define AT91_CCFG	(0xffffeb10 - AT91_BASE_SYS)
+#define AT91_DMA	(0xffffec00 - AT91_BASE_SYS)
+#define AT91_DBGU	(0xffffee00 - AT91_BASE_SYS)
+#define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
+#define AT91_PIOA	(0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOB	(0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOC	(0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOD	(0xfffff800 - AT91_BASE_SYS)
+#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDC	(0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT	(0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT	(0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT	(0xfffffd40 - AT91_BASE_SYS)
+#define AT91_GPBR	(0xfffffd50 - AT91_BASE_SYS)
+
+/*
+ * Internal Memory.
+ */
+#define AT91CAP9_SRAM_BASE	0x00100000	/* Internal SRAM base address */
+#define AT91CAP9_SRAM_SIZE	(32 * SZ_1K)	/* Internal SRAM size (32Kb) */
+
+#define AT91CAP9_ROM_BASE	0x00400000	/* Internal ROM base address */
+#define AT91CAP9_ROM_SIZE	(32 * SZ_1K)	/* Internal ROM size (32Kb) */
+
+#define AT91CAP9_LCDC_BASE	0x00500000	/* LCD Controller */
+#define AT91CAP9_UDPHS_BASE	0x00600000	/* USB High Speed Device Port */
+#define AT91CAP9_UHP_BASE	0x00700000	/* USB Host controller */
+
+#define CONFIG_DRAM_BASE	AT91_CHIPSELECT_6
+
+#endif
diff --git a/include/asm-arm/arch-at91/at91cap9_matrix.h b/include/asm-arm/arch-at91/at91cap9_matrix.h
new file mode 100644
index 0000000..a641686
--- /dev/null
+++ b/include/asm-arm/arch-at91/at91cap9_matrix.h
@@ -0,0 +1,132 @@
+/*
+ * include/asm-arm/arch-at91/at91cap9_matrix.h
+ *
+ *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ *  Copyright (C) 2006 Atmel Corporation.
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ * Based on AT91CAP9 datasheet revision B (Preliminary).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef AT91CAP9_MATRIX_H
+#define AT91CAP9_MATRIX_H
+
+#define AT91_MATRIX_MCFG0	(AT91_MATRIX + 0x00)	/* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1	(AT91_MATRIX + 0x04)	/* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2	(AT91_MATRIX + 0x08)	/* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3	(AT91_MATRIX + 0x0C)	/* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4	(AT91_MATRIX + 0x10)	/* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5	(AT91_MATRIX + 0x14)	/* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG6	(AT91_MATRIX + 0x18)	/* Master Configuration Register 6 */
+#define AT91_MATRIX_MCFG7	(AT91_MATRIX + 0x1C)	/* Master Configuration Register 7 */
+#define AT91_MATRIX_MCFG8	(AT91_MATRIX + 0x20)	/* Master Configuration Register 8 */
+#define AT91_MATRIX_MCFG9	(AT91_MATRIX + 0x24)	/* Master Configuration Register 9 */
+#define AT91_MATRIX_MCFG10	(AT91_MATRIX + 0x28)	/* Master Configuration Register 10 */
+#define AT91_MATRIX_MCFG11	(AT91_MATRIX + 0x2C)	/* Master Configuration Register 11 */
+#define		AT91_MATRIX_ULBT	(7 << 0)	/* Undefined Length Burst Type */
+#define			AT91_MATRIX_ULBT_INFINITE	(0 << 0)
+#define			AT91_MATRIX_ULBT_SINGLE		(1 << 0)
+#define			AT91_MATRIX_ULBT_FOUR		(2 << 0)
+#define			AT91_MATRIX_ULBT_EIGHT		(3 << 0)
+#define			AT91_MATRIX_ULBT_SIXTEEN	(4 << 0)
+
+#define AT91_MATRIX_SCFG0	(AT91_MATRIX + 0x40)	/* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1	(AT91_MATRIX + 0x44)	/* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2	(AT91_MATRIX + 0x48)	/* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3	(AT91_MATRIX + 0x4C)	/* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4	(AT91_MATRIX + 0x50)	/* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5	(AT91_MATRIX + 0x54)	/* Slave Configuration Register 5 */
+#define AT91_MATRIX_SCFG6	(AT91_MATRIX + 0x58)	/* Slave Configuration Register 6 */
+#define AT91_MATRIX_SCFG7	(AT91_MATRIX + 0x5C)	/* Slave Configuration Register 7 */
+#define AT91_MATRIX_SCFG8	(AT91_MATRIX + 0x60)	/* Slave Configuration Register 8 */
+#define AT91_MATRIX_SCFG9	(AT91_MATRIX + 0x64)	/* Slave Configuration Register 9 */
+#define		AT91_MATRIX_SLOT_CYCLE		(0xff << 0)	/* Maximum Number of Allowed Cycles for a Burst */
+#define		AT91_MATRIX_DEFMSTR_TYPE	(3    << 16)	/* Default Master Type */
+#define			AT91_MATRIX_DEFMSTR_TYPE_NONE	(0 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_LAST	(1 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_FIXED	(2 << 16)
+#define		AT91_MATRIX_FIXED_DEFMSTR	(0xf  << 18)	/* Fixed Index of Default Master */
+#define		AT91_MATRIX_ARBT		(3    << 24)	/* Arbitration Type */
+#define			AT91_MATRIX_ARBT_ROUND_ROBIN	(0 << 24)
+#define			AT91_MATRIX_ARBT_FIXED_PRIORITY	(1 << 24)
+
+#define AT91_MATRIX_PRAS0	(AT91_MATRIX + 0x80)	/* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRBS0	(AT91_MATRIX + 0x84)	/* Priority Register B for Slave 0 */
+#define AT91_MATRIX_PRAS1	(AT91_MATRIX + 0x88)	/* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRBS1	(AT91_MATRIX + 0x8C)	/* Priority Register B for Slave 1 */
+#define AT91_MATRIX_PRAS2	(AT91_MATRIX + 0x90)	/* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRBS2	(AT91_MATRIX + 0x94)	/* Priority Register B for Slave 2 */
+#define AT91_MATRIX_PRAS3	(AT91_MATRIX + 0x98)	/* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRBS3	(AT91_MATRIX + 0x9C)	/* Priority Register B for Slave 3 */
+#define AT91_MATRIX_PRAS4	(AT91_MATRIX + 0xA0)	/* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRBS4	(AT91_MATRIX + 0xA4)	/* Priority Register B for Slave 4 */
+#define AT91_MATRIX_PRAS5	(AT91_MATRIX + 0xA8)	/* Priority Register A for Slave 5 */
+#define AT91_MATRIX_PRBS5	(AT91_MATRIX + 0xAC)	/* Priority Register B for Slave 5 */
+#define AT91_MATRIX_PRAS6	(AT91_MATRIX + 0xB0)	/* Priority Register A for Slave 6 */
+#define AT91_MATRIX_PRBS6	(AT91_MATRIX + 0xB4)	/* Priority Register B for Slave 6 */
+#define AT91_MATRIX_PRAS7	(AT91_MATRIX + 0xB8)	/* Priority Register A for Slave 7 */
+#define AT91_MATRIX_PRBS7	(AT91_MATRIX + 0xBC)	/* Priority Register B for Slave 7 */
+#define AT91_MATRIX_PRAS8	(AT91_MATRIX + 0xC0)	/* Priority Register A for Slave 8 */
+#define AT91_MATRIX_PRBS8	(AT91_MATRIX + 0xC4)	/* Priority Register B for Slave 8 */
+#define AT91_MATRIX_PRAS9	(AT91_MATRIX + 0xC8)	/* Priority Register A for Slave 9 */
+#define AT91_MATRIX_PRBS9	(AT91_MATRIX + 0xCC)	/* Priority Register B for Slave 9 */
+#define		AT91_MATRIX_M0PR		(3 << 0)	/* Master 0 Priority */
+#define		AT91_MATRIX_M1PR		(3 << 4)	/* Master 1 Priority */
+#define		AT91_MATRIX_M2PR		(3 << 8)	/* Master 2 Priority */
+#define		AT91_MATRIX_M3PR		(3 << 12)	/* Master 3 Priority */
+#define		AT91_MATRIX_M4PR		(3 << 16)	/* Master 4 Priority */
+#define		AT91_MATRIX_M5PR		(3 << 20)	/* Master 5 Priority */
+#define		AT91_MATRIX_M6PR		(3 << 24)	/* Master 6 Priority */
+#define		AT91_MATRIX_M7PR		(3 << 28)	/* Master 7 Priority */
+#define		AT91_MATRIX_M8PR		(3 << 0)	/* Master 8 Priority (in Register B) */
+#define		AT91_MATRIX_M9PR		(3 << 4)	/* Master 9 Priority (in Register B) */
+#define		AT91_MATRIX_M10PR		(3 << 8)	/* Master 10 Priority (in Register B) */
+#define		AT91_MATRIX_M11PR		(3 << 12)	/* Master 11 Priority (in Register B) */
+
+#define AT91_MATRIX_MRCR	(AT91_MATRIX + 0x100)	/* Master Remap Control Register */
+#define		AT91_MATRIX_RCB0		(1 << 0)	/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define		AT91_MATRIX_RCB1		(1 << 1)	/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+#define		AT91_MATRIX_RCB2		(1 << 2)
+#define		AT91_MATRIX_RCB3		(1 << 3)
+#define		AT91_MATRIX_RCB4		(1 << 4)
+#define		AT91_MATRIX_RCB5		(1 << 5)
+#define		AT91_MATRIX_RCB6		(1 << 6)
+#define		AT91_MATRIX_RCB7		(1 << 7)
+#define		AT91_MATRIX_RCB8		(1 << 8)
+#define		AT91_MATRIX_RCB9		(1 << 9)
+#define		AT91_MATRIX_RCB10		(1 << 10)
+#define		AT91_MATRIX_RCB11		(1 << 11)
+
+#define AT91_MPBS0_SFR		(AT91_MATRIX + 0x114)	/* MPBlock Slave 0 Special Function Register */
+#define AT91_MPBS1_SFR		(AT91_MATRIX + 0x11C)	/* MPBlock Slave 1 Special Function Register */
+
+#define AT91_MATRIX_EBICSA	(AT91_MATRIX + 0x120)	/* EBI Chip Select Assignment Register */
+#define		AT91_MATRIX_EBI_CS1A		(1 << 1)	/* Chip Select 1 Assignment */
+#define			AT91_MATRIX_EBI_CS1A_SMC		(0 << 1)
+#define			AT91_MATRIX_EBI_CS1A_BCRAMC		(1 << 1)
+#define		AT91_MATRIX_EBI_CS3A		(1 << 3)	/* Chip Select 3 Assignment */
+#define			AT91_MATRIX_EBI_CS3A_SMC		(0 << 3)
+#define			AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA	(1 << 3)
+#define		AT91_MATRIX_EBI_CS4A		(1 << 4)	/* Chip Select 4 Assignment */
+#define			AT91_MATRIX_EBI_CS4A_SMC		(0 << 4)
+#define			AT91_MATRIX_EBI_CS4A_SMC_CF1		(1 << 4)
+#define		AT91_MATRIX_EBI_CS5A		(1 << 5)	/* Chip Select 5 Assignment */
+#define			AT91_MATRIX_EBI_CS5A_SMC		(0 << 5)
+#define			AT91_MATRIX_EBI_CS5A_SMC_CF2		(1 << 5)
+#define		AT91_MATRIX_EBI_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
+#define		AT91_MATRIX_EBI_DQSPDC		(1 << 9)	/* Data Qualifier Strobe Pull-Down Configuration */
+#define		AT91_MATRIX_EBI_VDDIOMSEL	(1 << 16)	/* Memory voltage selection */
+#define			AT91_MATRIX_EBI_VDDIOMSEL_1_8V		(0 << 16)
+#define			AT91_MATRIX_EBI_VDDIOMSEL_3_3V		(1 << 16)
+
+#define AT91_MPBS2_SFR		(AT91_MATRIX + 0x12C)	/* MPBlock Slave 2 Special Function Register */
+#define AT91_MPBS3_SFR		(AT91_MATRIX + 0x130)	/* MPBlock Slave 3 Special Function Register */
+#define AT91_APB_SFR		(AT91_MATRIX + 0x134)	/* APB Bridge Special Function Register */
+
+#endif
diff --git a/include/asm-arm/arch-at91/at91sam9260_matrix.h b/include/asm-arm/arch-at91/at91sam9260_matrix.h
index aacb1e9..a8e9fec 100644
--- a/include/asm-arm/arch-at91/at91sam9260_matrix.h
+++ b/include/asm-arm/arch-at91/at91sam9260_matrix.h
@@ -67,7 +67,7 @@
 #define		AT91_MATRIX_CS4A		(1 << 4)	/* Chip Select 4 Assignment */
 #define			AT91_MATRIX_CS4A_SMC		(0 << 4)
 #define			AT91_MATRIX_CS4A_SMC_CF1	(1 << 4)
-#define		AT91_MATRIX_CS5A		(1 << 5 )	/* Chip Select 5 Assignment */
+#define		AT91_MATRIX_CS5A		(1 << 5)	/* Chip Select 5 Assignment */
 #define			AT91_MATRIX_CS5A_SMC		(0 << 5)
 #define			AT91_MATRIX_CS5A_SMC_CF2	(1 << 5)
 #define		AT91_MATRIX_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
diff --git a/include/asm-arm/arch-at91/at91sam9263_matrix.h b/include/asm-arm/arch-at91/at91sam9263_matrix.h
index 6fc6e4b..72f6e66 100644
--- a/include/asm-arm/arch-at91/at91sam9263_matrix.h
+++ b/include/asm-arm/arch-at91/at91sam9263_matrix.h
@@ -44,7 +44,7 @@
 #define			AT91_MATRIX_DEFMSTR_TYPE_NONE	(0 << 16)
 #define			AT91_MATRIX_DEFMSTR_TYPE_LAST	(1 << 16)
 #define			AT91_MATRIX_DEFMSTR_TYPE_FIXED	(2 << 16)
-#define		AT91_MATRIX_FIXED_DEFMSTR	(7    << 18)	/* Fixed Index of Default Master */
+#define		AT91_MATRIX_FIXED_DEFMSTR	(0xf  << 18)	/* Fixed Index of Default Master */
 #define		AT91_MATRIX_ARBT		(3    << 24)	/* Arbitration Type */
 #define			AT91_MATRIX_ARBT_ROUND_ROBIN	(0 << 24)
 #define			AT91_MATRIX_ARBT_FIXED_PRIORITY	(1 << 24)
diff --git a/include/asm-arm/arch-at91/at91sam9rl_matrix.h b/include/asm-arm/arch-at91/at91sam9rl_matrix.h
index b15f11b..8422417 100644
--- a/include/asm-arm/arch-at91/at91sam9rl_matrix.h
+++ b/include/asm-arm/arch-at91/at91sam9rl_matrix.h
@@ -38,7 +38,7 @@
 #define			AT91_MATRIX_DEFMSTR_TYPE_NONE	(0 << 16)
 #define			AT91_MATRIX_DEFMSTR_TYPE_LAST	(1 << 16)
 #define			AT91_MATRIX_DEFMSTR_TYPE_FIXED	(2 << 16)
-#define		AT91_MATRIX_FIXED_DEFMSTR	(7    << 18)	/* Fixed Index of Default Master */
+#define		AT91_MATRIX_FIXED_DEFMSTR	(0xf  << 18)	/* Fixed Index of Default Master */
 #define		AT91_MATRIX_ARBT		(3    << 24)	/* Arbitration Type */
 #define			AT91_MATRIX_ARBT_ROUND_ROBIN	(0 << 24)
 #define			AT91_MATRIX_ARBT_FIXED_PRIORITY	(1 << 24)
diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h
index 7905496..55b07bd 100644
--- a/include/asm-arm/arch-at91/board.h
+++ b/include/asm-arm/arch-at91/board.h
@@ -34,6 +34,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/device.h>
 #include <linux/i2c.h>
+#include <linux/leds.h>
 #include <linux/spi/spi.h>
 
  /* USB Device */
@@ -71,7 +72,7 @@
 };
 extern void __init at91_add_device_eth(struct at91_eth_data *data);
 
-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263)
+#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9)
 #define eth_platform_data	at91_eth_data
 #endif
 
@@ -101,13 +102,23 @@
 extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices);
 
  /* Serial */
+#define ATMEL_UART_CTS	0x01
+#define ATMEL_UART_RTS	0x02
+#define ATMEL_UART_DSR	0x04
+#define ATMEL_UART_DTR	0x08
+#define ATMEL_UART_DCD	0x10
+#define ATMEL_UART_RI	0x20
+
+extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins);
+extern void __init at91_set_serial_console(unsigned portnr);
+
 struct at91_uart_config {
 	unsigned short	console_tty;	/* tty number of serial console */
 	unsigned short	nr_tty;		/* number of serial tty's */
 	short		tty_map[];	/* map UART to tty number */
 };
 extern struct platform_device *atmel_default_console_device;
-extern void __init at91_init_serial(struct at91_uart_config *config);
+extern void __init __deprecated at91_init_serial(struct at91_uart_config *config);
 
 struct atmel_uart_data {
 	short		use_dma_tx;	/* use transmit DMA? */
@@ -116,6 +127,23 @@
 };
 extern void __init at91_add_device_serial(void);
 
+/*
+ * SSC -- accessed through ssc_request(id).  Drivers don't bind to SSC
+ * platform devices.  Their SSC ID is part of their configuration data,
+ * along with information about which SSC signals they should use.
+ */
+#define ATMEL_SSC_TK	0x01
+#define ATMEL_SSC_TF	0x02
+#define ATMEL_SSC_TD	0x04
+#define ATMEL_SSC_TX	(ATMEL_SSC_TK | ATMEL_SSC_TF | ATMEL_SSC_TD)
+
+#define ATMEL_SSC_RK	0x10
+#define ATMEL_SSC_RF	0x20
+#define ATMEL_SSC_RD	0x40
+#define ATMEL_SSC_RX	(ATMEL_SSC_RK | ATMEL_SSC_RF | ATMEL_SSC_RD)
+
+extern void __init at91_add_device_ssc(unsigned id, unsigned pins);
+
  /* LCD Controller */
 struct atmel_lcdfb_info;
 extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
@@ -126,10 +154,12 @@
 };
 extern void __init at91_add_device_ac97(struct atmel_ac97_data *data);
 
+ /* ISI */
+extern void __init at91_add_device_isi(void);
+
  /* LEDs */
-extern u8 at91_leds_cpu;
-extern u8 at91_leds_timer;
 extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
+extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
 
 /* FIXME: this needs a better location, but gets stuff building again */
 extern int at91_suspend_entering_slow_clock(void);
diff --git a/include/asm-arm/arch-at91/cpu.h b/include/asm-arm/arch-at91/cpu.h
index 080cbb4..7145166 100644
--- a/include/asm-arm/arch-at91/cpu.h
+++ b/include/asm-arm/arch-at91/cpu.h
@@ -21,13 +21,13 @@
 #define ARCH_ID_AT91SAM9260	0x019803a0
 #define ARCH_ID_AT91SAM9261	0x019703a0
 #define ARCH_ID_AT91SAM9263	0x019607a0
+#define ARCH_ID_AT91SAM9RL64	0x019b03a0
+#define ARCH_ID_AT91CAP9	0x039A03A0
 
 #define ARCH_ID_AT91SAM9XE128	0x329973a0
 #define ARCH_ID_AT91SAM9XE256	0x329a93a0
 #define ARCH_ID_AT91SAM9XE512	0x329aa3a0
 
-#define ARCH_ID_AT91SAM9RL64	0x019b03a0
-
 #define ARCH_ID_AT91M40800	0x14080044
 #define ARCH_ID_AT91R40807	0x44080746
 #define ARCH_ID_AT91M40807	0x14080745
@@ -81,6 +81,11 @@
 #define cpu_is_at91sam9rl()	(0)
 #endif
 
+#ifdef CONFIG_ARCH_AT91CAP9
+#define cpu_is_at91cap9()	(at91_cpu_identify() == ARCH_ID_AT91CAP9)
+#else
+#define cpu_is_at91cap9()	(0)
+#endif
 
 /*
  * Since this is ARM, we will never run on any AVR32 CPU. But these
diff --git a/include/asm-arm/arch-at91/entry-macro.S b/include/asm-arm/arch-at91/entry-macro.S
index cc1d850..1005eee 100644
--- a/include/asm-arm/arch-at91/entry-macro.S
+++ b/include/asm-arm/arch-at91/entry-macro.S
@@ -17,13 +17,13 @@
 	.endm
 
 	.macro  get_irqnr_preamble, base, tmp
+	ldr	\base, =(AT91_VA_BASE_SYS + AT91_AIC)		@ base virtual address of AIC peripheral
 	.endm
 
 	.macro  arch_ret_to_user, tmp1, tmp2
 	.endm
 
 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-	ldr	\base, =(AT91_VA_BASE_SYS + AT91_AIC)		@ base virtual address of AIC peripheral
 	ldr	\irqnr, [\base, #(AT91_AIC_IVR - AT91_AIC)]	@ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
 	ldr	\irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)]	@ read interrupt source number
 	teq	\irqstat, #0					@ ISR is 0 when no current interrupt, or spurious interrupt
diff --git a/include/asm-arm/arch-at91/hardware.h b/include/asm-arm/arch-at91/hardware.h
index 8f1cdd3..2c826d82 100644
--- a/include/asm-arm/arch-at91/hardware.h
+++ b/include/asm-arm/arch-at91/hardware.h
@@ -26,6 +26,8 @@
 #include <asm/arch/at91sam9263.h>
 #elif defined(CONFIG_ARCH_AT91SAM9RL)
 #include <asm/arch/at91sam9rl.h>
+#elif defined(CONFIG_ARCH_AT91CAP9)
+#include <asm/arch/at91cap9.h>
 #elif defined(CONFIG_ARCH_AT91X40)
 #include <asm/arch/at91x40.h>
 #else
diff --git a/include/asm-arm/arch-at91/timex.h b/include/asm-arm/arch-at91/timex.h
index a310698..f1933b0 100644
--- a/include/asm-arm/arch-at91/timex.h
+++ b/include/asm-arm/arch-at91/timex.h
@@ -42,6 +42,11 @@
 #define AT91SAM9_MASTER_CLOCK	100000000
 #define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
 
+#elif defined(CONFIG_ARCH_AT91CAP9)
+
+#define AT91CAP9_MASTER_CLOCK	100000000
+#define CLOCK_TICK_RATE		(AT91CAP9_MASTER_CLOCK/16)
+
 #elif defined(CONFIG_ARCH_AT91X40)
 
 #define AT91X40_MASTER_CLOCK	40000000
diff --git a/include/asm-arm/arch-ep93xx/gpio.h b/include/asm-arm/arch-ep93xx/gpio.h
index 1ee14a1..9b1864b 100644
--- a/include/asm-arm/arch-ep93xx/gpio.h
+++ b/include/asm-arm/arch-ep93xx/gpio.h
@@ -5,16 +5,6 @@
 #ifndef __ASM_ARCH_GPIO_H
 #define __ASM_ARCH_GPIO_H
 
-#define GPIO_IN				0
-#define GPIO_OUT			1
-
-#define EP93XX_GPIO_LOW			0
-#define EP93XX_GPIO_HIGH		1
-
-extern void gpio_line_config(int line, int direction);
-extern int  gpio_line_get(int line);
-extern void gpio_line_set(int line, int value);
-
 /* GPIO port A.  */
 #define EP93XX_GPIO_LINE_A(x)		((x) + 0)
 #define EP93XX_GPIO_LINE_EGPIO0		EP93XX_GPIO_LINE_A(0)
@@ -38,7 +28,7 @@
 #define EP93XX_GPIO_LINE_EGPIO15	EP93XX_GPIO_LINE_B(7)
 
 /* GPIO port C.  */
-#define EP93XX_GPIO_LINE_C(x)		((x) + 16)
+#define EP93XX_GPIO_LINE_C(x)		((x) + 40)
 #define EP93XX_GPIO_LINE_ROW0		EP93XX_GPIO_LINE_C(0)
 #define EP93XX_GPIO_LINE_ROW1		EP93XX_GPIO_LINE_C(1)
 #define EP93XX_GPIO_LINE_ROW2		EP93XX_GPIO_LINE_C(2)
@@ -71,7 +61,7 @@
 #define EP93XX_GPIO_LINE_IDEDA2		EP93XX_GPIO_LINE_E(7)
 
 /* GPIO port F.  */
-#define EP93XX_GPIO_LINE_F(x)		((x) + 40)
+#define EP93XX_GPIO_LINE_F(x)		((x) + 16)
 #define EP93XX_GPIO_LINE_WP		EP93XX_GPIO_LINE_F(0)
 #define EP93XX_GPIO_LINE_MCCD1		EP93XX_GPIO_LINE_F(1)
 #define EP93XX_GPIO_LINE_MCCD2		EP93XX_GPIO_LINE_F(2)
@@ -103,5 +93,49 @@
 #define EP93XX_GPIO_LINE_DD6		EP93XX_GPIO_LINE_H(6)
 #define EP93XX_GPIO_LINE_DD7		EP93XX_GPIO_LINE_H(7)
 
+/* maximum value for gpio line identifiers */
+#define EP93XX_GPIO_LINE_MAX		EP93XX_GPIO_LINE_H(7)
+
+/* maximum value for irq capable line identifiers */
+#define EP93XX_GPIO_LINE_MAX_IRQ	EP93XX_GPIO_LINE_F(7)
+
+/* new generic GPIO API - see Documentation/gpio.txt */
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+	if (gpio > EP93XX_GPIO_LINE_MAX)
+		return -EINVAL;
+	return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+}
+
+int gpio_direction_input(unsigned gpio);
+int gpio_direction_output(unsigned gpio, int value);
+int gpio_get_value(unsigned gpio);
+void gpio_set_value(unsigned gpio, int value);
+
+#include <asm-generic/gpio.h> /* cansleep wrappers */
+
+/*
+ * Map GPIO A0..A7  (0..7)  to irq 64..71,
+ *          B0..B7  (7..15) to irq 72..79, and
+ *          F0..F7 (16..24) to irq 80..87.
+ */
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+	if (gpio <= EP93XX_GPIO_LINE_MAX_IRQ)
+		return 64 + gpio;
+
+	return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+	return irq - gpio_to_irq(0);
+}
 
 #endif
diff --git a/include/asm-arm/arch-ep93xx/irqs.h b/include/asm-arm/arch-ep93xx/irqs.h
index 2a8c636..53d4a68 100644
--- a/include/asm-arm/arch-ep93xx/irqs.h
+++ b/include/asm-arm/arch-ep93xx/irqs.h
@@ -67,12 +67,6 @@
 #define IRQ_EP93XX_SAI			60
 #define EP93XX_VIC2_VALID_IRQ_MASK	0x1fffffff
 
-/*
- * Map GPIO A0..A7 to irq 64..71, B0..B7 to 72..79, and
- * F0..F7 to 80..87.
- */
-#define IRQ_EP93XX_GPIO(x)		(64 + (((x) + (((x) >> 2) & 8)) & 0x1f))
-
 #define NR_EP93XX_IRQS			(64 + 24)
 
 #define EP93XX_BOARD_IRQ(x)		(NR_EP93XX_IRQS + (x))
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index eeeea90..9c5d235 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -61,13 +61,13 @@
 	if((addr < PCIBIOS_MIN_MEM) || (addr > 0x4fffffff))
 		return __arm_ioremap(addr, size, mtype);
 
-	return (void *)addr;
+	return (void __iomem *)addr;
 }
 
 static inline void
 __ixp4xx_iounmap(void __iomem *addr)
 {
-	if ((u32)addr >= VMALLOC_START)
+	if ((__force u32)addr >= VMALLOC_START)
 		__iounmap(addr);
 }
 
@@ -141,9 +141,9 @@
 static inline void 
 __ixp4xx_writel(u32 value, volatile void __iomem *p)
 {
-	u32 addr = (u32)p;
+	u32 addr = (__force u32)p;
 	if (addr >= VMALLOC_START) {
-		__raw_writel(value, addr);
+		__raw_writel(value, p);
 		return;
 	}
 
@@ -208,11 +208,11 @@
 static inline unsigned long 
 __ixp4xx_readl(const volatile void __iomem *p)
 {
-	u32 addr = (u32)p;
+	u32 addr = (__force u32)p;
 	u32 data;
 
 	if (addr >= VMALLOC_START)
-		return __raw_readl(addr);
+		return __raw_readl(p);
 
 	if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
 		return 0xffffffff;
@@ -438,7 +438,7 @@
 		return	(unsigned int)__ixp4xx_inl(port & PIO_MASK);
 	else {
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		return le32_to_cpu(__raw_readl((u32)port));
+		return le32_to_cpu((__force __le32)__raw_readl(addr));
 #else
 		return (unsigned int)__ixp4xx_readl(addr);
 #endif
@@ -523,7 +523,7 @@
 		__ixp4xx_outl(value, port & PIO_MASK);
 	else
 #ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_writel(cpu_to_le32(value), port);
+		__raw_writel((u32 __force)cpu_to_le32(value), addr);
 #else
 		__ixp4xx_writel(value, addr);
 #endif
diff --git a/include/asm-arm/arch-ks8695/regs-gpio.h b/include/asm-arm/arch-ks8695/regs-gpio.h
index 57fcf9f..6b95d77 100644
--- a/include/asm-arm/arch-ks8695/regs-gpio.h
+++ b/include/asm-arm/arch-ks8695/regs-gpio.h
@@ -49,5 +49,7 @@
 #define IOPC_TM_FALLING		(4)		/* Falling Edge Detection */
 #define IOPC_TM_EDGE		(6)		/* Both Edge Detection */
 
+/* Port Data Register */
+#define IOPD_(x)		(1 << (x))	/* Signal Level of GPIO Pin x */
 
 #endif
diff --git a/include/asm-arm/arch-msm/board.h b/include/asm-arm/arch-msm/board.h
new file mode 100644
index 0000000..763051f
--- /dev/null
+++ b/include/asm-arm/arch-msm/board.h
@@ -0,0 +1,37 @@
+/* linux/include/asm-arm/arch-msm/board.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_BOARD_H
+#define __ASM_ARCH_MSM_BOARD_H
+
+#include <linux/types.h>
+
+/* platform device data structures */
+
+struct msm_mddi_platform_data
+{
+	void (*panel_power)(int on);
+	unsigned has_vsync_irq:1;
+};
+
+/* common init routines for use by arch/arm/mach-msm/board-*.c */
+
+void __init msm_add_devices(void);
+void __init msm_map_common_io(void);
+void __init msm_init_irq(void);
+void __init msm_init_gpio(void);
+
+#endif
diff --git a/include/asm-arm/arch-msm/debug-macro.S b/include/asm-arm/arch-msm/debug-macro.S
new file mode 100644
index 0000000..393d527
--- /dev/null
+++ b/include/asm-arm/arch-msm/debug-macro.S
@@ -0,0 +1,40 @@
+/* include/asm-arm/arch-msm7200/debug-macro.S
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/hardware.h>
+#include <asm/arch/msm_iomap.h>
+
+	.macro	addruart,rx
+	@ see if the MMU is enabled and select appropriate base address
+	mrc	p15, 0, \rx, c1, c0
+	tst	\rx, #1
+	ldreq	\rx, =MSM_UART1_PHYS
+	ldrne	\rx, =MSM_UART1_BASE
+	.endm
+
+	.macro	senduart,rd,rx
+	str	\rd, [\rx, #0x0C]
+	.endm
+
+	.macro	waituart,rd,rx
+	@ wait for TX_READY
+1:	ldr	\rd, [\rx, #0x08]
+	tst	\rd, #0x04
+	beq	1b
+	.endm
+
+	.macro	busyuart,rd,rx
+	.endm
diff --git a/include/asm-arm/arch-msm/dma.h b/include/asm-arm/arch-msm/dma.h
new file mode 100644
index 0000000..e4b565b
--- /dev/null
+++ b/include/asm-arm/arch-msm/dma.h
@@ -0,0 +1,151 @@
+/* linux/include/asm-arm/arch-msm/dma.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_DMA_H
+
+#include <linux/list.h>
+#include <asm/arch/msm_iomap.h>
+
+struct msm_dmov_cmd {
+	struct list_head list;
+	unsigned int cmdptr;
+	void (*complete_func)(struct msm_dmov_cmd *cmd, unsigned int result);
+/*	void (*user_result_func)(struct msm_dmov_cmd *cmd); */
+};
+
+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd);
+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
+/* int msm_dmov_exec_cmd_etc(unsigned id, unsigned int cmdptr, int timeout, int interruptible); */
+
+
+
+#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2))
+#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2))
+#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
+#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
+
+/* only security domain 3 is available to the ARM11
+ * SD0 -> mARM trusted, SD1 -> mARM nontrusted, SD2 -> aDSP, SD3 -> aARM
+ */
+
+#define DMOV_CMD_PTR(ch)      DMOV_SD3(0x000, ch)
+#define DMOV_CMD_LIST         (0 << 29) /* does not work */
+#define DMOV_CMD_PTR_LIST     (1 << 29) /* works */
+#define DMOV_CMD_INPUT_CFG    (2 << 29) /* untested */
+#define DMOV_CMD_OUTPUT_CFG   (3 << 29) /* untested */
+#define DMOV_CMD_ADDR(addr)   ((addr) >> 3)
+
+#define DMOV_RSLT(ch)         DMOV_SD3(0x040, ch)
+#define DMOV_RSLT_VALID       (1 << 31) /* 0 == host has empties result fifo */
+#define DMOV_RSLT_ERROR       (1 << 3)
+#define DMOV_RSLT_FLUSH       (1 << 2)
+#define DMOV_RSLT_DONE        (1 << 1)  /* top pointer done */
+#define DMOV_RSLT_USER        (1 << 0)  /* command with FR force result */
+
+#define DMOV_FLUSH0(ch)       DMOV_SD3(0x080, ch)
+#define DMOV_FLUSH1(ch)       DMOV_SD3(0x0C0, ch)
+#define DMOV_FLUSH2(ch)       DMOV_SD3(0x100, ch)
+#define DMOV_FLUSH3(ch)       DMOV_SD3(0x140, ch)
+#define DMOV_FLUSH4(ch)       DMOV_SD3(0x180, ch)
+#define DMOV_FLUSH5(ch)       DMOV_SD3(0x1C0, ch)
+
+#define DMOV_STATUS(ch)       DMOV_SD3(0x200, ch)
+#define DMOV_STATUS_RSLT_COUNT(n)    (((n) >> 29))
+#define DMOV_STATUS_CMD_COUNT(n)     (((n) >> 27) & 3)
+#define DMOV_STATUS_RSLT_VALID       (1 << 1)
+#define DMOV_STATUS_CMD_PTR_RDY      (1 << 0)
+
+#define DMOV_ISR              DMOV_SD3(0x380, 0)
+
+#define DMOV_CONFIG(ch)       DMOV_SD3(0x300, ch)
+#define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2)
+#define DMOV_CONFIG_FORCE_FLUSH_RSLT   (1 << 1)
+#define DMOV_CONFIG_IRQ_EN             (1 << 0)
+
+/* channel assignments */
+
+#define DMOV_NAND_CHAN        7
+#define DMOV_NAND_CRCI_CMD    5
+#define DMOV_NAND_CRCI_DATA   4
+
+#define DMOV_SDC1_CHAN        8
+#define DMOV_SDC1_CRCI        6
+
+#define DMOV_SDC2_CHAN        8
+#define DMOV_SDC2_CRCI        7
+
+#define DMOV_TSIF_CHAN        10
+#define DMOV_TSIF_CRCI        10
+
+#define DMOV_USB_CHAN         11
+
+/* no client rate control ifc (eg, ram) */
+#define DMOV_NONE_CRCI        0
+
+
+/* If the CMD_PTR register has CMD_PTR_LIST selected, the data mover
+ * is going to walk a list of 32bit pointers as described below.  Each
+ * pointer points to a *array* of dmov_s, etc structs.  The last pointer
+ * in the list is marked with CMD_PTR_LP.  The last struct in each array
+ * is marked with CMD_LC (see below).
+ */
+#define CMD_PTR_ADDR(addr)  ((addr) >> 3)
+#define CMD_PTR_LP          (1 << 31) /* last pointer */
+#define CMD_PTR_PT          (3 << 29) /* ? */
+
+/* Single Item Mode */
+typedef struct {
+	unsigned cmd;
+	unsigned src;
+	unsigned dst;
+	unsigned len;
+} dmov_s;
+
+/* Scatter/Gather Mode */
+typedef struct {
+	unsigned cmd;
+	unsigned src_dscr;
+	unsigned dst_dscr;
+	unsigned _reserved;
+} dmov_sg;
+
+/* bits for the cmd field of the above structures */
+
+#define CMD_LC      (1 << 31)  /* last command */
+#define CMD_FR      (1 << 22)  /* force result -- does not work? */
+#define CMD_OCU     (1 << 21)  /* other channel unblock */
+#define CMD_OCB     (1 << 20)  /* other channel block */
+#define CMD_TCB     (1 << 19)  /* ? */
+#define CMD_DAH     (1 << 18)  /* destination address hold -- does not work?*/
+#define CMD_SAH     (1 << 17)  /* source address hold -- does not work? */
+
+#define CMD_MODE_SINGLE     (0 << 0) /* dmov_s structure used */
+#define CMD_MODE_SG         (1 << 0) /* untested */
+#define CMD_MODE_IND_SG     (2 << 0) /* untested */
+#define CMD_MODE_BOX        (3 << 0) /* untested */
+
+#define CMD_DST_SWAP_BYTES  (1 << 14) /* exchange each byte n with byte n+1 */
+#define CMD_DST_SWAP_SHORTS (1 << 15) /* exchange each short n with short n+1 */
+#define CMD_DST_SWAP_WORDS  (1 << 16) /* exchange each word n with word n+1 */
+
+#define CMD_SRC_SWAP_BYTES  (1 << 11) /* exchange each byte n with byte n+1 */
+#define CMD_SRC_SWAP_SHORTS (1 << 12) /* exchange each short n with short n+1 */
+#define CMD_SRC_SWAP_WORDS  (1 << 13) /* exchange each word n with word n+1 */
+
+#define CMD_DST_CRCI(n)     (((n) & 15) << 7)
+#define CMD_SRC_CRCI(n)     (((n) & 15) << 3)
+
+#endif
diff --git a/include/asm-arm/arch-msm/entry-macro.S b/include/asm-arm/arch-msm/entry-macro.S
new file mode 100644
index 0000000..ee24aec
--- /dev/null
+++ b/include/asm-arm/arch-msm/entry-macro.S
@@ -0,0 +1,38 @@
+/* include/asm-arm/arch-msm7200/entry-macro.S
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/arch/msm_iomap.h>
+
+ 	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_preamble, base, tmp
+	@ enable imprecise aborts
+	cpsie	a
+	mov	\base, #MSM_VIC_BASE
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	@ 0xD0 has irq# or old irq# if the irq has been handled
+	@ 0xD4 has irq# or -1 if none pending *but* if you just
+	@ read 0xD4 you never get the first irq for some reason
+	ldr	\irqnr, [\base, #0xD0]
+	ldr	\irqnr, [\base, #0xD4]
+	cmp	\irqnr, #0xffffffff
+	.endm
diff --git a/include/asm-arm/arch-msm/hardware.h b/include/asm-arm/arch-msm/hardware.h
new file mode 100644
index 0000000..89af2b7
--- /dev/null
+++ b/include/asm-arm/arch-msm/hardware.h
@@ -0,0 +1,18 @@
+/* linux/include/asm-arm/arch-msm/hardware.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_HARDWARE_H
+
+#endif
diff --git a/include/asm-arm/arch-msm/io.h b/include/asm-arm/arch-msm/io.h
new file mode 100644
index 0000000..4645ae2
--- /dev/null
+++ b/include/asm-arm/arch-msm/io.h
@@ -0,0 +1,33 @@
+/* include/asm-arm/arch-msm/io.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __arch_ioremap __msm_ioremap
+#define __arch_iounmap __iounmap
+
+void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype);
+
+static inline void __iomem *__io(unsigned long addr)
+{
+	return (void __iomem *)addr;
+}
+#define __io(a)         __io(a)
+#define __mem_pci(a)    (a)
+
+#endif
diff --git a/include/asm-arm/arch-msm/irqs.h b/include/asm-arm/arch-msm/irqs.h
new file mode 100644
index 0000000..565430c
--- /dev/null
+++ b/include/asm-arm/arch-msm/irqs.h
@@ -0,0 +1,89 @@
+/* linux/include/asm-arm/arch-msm/irqs.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_H
+
+/* MSM ARM11 Interrupt Numbers */
+/* See 80-VE113-1 A, pp219-221     */
+
+#define INT_A9_M2A_0         0
+#define INT_A9_M2A_1         1
+#define INT_A9_M2A_2         2
+#define INT_A9_M2A_3         3
+#define INT_A9_M2A_4         4
+#define INT_A9_M2A_5         5
+#define INT_A9_M2A_6         6
+#define INT_GP_TIMER_EXP     7
+#define INT_DEBUG_TIMER_EXP  8
+#define INT_UART1            9
+#define INT_UART2            10
+#define INT_UART3            11
+#define INT_UART1_RX         12
+#define INT_UART2_RX         13
+#define INT_UART3_RX         14
+#define INT_USB_OTG          15
+#define INT_MDDI_PRI         16
+#define INT_MDDI_EXT         17
+#define INT_MDDI_CLIENT      18
+#define INT_MDP              19
+#define INT_GRAPHICS         20
+#define INT_ADM_AARM         21
+#define INT_ADSP_A11         22
+#define INT_ADSP_A9_A11      23
+#define INT_SDC1_0           24
+#define INT_SDC1_1           25
+#define INT_SDC2_0           26
+#define INT_SDC2_1           27
+#define INT_KEYSENSE         28
+#define INT_TCHSCRN_SSBI     29
+#define INT_TCHSCRN1         30
+#define INT_TCHSCRN2         31
+
+#define INT_GPIO_GROUP1      (32 + 0)
+#define INT_GPIO_GROUP2      (32 + 1)
+#define INT_PWB_I2C          (32 + 2)
+#define INT_SOFTRESET        (32 + 3)
+#define INT_NAND_WR_ER_DONE  (32 + 4)
+#define INT_NAND_OP_DONE     (32 + 5)
+#define INT_PBUS_ARM11       (32 + 6)
+#define INT_AXI_MPU_SMI      (32 + 7)
+#define INT_AXI_MPU_EBI1     (32 + 8)
+#define INT_AD_HSSD          (32 + 9)
+#define INT_ARM11_PMU        (32 + 10)
+#define INT_ARM11_DMA        (32 + 11)
+#define INT_TSIF_IRQ         (32 + 12)
+#define INT_UART1DM_IRQ      (32 + 13)
+#define INT_UART1DM_RX       (32 + 14)
+#define INT_USB_HS           (32 + 15)
+#define INT_SDC3_0           (32 + 16)
+#define INT_SDC3_1           (32 + 17)
+#define INT_SDC4_0           (32 + 18)
+#define INT_SDC4_1           (32 + 19)
+#define INT_UART2DM_RX       (32 + 20)
+#define INT_UART2DM_IRQ      (32 + 21)
+
+/* 22-31 are reserved */
+
+#define MSM_IRQ_BIT(irq)     (1 << ((irq) & 31))
+
+#define NR_MSM_IRQS 64
+#define NR_GPIO_IRQS 122
+#define NR_BOARD_IRQS 64
+#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
+
+#define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n))
+
+#endif
diff --git a/include/asm-arm/arch-msm/memory.h b/include/asm-arm/arch-msm/memory.h
new file mode 100644
index 0000000..b5ce0e9
--- /dev/null
+++ b/include/asm-arm/arch-msm/memory.h
@@ -0,0 +1,27 @@
+/* linux/include/asm-arm/arch-msm/memory.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/* physical offset of RAM */
+#define PHYS_OFFSET		UL(0x10000000)
+
+/* bus address and physical addresses are identical */
+#define __virt_to_bus(x)	__virt_to_phys(x)
+#define __bus_to_virt(x)	__phys_to_virt(x)
+
+#endif
+
diff --git a/include/asm-arm/arch-msm/msm_iomap.h b/include/asm-arm/arch-msm/msm_iomap.h
new file mode 100644
index 0000000..b8955cc
--- /dev/null
+++ b/include/asm-arm/arch-msm/msm_iomap.h
@@ -0,0 +1,104 @@
+/* linux/include/asm-arm/arch-msm/msm_iomap.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough.  Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_H
+#define __ASM_ARCH_MSM_IOMAP_H
+
+#include <asm/sizes.h>
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM_VIC_BASE          0xE0000000
+#define MSM_VIC_PHYS          0xC0000000
+#define MSM_VIC_SIZE          SZ_4K
+
+#define MSM_CSR_BASE          0xE0001000
+#define MSM_CSR_PHYS          0xC0100000
+#define MSM_CSR_SIZE          SZ_4K
+
+#define MSM_GPT_PHYS          MSM_CSR_PHYS
+#define MSM_GPT_BASE          MSM_CSR_BASE
+#define MSM_GPT_SIZE          SZ_4K
+
+#define MSM_DMOV_BASE         0xE0002000
+#define MSM_DMOV_PHYS         0xA9700000
+#define MSM_DMOV_SIZE         SZ_4K
+
+#define MSM_UART1_BASE        0xE0003000
+#define MSM_UART1_PHYS        0xA9A00000
+#define MSM_UART1_SIZE        SZ_4K
+
+#define MSM_UART2_BASE        0xE0004000
+#define MSM_UART2_PHYS        0xA9B00000
+#define MSM_UART2_SIZE        SZ_4K
+
+#define MSM_UART3_BASE        0xE0005000
+#define MSM_UART3_PHYS        0xA9C00000
+#define MSM_UART3_SIZE        SZ_4K
+
+#define MSM_I2C_BASE          0xE0006000
+#define MSM_I2C_PHYS          0xA9900000
+#define MSM_I2C_SIZE          SZ_4K
+
+#define MSM_GPIO1_BASE        0xE0007000
+#define MSM_GPIO1_PHYS        0xA9200000
+#define MSM_GPIO1_SIZE        SZ_4K
+
+#define MSM_GPIO2_BASE        0xE0008000
+#define MSM_GPIO2_PHYS        0xA9300000
+#define MSM_GPIO2_SIZE        SZ_4K
+
+#define MSM_HSUSB_BASE        0xE0009000
+#define MSM_HSUSB_PHYS        0xA0800000
+#define MSM_HSUSB_SIZE        SZ_4K
+
+#define MSM_CLK_CTL_BASE      0xE000A000
+#define MSM_CLK_CTL_PHYS      0xA8600000
+#define MSM_CLK_CTL_SIZE      SZ_4K
+
+#define MSM_PMDH_BASE         0xE000B000
+#define MSM_PMDH_PHYS         0xAA600000
+#define MSM_PMDH_SIZE         SZ_4K
+
+#define MSM_EMDH_BASE         0xE000C000
+#define MSM_EMDH_PHYS         0xAA700000
+#define MSM_EMDH_SIZE         SZ_4K
+
+#define MSM_MDP_BASE          0xE0010000
+#define MSM_MDP_PHYS          0xAA200000
+#define MSM_MDP_SIZE          0x000F0000
+
+#define MSM_SHARED_RAM_BASE   0xE0100000
+#define MSM_SHARED_RAM_PHYS   0x01F00000
+#define MSM_SHARED_RAM_SIZE   SZ_1M
+
+#endif
diff --git a/include/asm-arm/arch-msm/system.h b/include/asm-arm/arch-msm/system.h
new file mode 100644
index 0000000..7c5544b
--- /dev/null
+++ b/include/asm-arm/arch-msm/system.h
@@ -0,0 +1,23 @@
+/* linux/include/asm-arm/arch-msm/system.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/hardware.h>
+
+void arch_idle(void);
+
+static inline void arch_reset(char mode)
+{
+	for (;;) ;  /* depends on IPC w/ other core */
+}
diff --git a/include/asm-arm/arch-msm/timex.h b/include/asm-arm/arch-msm/timex.h
new file mode 100644
index 0000000..154b23f
--- /dev/null
+++ b/include/asm-arm/arch-msm/timex.h
@@ -0,0 +1,20 @@
+/* linux/include/asm-arm/arch-msm/timex.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_TIMEX_H
+
+#define CLOCK_TICK_RATE		1000000
+
+#endif
diff --git a/include/asm-arm/arch-msm/uncompress.h b/include/asm-arm/arch-msm/uncompress.h
new file mode 100644
index 0000000..e91ed78
--- /dev/null
+++ b/include/asm-arm/arch-msm/uncompress.h
@@ -0,0 +1,36 @@
+/* linux/include/asm-arm/arch-msm/uncompress.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_UNCOMPRESS_H
+
+#include "hardware.h"
+
+static void putc(int c)
+{
+}
+
+static inline void flush(void)
+{
+}
+
+static inline void arch_decomp_setup(void)
+{
+}
+
+static inline void arch_decomp_wdog(void)
+{
+}
+
+#endif
diff --git a/include/asm-arm/arch-msm/vmalloc.h b/include/asm-arm/arch-msm/vmalloc.h
new file mode 100644
index 0000000..60f8d91
--- /dev/null
+++ b/include/asm-arm/arch-msm/vmalloc.h
@@ -0,0 +1,22 @@
+/* linux/include/asm-arm/arch-msm/vmalloc.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_VMALLOC_H
+#define __ASM_ARCH_MSM_VMALLOC_H
+
+#define VMALLOC_END	  (PAGE_OFFSET + 0x10000000)
+
+#endif
+
diff --git a/include/asm-arm/arch-orion/debug-macro.S b/include/asm-arm/arch-orion/debug-macro.S
new file mode 100644
index 0000000..e2a8064
--- /dev/null
+++ b/include/asm-arm/arch-orion/debug-macro.S
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-arm/arch-orion/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+	.macro  addruart,rx
+	mov   \rx, #0xf1000000
+	orr   \rx, \rx, #0x00012000
+	.endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff --git a/include/asm-arm/arch-orion/dma.h b/include/asm-arm/arch-orion/dma.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/include/asm-arm/arch-orion/dma.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/include/asm-arm/arch-orion/entry-macro.S b/include/asm-arm/arch-orion/entry-macro.S
new file mode 100644
index 0000000..b76075a
--- /dev/null
+++ b/include/asm-arm/arch-orion/entry-macro.S
@@ -0,0 +1,31 @@
+/*
+ * include/asm-arm/arch-orion/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Orion platforms
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/arch/orion.h>
+
+	.macro  disable_fiq
+	.endm
+
+	.macro  arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro  get_irqnr_preamble, base, tmp
+	ldr	\base, =MAIN_IRQ_CAUSE
+	.endm
+
+	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr	\irqstat, [\base, #0]		@ main cause
+	ldr	\tmp, [\base, #(MAIN_IRQ_MASK - MAIN_IRQ_CAUSE)] @ main mask
+	mov	\irqnr, #0			@ default irqnr
+	@ find cause bits that are unmasked
+	ands	\irqstat, \irqstat, \tmp	@ clear Z flag if any
+	clzne	\irqnr,	\irqstat		@ calc irqnr
+	rsbne	\irqnr, \irqnr, #31
+	.endm
diff --git a/include/asm-arm/arch-orion/gpio.h b/include/asm-arm/arch-orion/gpio.h
new file mode 100644
index 0000000..d66284f
--- /dev/null
+++ b/include/asm-arm/arch-orion/gpio.h
@@ -0,0 +1,28 @@
+/*
+ * include/asm-arm/arch-orion/gpio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+extern int gpio_request(unsigned pin, const char *label);
+extern void gpio_free(unsigned pin);
+extern int gpio_direction_input(unsigned pin);
+extern int gpio_direction_output(unsigned pin, int value);
+extern int gpio_get_value(unsigned pin);
+extern void gpio_set_value(unsigned pin, int value);
+extern void orion_gpio_set_blink(unsigned pin, int blink);
+extern void gpio_display(void);		/* debug */
+
+static inline int gpio_to_irq(int pin)
+{
+	return pin + IRQ_ORION_GPIO_START;
+}
+
+static inline int irq_to_gpio(int irq)
+{
+	return irq - IRQ_ORION_GPIO_START;
+}
+
+#include <asm-generic/gpio.h>		/* cansleep wrappers */
diff --git a/include/asm-arm/arch-orion/hardware.h b/include/asm-arm/arch-orion/hardware.h
new file mode 100644
index 0000000..8a12d21
--- /dev/null
+++ b/include/asm-arm/arch-orion/hardware.h
@@ -0,0 +1,24 @@
+/*
+ * include/asm-arm/arch-orion/hardware.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#define __ASM_ARCH_HARDWARE_H__
+
+#include "orion.h"
+
+#define PCI_MEMORY_VADDR        ORION_PCI_SYS_MEM_BASE
+#define PCI_IO_VADDR            ORION_PCI_SYS_IO_BASE
+
+#define pcibios_assign_all_busses()  1
+
+#define PCIBIOS_MIN_IO  0x1000
+#define PCIBIOS_MIN_MEM 0x01000000
+#define PCIMEM_BASE     PCI_MEMORY_VADDR /* mem base for VGA */
+
+#endif  /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-orion/io.h b/include/asm-arm/arch-orion/io.h
new file mode 100644
index 0000000..e0b8c39
--- /dev/null
+++ b/include/asm-arm/arch-orion/io.h
@@ -0,0 +1,27 @@
+/*
+ * include/asm-arm/arch-orion/io.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include "orion.h"
+
+#define IO_SPACE_LIMIT		0xffffffff
+#define IO_SPACE_REMAP		ORION_PCI_SYS_IO_BASE
+
+static inline void __iomem *__io(unsigned long addr)
+{
+	return (void __iomem *)addr;
+}
+
+#define __io(a)			__io(a)
+#define __mem_pci(a)		(a)
+
+#endif
diff --git a/include/asm-arm/arch-orion/irqs.h b/include/asm-arm/arch-orion/irqs.h
new file mode 100644
index 0000000..eea65ca
--- /dev/null
+++ b/include/asm-arm/arch-orion/irqs.h
@@ -0,0 +1,61 @@
+/*
+ * include/asm-arm/arch-orion/irqs.h
+ *
+ * IRQ definitions for Orion SoC
+ *
+ *  Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ *  This file is licensed under the terms of the GNU General Public
+ *  License version 2. This program is licensed "as is" without any
+ *  warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+
+#include "orion.h"	/* need GPIO_MAX */
+
+/*
+ * Orion Main Interrupt Controller
+ */
+#define IRQ_ORION_BRIDGE	0
+#define IRQ_ORION_DOORBELL_H2C	1
+#define IRQ_ORION_DOORBELL_C2H	2
+#define IRQ_ORION_UART0		3
+#define IRQ_ORION_UART1		4
+#define IRQ_ORION_I2C		5
+#define IRQ_ORION_GPIO_0_7	6
+#define IRQ_ORION_GPIO_8_15	7
+#define IRQ_ORION_GPIO_16_23	8
+#define IRQ_ORION_GPIO_24_31	9
+#define IRQ_ORION_PCIE0_ERR	10
+#define IRQ_ORION_PCIE0_INT	11
+#define IRQ_ORION_USB1_CTRL	12
+#define IRQ_ORION_DEV_BUS_ERR	14
+#define IRQ_ORION_PCI_ERR	15
+#define IRQ_ORION_USB_BR_ERR	16
+#define IRQ_ORION_USB0_CTRL	17
+#define IRQ_ORION_ETH_RX	18
+#define IRQ_ORION_ETH_TX	19
+#define IRQ_ORION_ETH_MISC	20
+#define IRQ_ORION_ETH_SUM	21
+#define IRQ_ORION_ETH_ERR	22
+#define IRQ_ORION_IDMA_ERR	23
+#define IRQ_ORION_IDMA_0	24
+#define IRQ_ORION_IDMA_1	25
+#define IRQ_ORION_IDMA_2	26
+#define IRQ_ORION_IDMA_3	27
+#define IRQ_ORION_CESA		28
+#define IRQ_ORION_SATA		29
+#define IRQ_ORION_XOR0		30
+#define IRQ_ORION_XOR1		31
+
+/*
+ * Orion General Purpose Pins
+ */
+#define IRQ_ORION_GPIO_START	32
+#define NR_GPIO_IRQS		GPIO_MAX
+
+#define NR_IRQS			(IRQ_ORION_GPIO_START + NR_GPIO_IRQS)
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff --git a/include/asm-arm/arch-orion/memory.h b/include/asm-arm/arch-orion/memory.h
new file mode 100644
index 0000000..d954dba
--- /dev/null
+++ b/include/asm-arm/arch-orion/memory.h
@@ -0,0 +1,15 @@
+/*
+ * include/asm-arm/arch-orion/memory.h
+ *
+ * Marvell Orion memory definitions
+ */
+
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#define PHYS_OFFSET	UL(0x00000000)
+
+#define __virt_to_bus(x)	__virt_to_phys(x)
+#define __bus_to_virt(x)	__phys_to_virt(x)
+
+#endif
diff --git a/include/asm-arm/arch-orion/orion.h b/include/asm-arm/arch-orion/orion.h
new file mode 100644
index 0000000..f787f75
--- /dev/null
+++ b/include/asm-arm/arch-orion/orion.h
@@ -0,0 +1,143 @@
+/*
+ * include/asm-arm/arch-orion/orion.h
+ *
+ * Generic definitions of Orion SoC flavors:
+ *  Orion-1, Orion-NAS, Orion-VoIP, and Orion-2.
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_ORION_H__
+#define __ASM_ARCH_ORION_H__
+
+/*******************************************************************************
+ * Orion Address Map
+ * Use the same mapping (1:1 virtual:physical) of internal registers and
+ * PCI system (PCI+PCIE) for all machines.
+ * Each machine defines the rest of its mapping (e.g. device bus flashes)
+ ******************************************************************************/
+#define ORION_REGS_BASE		0xf1000000
+#define ORION_REGS_SIZE		SZ_1M
+
+#define ORION_PCI_SYS_MEM_BASE	0xe0000000
+#define ORION_PCIE_MEM_BASE	ORION_PCI_SYS_MEM_BASE
+#define ORION_PCIE_MEM_SIZE	SZ_128M
+#define ORION_PCI_MEM_BASE	(ORION_PCIE_MEM_BASE + ORION_PCIE_MEM_SIZE)
+#define ORION_PCI_MEM_SIZE	SZ_128M
+
+#define ORION_PCI_SYS_IO_BASE	0xf2000000
+#define ORION_PCIE_IO_BASE	ORION_PCI_SYS_IO_BASE
+#define ORION_PCIE_IO_SIZE	SZ_1M
+#define ORION_PCIE_IO_REMAP	(ORION_PCIE_IO_BASE - ORION_PCI_SYS_IO_BASE)
+#define ORION_PCI_IO_BASE	(ORION_PCIE_IO_BASE + ORION_PCIE_IO_SIZE)
+#define ORION_PCI_IO_SIZE	SZ_1M
+#define ORION_PCI_IO_REMAP	(ORION_PCI_IO_BASE - ORION_PCI_SYS_IO_BASE)
+/* Relevant only for Orion-NAS */
+#define ORION_PCIE_WA_BASE	0xf0000000
+#define ORION_PCIE_WA_SIZE	SZ_16M
+
+/*******************************************************************************
+ * Supported Devices & Revisions
+ ******************************************************************************/
+/* Orion-1 (88F5181) */
+#define MV88F5181_DEV_ID	0x5181
+#define MV88F5181_REV_B1	3
+/* Orion-NAS (88F5182) */
+#define MV88F5182_DEV_ID	0x5182
+#define MV88F5182_REV_A2	2
+/* Orion-2 (88F5281) */
+#define MV88F5281_DEV_ID	0x5281
+#define MV88F5281_REV_D1	5
+#define MV88F5281_REV_D2	6
+
+/*******************************************************************************
+ * Orion Registers Map
+ ******************************************************************************/
+#define ORION_DDR_REG_BASE	(ORION_REGS_BASE | 0x00000)
+#define ORION_DEV_BUS_REG_BASE	(ORION_REGS_BASE | 0x10000)
+#define ORION_BRIDGE_REG_BASE	(ORION_REGS_BASE | 0x20000)
+#define ORION_PCI_REG_BASE	(ORION_REGS_BASE | 0x30000)
+#define ORION_PCIE_REG_BASE	(ORION_REGS_BASE | 0x40000)
+#define ORION_USB0_REG_BASE	(ORION_REGS_BASE | 0x50000)
+#define ORION_ETH_REG_BASE	(ORION_REGS_BASE | 0x70000)
+#define ORION_SATA_REG_BASE	(ORION_REGS_BASE | 0x80000)
+#define ORION_USB1_REG_BASE	(ORION_REGS_BASE | 0xa0000)
+
+#define ORION_DDR_REG(x)	(ORION_DDR_REG_BASE | (x))
+#define ORION_DEV_BUS_REG(x)	(ORION_DEV_BUS_REG_BASE | (x))
+#define ORION_BRIDGE_REG(x)	(ORION_BRIDGE_REG_BASE | (x))
+#define ORION_PCI_REG(x)	(ORION_PCI_REG_BASE | (x))
+#define ORION_PCIE_REG(x)	(ORION_PCIE_REG_BASE | (x))
+#define ORION_USB0_REG(x)	(ORION_USB0_REG_BASE | (x))
+#define ORION_USB1_REG(x)	(ORION_USB1_REG_BASE | (x))
+#define ORION_ETH_REG(x)	(ORION_ETH_REG_BASE | (x))
+#define ORION_SATA_REG(x)	(ORION_SATA_REG_BASE | (x))
+
+/*******************************************************************************
+ * Device Bus Registers
+ ******************************************************************************/
+#define MPP_0_7_CTRL		ORION_DEV_BUS_REG(0x000)
+#define MPP_8_15_CTRL		ORION_DEV_BUS_REG(0x004)
+#define MPP_16_19_CTRL		ORION_DEV_BUS_REG(0x050)
+#define MPP_DEV_CTRL		ORION_DEV_BUS_REG(0x008)
+#define MPP_RESET_SAMPLE	ORION_DEV_BUS_REG(0x010)
+#define GPIO_OUT		ORION_DEV_BUS_REG(0x100)
+#define GPIO_IO_CONF		ORION_DEV_BUS_REG(0x104)
+#define GPIO_BLINK_EN		ORION_DEV_BUS_REG(0x108)
+#define GPIO_IN_POL		ORION_DEV_BUS_REG(0x10c)
+#define GPIO_DATA_IN		ORION_DEV_BUS_REG(0x110)
+#define GPIO_EDGE_CAUSE		ORION_DEV_BUS_REG(0x114)
+#define GPIO_EDGE_MASK		ORION_DEV_BUS_REG(0x118)
+#define GPIO_LEVEL_MASK		ORION_DEV_BUS_REG(0x11c)
+#define DEV_BANK_0_PARAM	ORION_DEV_BUS_REG(0x45c)
+#define DEV_BANK_1_PARAM	ORION_DEV_BUS_REG(0x460)
+#define DEV_BANK_2_PARAM	ORION_DEV_BUS_REG(0x464)
+#define DEV_BANK_BOOT_PARAM	ORION_DEV_BUS_REG(0x46c)
+#define DEV_BUS_CTRL		ORION_DEV_BUS_REG(0x4c0)
+#define DEV_BUS_INT_CAUSE	ORION_DEV_BUS_REG(0x4d0)
+#define DEV_BUS_INT_MASK	ORION_DEV_BUS_REG(0x4d4)
+#define I2C_BASE		ORION_DEV_BUS_REG(0x1000)
+#define UART0_BASE		ORION_DEV_BUS_REG(0x2000)
+#define UART1_BASE		ORION_DEV_BUS_REG(0x2100)
+#define GPIO_MAX		32
+
+/***************************************************************************
+ * Orion CPU Bridge Registers
+ **************************************************************************/
+#define CPU_CONF		ORION_BRIDGE_REG(0x100)
+#define CPU_CTRL		ORION_BRIDGE_REG(0x104)
+#define CPU_RESET_MASK		ORION_BRIDGE_REG(0x108)
+#define CPU_SOFT_RESET		ORION_BRIDGE_REG(0x10c)
+#define POWER_MNG_CTRL_REG	ORION_BRIDGE_REG(0x11C)
+#define BRIDGE_CAUSE		ORION_BRIDGE_REG(0x110)
+#define BRIDGE_MASK		ORION_BRIDGE_REG(0x114)
+#define MAIN_IRQ_CAUSE		ORION_BRIDGE_REG(0x200)
+#define MAIN_IRQ_MASK		ORION_BRIDGE_REG(0x204)
+#define TIMER_CTRL		ORION_BRIDGE_REG(0x300)
+#define TIMER_VAL(x)		ORION_BRIDGE_REG(0x314 + ((x) * 8))
+#define TIMER_VAL_RELOAD(x)	ORION_BRIDGE_REG(0x310 + ((x) * 8))
+
+#ifndef __ASSEMBLY__
+
+/*******************************************************************************
+ * Helpers to access Orion registers
+ ******************************************************************************/
+#include <asm/types.h>
+#include <asm/io.h>
+
+#define orion_read(r)		__raw_readl(r)
+#define orion_write(r, val)	__raw_writel(val, r)
+
+/*
+ * These are not preempt safe. Locks, if needed, must be taken care by caller.
+ */
+#define orion_setbits(r, mask)	orion_write((r), orion_read(r) | (mask))
+#define orion_clrbits(r, mask)	orion_write((r), orion_read(r) & ~(mask))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_ARCH_ORION_H__ */
diff --git a/include/asm-arm/arch-orion/platform.h b/include/asm-arm/arch-orion/platform.h
new file mode 100644
index 0000000..143c38e
--- /dev/null
+++ b/include/asm-arm/arch-orion/platform.h
@@ -0,0 +1,25 @@
+/*
+ * asm-arm/arch-orion/platform.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_PLATFORM_H__
+#define __ASM_ARCH_PLATFORM_H__
+
+/*
+ * Device bus NAND private data
+ */
+struct orion_nand_data {
+	struct mtd_partition *parts;
+	u32 nr_parts;
+	u8 ale;		/* address line number connected to ALE */
+	u8 cle;		/* address line number connected to CLE */
+	u8 width;	/* buswidth */
+};
+
+#endif
diff --git a/include/asm-arm/arch-orion/system.h b/include/asm-arm/arch-orion/system.h
new file mode 100644
index 0000000..17704c6
--- /dev/null
+++ b/include/asm-arm/arch-orion/system.h
@@ -0,0 +1,31 @@
+/*
+ * include/asm-arm/arch-orion/system.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/orion.h>
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	/*
+	 * Enable and issue soft reset
+	 */
+	orion_setbits(CPU_RESET_MASK, (1 << 2));
+	orion_setbits(CPU_SOFT_RESET, 1);
+}
+
+#endif
diff --git a/include/asm-arm/arch-orion/timex.h b/include/asm-arm/arch-orion/timex.h
new file mode 100644
index 0000000..26c2c91
--- /dev/null
+++ b/include/asm-arm/arch-orion/timex.h
@@ -0,0 +1,12 @@
+/*
+ * include/asm-arm/arch-orion/timex.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define ORION_TCLK		166666667
+#define CLOCK_TICK_RATE		ORION_TCLK
diff --git a/include/asm-arm/arch-orion/uncompress.h b/include/asm-arm/arch-orion/uncompress.h
new file mode 100644
index 0000000..a1a222f
--- /dev/null
+++ b/include/asm-arm/arch-orion/uncompress.h
@@ -0,0 +1,44 @@
+/*
+ * include/asm-arm/arch-orion/uncompress.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/arch/orion.h>
+
+#define MV_UART_LSR 	((volatile unsigned char *)(UART0_BASE + 0x14))
+#define MV_UART_THR	((volatile unsigned char *)(UART0_BASE + 0x0))
+
+#define LSR_THRE	0x20
+
+static void putc(const char c)
+{
+	int j = 0x1000;
+	while (--j && !(*MV_UART_LSR & LSR_THRE))
+		barrier();
+	*MV_UART_THR = c;
+}
+
+static void flush(void)
+{
+}
+
+static void orion_early_putstr(const char *ptr)
+{
+	char c;
+	while ((c = *ptr++) != '\0') {
+		if (c == '\n')
+			putc('\r');
+		putc(c);
+	}
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-orion/vmalloc.h b/include/asm-arm/arch-orion/vmalloc.h
new file mode 100644
index 0000000..23e2a10
--- /dev/null
+++ b/include/asm-arm/arch-orion/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * include/asm-arm/arch-orion/vmalloc.h
+ */
+
+#define VMALLOC_END       0xf0000000
diff --git a/include/asm-arm/arch-pxa/colibri.h b/include/asm-arm/arch-pxa/colibri.h
new file mode 100644
index 0000000..2ae373f
--- /dev/null
+++ b/include/asm-arm/arch-pxa/colibri.h
@@ -0,0 +1,19 @@
+#ifndef _COLIBRI_H_
+#define _COLIBRI_H_
+
+/* physical memory regions */
+#define COLIBRI_FLASH_PHYS	(PXA_CS0_PHYS)  /* Flash region */
+#define COLIBRI_ETH_PHYS	(PXA_CS2_PHYS)  /* Ethernet DM9000 region */
+#define COLIBRI_SDRAM_BASE	0xa0000000      /* SDRAM region */
+
+/* virtual memory regions */
+#define COLIBRI_DISK_VIRT	0xF0000000	/* Disk On Chip region */
+
+/* size of flash */
+#define COLIBRI_FLASH_SIZE	0x02000000	/* Flash size 32 MB */
+
+/* Ethernet Controller Davicom DM9000 */
+#define GPIO_DM9000		114
+#define COLIBRI_ETH_IRQ	IRQ_GPIO(GPIO_DM9000)
+
+#endif /* _COLIBRI_H_ */
diff --git a/include/asm-arm/arch-pxa/corgi.h b/include/asm-arm/arch-pxa/corgi.h
index e554caa..bf85650 100644
--- a/include/asm-arm/arch-pxa/corgi.h
+++ b/include/asm-arm/arch-pxa/corgi.h
@@ -104,7 +104,6 @@
  */
 extern struct platform_device corgiscoop_device;
 extern struct platform_device corgissp_device;
-extern struct platform_device corgifb_device;
 
 #endif /* __ASM_ARCH_CORGI_H  */
 
diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h
index b76ee6d..c562b97 100644
--- a/include/asm-arm/arch-pxa/irqs.h
+++ b/include/asm-arm/arch-pxa/irqs.h
@@ -180,7 +180,8 @@
 #define NR_IRQS			(IRQ_LOCOMO_SPI_TEND + 1)
 #elif defined(CONFIG_ARCH_LUBBOCK) || \
       defined(CONFIG_MACH_LOGICPD_PXA270) || \
-      defined(CONFIG_MACH_MAINSTONE)
+      defined(CONFIG_MACH_MAINSTONE) || \
+      defined(CONFIG_MACH_PCM027)
 #define NR_IRQS			(IRQ_BOARD_END)
 #else
 #define NR_IRQS			(IRQ_BOARD_START)
@@ -227,6 +228,13 @@
 #define IRQ_LOCOMO_LT_BASE	(IRQ_BOARD_START + 2)
 #define IRQ_LOCOMO_SPI_BASE	(IRQ_BOARD_START + 3)
 
+/* phyCORE-PXA270 (PCM027) Interrupts */
+#define PCM027_IRQ(x)          (IRQ_BOARD_START + (x))
+#define PCM027_BTDET_IRQ       PCM027_IRQ(0)
+#define PCM027_FF_RI_IRQ       PCM027_IRQ(1)
+#define PCM027_MMCDET_IRQ      PCM027_IRQ(2)
+#define PCM027_PM_5V_IRQ       PCM027_IRQ(3)
+
 /* ITE8152 irqs */
 /* add IT8152 IRQs beyond BOARD_END */
 #ifdef CONFIG_PCI_HOST_ITE8152
diff --git a/include/asm-arm/arch-pxa/littleton.h b/include/asm-arm/arch-pxa/littleton.h
new file mode 100644
index 0000000..79d209b
--- /dev/null
+++ b/include/asm-arm/arch-pxa/littleton.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_ZYLONITE_H
+#define __ASM_ARCH_ZYLONITE_H
+
+#define LITTLETON_ETH_PHYS	0x30000000
+
+#endif /* __ASM_ARCH_ZYLONITE_H */
diff --git a/include/asm-arm/arch-pxa/magician.h b/include/asm-arm/arch-pxa/magician.h
new file mode 100644
index 0000000..337f51f
--- /dev/null
+++ b/include/asm-arm/arch-pxa/magician.h
@@ -0,0 +1,111 @@
+/*
+ * GPIO and IRQ definitions for HTC Magician PDA phones
+ *
+ * Copyright (c) 2007 Philipp Zabel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _MAGICIAN_H_
+#define _MAGICIAN_H_
+
+#include <asm/arch/pxa-regs.h>
+
+/*
+ * PXA GPIOs
+ */
+
+#define GPIO0_MAGICIAN_KEY_POWER		0
+#define GPIO9_MAGICIAN_UNKNOWN			9
+#define GPIO10_MAGICIAN_GSM_IRQ			10
+#define GPIO11_MAGICIAN_GSM_OUT1		11
+#define GPIO13_MAGICIAN_CPLD_IRQ		13
+#define GPIO18_MAGICIAN_UNKNOWN			18
+#define GPIO22_MAGICIAN_VIBRA_EN		22
+#define GPIO26_MAGICIAN_GSM_POWER		26
+#define GPIO27_MAGICIAN_USBC_PUEN		27
+#define GPIO30_MAGICIAN_nCHARGE_EN		30
+#define GPIO37_MAGICIAN_KEY_HANGUP		37
+#define GPIO38_MAGICIAN_KEY_CONTACTS		38
+#define GPIO40_MAGICIAN_GSM_OUT2		40
+#define GPIO48_MAGICIAN_UNKNOWN			48
+#define GPIO56_MAGICIAN_UNKNOWN			56
+#define GPIO57_MAGICIAN_CAM_RESET		57
+#define GPIO83_MAGICIAN_nIR_EN			83
+#define GPIO86_MAGICIAN_GSM_RESET		86
+#define GPIO87_MAGICIAN_GSM_SELECT		87
+#define GPIO90_MAGICIAN_KEY_CALENDAR		90
+#define GPIO91_MAGICIAN_KEY_CAMERA		91
+#define GPIO93_MAGICIAN_KEY_UP			93
+#define GPIO94_MAGICIAN_KEY_DOWN		94
+#define GPIO95_MAGICIAN_KEY_LEFT		95
+#define GPIO96_MAGICIAN_KEY_RIGHT		96
+#define GPIO97_MAGICIAN_KEY_ENTER		97
+#define GPIO98_MAGICIAN_KEY_RECORD		98
+#define GPIO99_MAGICIAN_HEADPHONE_IN		99
+#define GPIO100_MAGICIAN_KEY_VOL_UP		100
+#define GPIO101_MAGICIAN_KEY_VOL_DOWN 		101
+#define GPIO102_MAGICIAN_KEY_PHONE		102
+#define GPIO103_MAGICIAN_LED_KP			103
+#define GPIO104_MAGICIAN_LCD_POWER_1 		104
+#define GPIO105_MAGICIAN_LCD_POWER_2		105
+#define GPIO106_MAGICIAN_LCD_POWER_3		106
+#define GPIO107_MAGICIAN_DS1WM_IRQ		107
+#define GPIO108_MAGICIAN_GSM_READY		108
+#define GPIO114_MAGICIAN_UNKNOWN		114
+#define GPIO115_MAGICIAN_nPEN_IRQ		115
+#define GPIO116_MAGICIAN_nCAM_EN		116
+#define GPIO119_MAGICIAN_UNKNOWN		119
+#define GPIO120_MAGICIAN_UNKNOWN		120
+
+/*
+ * PXA GPIO alternate function mode & direction
+ */
+
+#define GPIO0_MAGICIAN_KEY_POWER_MD		(0 | GPIO_IN)
+#define GPIO9_MAGICIAN_UNKNOWN_MD		(9 | GPIO_IN)
+#define GPIO10_MAGICIAN_GSM_IRQ_MD		(10 | GPIO_IN)
+#define GPIO11_MAGICIAN_GSM_OUT1_MD		(11 | GPIO_OUT)
+#define GPIO13_MAGICIAN_CPLD_IRQ_MD		(13 | GPIO_IN)
+#define GPIO18_MAGICIAN_UNKNOWN_MD		(18 | GPIO_OUT)
+#define GPIO22_MAGICIAN_VIBRA_EN_MD		(22 | GPIO_OUT)
+#define GPIO26_MAGICIAN_GSM_POWER_MD		(26 | GPIO_OUT)
+#define GPIO27_MAGICIAN_USBC_PUEN_MD		(27 | GPIO_OUT)
+#define GPIO30_MAGICIAN_nCHARGE_EN_MD		(30 | GPIO_OUT)
+#define GPIO37_MAGICIAN_KEY_HANGUP_MD		(37 | GPIO_OUT)
+#define GPIO38_MAGICIAN_KEY_CONTACTS_MD		(38 | GPIO_OUT)
+#define GPIO40_MAGICIAN_GSM_OUT2_MD		(40 | GPIO_OUT)
+#define GPIO48_MAGICIAN_UNKNOWN_MD		(48 | GPIO_OUT)
+#define GPIO56_MAGICIAN_UNKNOWN_MD		(56 | GPIO_OUT)
+#define GPIO57_MAGICIAN_CAM_RESET_MD		(57 | GPIO_OUT)
+#define GPIO83_MAGICIAN_nIR_EN_MD		(83 | GPIO_OUT)
+#define GPIO86_MAGICIAN_GSM_RESET_MD		(86 | GPIO_OUT)
+#define GPIO87_MAGICIAN_GSM_SELECT_MD		(87 | GPIO_OUT)
+#define GPIO90_MAGICIAN_KEY_CALENDAR_MD		(90 | GPIO_OUT)
+#define GPIO91_MAGICIAN_KEY_CAMERA_MD		(91 | GPIO_OUT)
+#define GPIO93_MAGICIAN_KEY_UP_MD		(93 | GPIO_IN)
+#define GPIO94_MAGICIAN_KEY_DOWN_MD		(94 | GPIO_IN)
+#define GPIO95_MAGICIAN_KEY_LEFT_MD		(95 | GPIO_IN)
+#define GPIO96_MAGICIAN_KEY_RIGHT_MD		(96 | GPIO_IN)
+#define GPIO97_MAGICIAN_KEY_ENTER_MD		(97 | GPIO_IN)
+#define GPIO98_MAGICIAN_KEY_RECORD_MD		(98 | GPIO_IN)
+#define GPIO99_MAGICIAN_HEADPHONE_IN_MD		(99 | GPIO_IN)
+#define GPIO100_MAGICIAN_KEY_VOL_UP_MD		(100 | GPIO_IN)
+#define GPIO101_MAGICIAN_KEY_VOL_DOWN_MD 	(101 | GPIO_IN)
+#define GPIO102_MAGICIAN_KEY_PHONE_MD		(102 | GPIO_IN)
+#define GPIO103_MAGICIAN_LED_KP_MD		(103 | GPIO_OUT)
+#define GPIO104_MAGICIAN_LCD_POWER_1_MD 	(104 | GPIO_OUT)
+#define GPIO105_MAGICIAN_LCD_POWER_2_MD		(105 | GPIO_OUT)
+#define GPIO106_MAGICIAN_LCD_POWER_3_MD		(106 | GPIO_OUT)
+#define GPIO107_MAGICIAN_DS1WM_IRQ_MD		(107 | GPIO_IN)
+#define GPIO108_MAGICIAN_GSM_READY_MD		(108 | GPIO_IN)
+#define GPIO114_MAGICIAN_UNKNOWN_MD		(114 | GPIO_OUT)
+#define GPIO115_MAGICIAN_nPEN_IRQ_MD		(115 | GPIO_IN)
+#define GPIO116_MAGICIAN_nCAM_EN_MD		(116 | GPIO_OUT)
+#define GPIO119_MAGICIAN_UNKNOWN_MD		(119 | GPIO_OUT)
+#define GPIO120_MAGICIAN_UNKNOWN_MD		(120 | GPIO_OUT)
+
+#endif /* _MAGICIAN_H_ */
diff --git a/include/asm-arm/arch-pxa/mfp-pxa300.h b/include/asm-arm/arch-pxa/mfp-pxa300.h
index a209966..bb41031 100644
--- a/include/asm-arm/arch-pxa/mfp-pxa300.h
+++ b/include/asm-arm/arch-pxa/mfp-pxa300.h
@@ -16,6 +16,7 @@
 #define __ASM_ARCH_MFP_PXA300_H
 
 #include <asm/arch/mfp.h>
+#include <asm/arch/mfp-pxa3xx.h>
 
 /* GPIO */
 #define GPIO46_GPIO		MFP_CFG(GPIO46, AF1)
diff --git a/include/asm-arm/arch-pxa/mfp-pxa320.h b/include/asm-arm/arch-pxa/mfp-pxa320.h
index 52deedc..576aa46 100644
--- a/include/asm-arm/arch-pxa/mfp-pxa320.h
+++ b/include/asm-arm/arch-pxa/mfp-pxa320.h
@@ -16,6 +16,7 @@
 #define __ASM_ARCH_MFP_PXA320_H
 
 #include <asm/arch/mfp.h>
+#include <asm/arch/mfp-pxa3xx.h>
 
 /* GPIO */
 #define GPIO46_GPIO		MFP_CFG(GPIO46, AF0)
diff --git a/include/asm-arm/arch-pxa/mfp-pxa3xx.h b/include/asm-arm/arch-pxa/mfp-pxa3xx.h
new file mode 100644
index 0000000..1f6b35c
--- /dev/null
+++ b/include/asm-arm/arch-pxa/mfp-pxa3xx.h
@@ -0,0 +1,252 @@
+#ifndef __ASM_ARCH_MFP_PXA3XX_H
+#define __ASM_ARCH_MFP_PXA3XX_H
+
+#define MFPR_BASE	(0x40e10000)
+#define MFPR_SIZE	(PAGE_SIZE)
+
+/* MFPR register bit definitions */
+#define MFPR_PULL_SEL		(0x1 << 15)
+#define MFPR_PULLUP_EN		(0x1 << 14)
+#define MFPR_PULLDOWN_EN	(0x1 << 13)
+#define MFPR_SLEEP_SEL		(0x1 << 9)
+#define MFPR_SLEEP_OE_N		(0x1 << 7)
+#define MFPR_EDGE_CLEAR		(0x1 << 6)
+#define MFPR_EDGE_FALL_EN	(0x1 << 5)
+#define MFPR_EDGE_RISE_EN	(0x1 << 4)
+
+#define MFPR_SLEEP_DATA(x)	((x) << 8)
+#define MFPR_DRIVE(x)		(((x) & 0x7) << 10)
+#define MFPR_AF_SEL(x)		(((x) & 0x7) << 0)
+
+#define MFPR_EDGE_NONE		(0)
+#define MFPR_EDGE_RISE		(MFPR_EDGE_RISE_EN)
+#define MFPR_EDGE_FALL		(MFPR_EDGE_FALL_EN)
+#define MFPR_EDGE_BOTH		(MFPR_EDGE_RISE | MFPR_EDGE_FALL)
+
+/*
+ * Table that determines the low power modes outputs, with actual settings
+ * used in parentheses for don't-care values. Except for the float output,
+ * the configured driven and pulled levels match, so if there is a need for
+ * non-LPM pulled output, the same configuration could probably be used.
+ *
+ * Output value  sleep_oe_n  sleep_data  pullup_en  pulldown_en  pull_sel
+ *                 (bit 7)    (bit 8)    (bit 14)     (bit 13)   (bit 15)
+ *
+ * Input            0          X(0)        X(0)        X(0)       0
+ * Drive 0          0          0           0           X(1)       0
+ * Drive 1          0          1           X(1)        0	  0
+ * Pull hi (1)      1          X(1)        1           0	  0
+ * Pull lo (0)      1          X(0)        0           1	  0
+ * Z (float)        1          X(0)        0           0	  0
+ */
+#define MFPR_LPM_INPUT		(0)
+#define MFPR_LPM_DRIVE_LOW	(MFPR_SLEEP_DATA(0) | MFPR_PULLDOWN_EN)
+#define MFPR_LPM_DRIVE_HIGH    	(MFPR_SLEEP_DATA(1) | MFPR_PULLUP_EN)
+#define MFPR_LPM_PULL_LOW      	(MFPR_LPM_DRIVE_LOW  | MFPR_SLEEP_OE_N)
+#define MFPR_LPM_PULL_HIGH     	(MFPR_LPM_DRIVE_HIGH | MFPR_SLEEP_OE_N)
+#define MFPR_LPM_FLOAT         	(MFPR_SLEEP_OE_N)
+#define MFPR_LPM_MASK		(0xe080)
+
+/*
+ * The pullup and pulldown state of the MFP pin at run mode is by default
+ * determined by the selected alternate function. In case that some buggy
+ * devices need to override this default behavior,  the definitions below
+ * indicates the setting of corresponding MFPR bits
+ *
+ * Definition       pull_sel  pullup_en  pulldown_en
+ * MFPR_PULL_NONE       0         0        0
+ * MFPR_PULL_LOW        1         0        1
+ * MFPR_PULL_HIGH       1         1        0
+ * MFPR_PULL_BOTH       1         1        1
+ */
+#define MFPR_PULL_NONE		(0)
+#define MFPR_PULL_LOW		(MFPR_PULL_SEL | MFPR_PULLDOWN_EN)
+#define MFPR_PULL_BOTH		(MFPR_PULL_LOW | MFPR_PULLUP_EN)
+#define MFPR_PULL_HIGH		(MFPR_PULL_SEL | MFPR_PULLUP_EN)
+
+/* PXA3xx common MFP configurations - processor specific ones defined
+ * in mfp-pxa300.h and mfp-pxa320.h
+ */
+#define GPIO0_GPIO		MFP_CFG(GPIO0, AF0)
+#define GPIO1_GPIO		MFP_CFG(GPIO1, AF0)
+#define GPIO2_GPIO		MFP_CFG(GPIO2, AF0)
+#define GPIO3_GPIO		MFP_CFG(GPIO3, AF0)
+#define GPIO4_GPIO		MFP_CFG(GPIO4, AF0)
+#define GPIO5_GPIO		MFP_CFG(GPIO5, AF0)
+#define GPIO6_GPIO		MFP_CFG(GPIO6, AF0)
+#define GPIO7_GPIO		MFP_CFG(GPIO7, AF0)
+#define GPIO8_GPIO		MFP_CFG(GPIO8, AF0)
+#define GPIO9_GPIO		MFP_CFG(GPIO9, AF0)
+#define GPIO10_GPIO		MFP_CFG(GPIO10, AF0)
+#define GPIO11_GPIO		MFP_CFG(GPIO11, AF0)
+#define GPIO12_GPIO		MFP_CFG(GPIO12, AF0)
+#define GPIO13_GPIO		MFP_CFG(GPIO13, AF0)
+#define GPIO14_GPIO		MFP_CFG(GPIO14, AF0)
+#define GPIO15_GPIO		MFP_CFG(GPIO15, AF0)
+#define GPIO16_GPIO		MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO		MFP_CFG(GPIO17, AF0)
+#define GPIO18_GPIO		MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO		MFP_CFG(GPIO19, AF0)
+#define GPIO20_GPIO		MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO		MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO		MFP_CFG(GPIO22, AF0)
+#define GPIO23_GPIO		MFP_CFG(GPIO23, AF0)
+#define GPIO24_GPIO		MFP_CFG(GPIO24, AF0)
+#define GPIO25_GPIO		MFP_CFG(GPIO25, AF0)
+#define GPIO26_GPIO		MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO		MFP_CFG(GPIO27, AF0)
+#define GPIO28_GPIO		MFP_CFG(GPIO28, AF0)
+#define GPIO29_GPIO		MFP_CFG(GPIO29, AF0)
+#define GPIO30_GPIO		MFP_CFG(GPIO30, AF0)
+#define GPIO31_GPIO		MFP_CFG(GPIO31, AF0)
+#define GPIO32_GPIO		MFP_CFG(GPIO32, AF0)
+#define GPIO33_GPIO		MFP_CFG(GPIO33, AF0)
+#define GPIO34_GPIO		MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO		MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO		MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO		MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO		MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO		MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO		MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO		MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO		MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO		MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO		MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO		MFP_CFG(GPIO45, AF0)
+
+#define GPIO47_GPIO		MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO		MFP_CFG(GPIO48, AF0)
+
+#define GPIO53_GPIO		MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO		MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO		MFP_CFG(GPIO55, AF0)
+
+#define GPIO57_GPIO		MFP_CFG(GPIO57, AF0)
+
+#define GPIO63_GPIO		MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO		MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO		MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO		MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO		MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO		MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO		MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO		MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO		MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO		MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO		MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO		MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO		MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO		MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO		MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO		MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO		MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO		MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO		MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO		MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO		MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO		MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO		MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO		MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO		MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO		MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO		MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO		MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO		MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO		MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO		MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO		MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO		MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO		MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO		MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO		MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO		MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO		MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO		MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO		MFP_CFG(GPIO102, AF0)
+#define GPIO103_GPIO		MFP_CFG(GPIO103, AF0)
+#define GPIO104_GPIO		MFP_CFG(GPIO104, AF0)
+#define GPIO105_GPIO		MFP_CFG(GPIO105, AF0)
+#define GPIO106_GPIO		MFP_CFG(GPIO106, AF0)
+#define GPIO107_GPIO		MFP_CFG(GPIO107, AF0)
+#define GPIO108_GPIO		MFP_CFG(GPIO108, AF0)
+#define GPIO109_GPIO		MFP_CFG(GPIO109, AF0)
+#define GPIO110_GPIO		MFP_CFG(GPIO110, AF0)
+#define GPIO111_GPIO		MFP_CFG(GPIO111, AF0)
+#define GPIO112_GPIO		MFP_CFG(GPIO112, AF0)
+#define GPIO113_GPIO		MFP_CFG(GPIO113, AF0)
+#define GPIO114_GPIO		MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO		MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO		MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO		MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO		MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO		MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO		MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO		MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO		MFP_CFG(GPIO122, AF0)
+#define GPIO123_GPIO		MFP_CFG(GPIO123, AF0)
+#define GPIO124_GPIO		MFP_CFG(GPIO124, AF0)
+#define GPIO125_GPIO		MFP_CFG(GPIO125, AF0)
+#define GPIO126_GPIO		MFP_CFG(GPIO126, AF0)
+#define GPIO127_GPIO		MFP_CFG(GPIO127, AF0)
+
+#define GPIO0_2_GPIO		MFP_CFG(GPIO0_2, AF0)
+#define GPIO1_2_GPIO		MFP_CFG(GPIO1_2, AF0)
+#define GPIO2_2_GPIO		MFP_CFG(GPIO2_2, AF0)
+#define GPIO3_2_GPIO		MFP_CFG(GPIO3_2, AF0)
+#define GPIO4_2_GPIO		MFP_CFG(GPIO4_2, AF0)
+#define GPIO5_2_GPIO		MFP_CFG(GPIO5_2, AF0)
+#define GPIO6_2_GPIO		MFP_CFG(GPIO6_2, AF0)
+
+/*
+ * each MFP pin will have a MFPR register, since the offset of the
+ * register varies between processors, the processor specific code
+ * should initialize the pin offsets by pxa3xx_mfp_init_addr()
+ *
+ * pxa3xx_mfp_init_addr - accepts a table of "pxa3xx_mfp_addr_map"
+ * structure, which represents a range of MFP pins from "start" to
+ * "end", with the offset begining at "offset", to define a single
+ * pin, let "end" = -1
+ *
+ * use
+ *
+ * MFP_ADDR_X() to define a range of pins
+ * MFP_ADDR()   to define a single pin
+ * MFP_ADDR_END to signal the end of pin offset definitions
+ */
+struct pxa3xx_mfp_addr_map {
+	unsigned int	start;
+	unsigned int	end;
+	unsigned long	offset;
+};
+
+#define MFP_ADDR_X(start, end, offset) \
+	{ MFP_PIN_##start, MFP_PIN_##end, offset }
+
+#define MFP_ADDR(pin, offset) \
+	{ MFP_PIN_##pin, -1, offset }
+
+#define MFP_ADDR_END	{ MFP_PIN_INVALID, 0 }
+
+/*
+ * pxa3xx_mfp_read()/pxa3xx_mfp_write() - for direct read/write access
+ * to the MFPR register
+ */
+unsigned long pxa3xx_mfp_read(int mfp);
+void pxa3xx_mfp_write(int mfp, unsigned long mfpr_val);
+
+/*
+ * pxa3xx_mfp_config - configure the MFPR registers
+ *
+ * used by board specific initialization code
+ */
+void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num);
+
+/*
+ * pxa3xx_mfp_init_addr() - initialize the mapping between mfp pin
+ * index and MFPR register offset
+ *
+ * used by processor specific code
+ */
+void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *);
+void __init pxa3xx_init_mfp(void);
+#endif /* __ASM_ARCH_MFP_PXA3XX_H */
diff --git a/include/asm-arm/arch-pxa/mfp.h b/include/asm-arm/arch-pxa/mfp.h
index 03c508d..02f6157 100644
--- a/include/asm-arm/arch-pxa/mfp.h
+++ b/include/asm-arm/arch-pxa/mfp.h
@@ -16,9 +16,6 @@
 #ifndef __ASM_ARCH_MFP_H
 #define __ASM_ARCH_MFP_H
 
-#define MFPR_BASE	(0x40e10000)
-#define MFPR_SIZE	(PAGE_SIZE)
-
 #define mfp_to_gpio(m)	((m) % 128)
 
 /* list of all the configurable MFP pins */
@@ -217,114 +214,21 @@
 };
 
 /*
- * Table that determines the low power modes outputs, with actual settings
- * used in parentheses for don't-care values. Except for the float output,
- * the configured driven and pulled levels match, so if there is a need for
- * non-LPM pulled output, the same configuration could probably be used.
- *
- * Output value  sleep_oe_n  sleep_data  pullup_en  pulldown_en  pull_sel
- *                 (bit 7)    (bit 8)    (bit 14d)   (bit 13d)
- *
- * Drive 0          0          0           0           X (1)      0
- * Drive 1          0          1           X (1)       0	  0
- * Pull hi (1)      1          X(1)        1           0	  0
- * Pull lo (0)      1          X(0)        0           1	  0
- * Z (float)        1          X(0)        0           0	  0
- */
-#define MFP_LPM_DRIVE_LOW	0x8
-#define MFP_LPM_DRIVE_HIGH    	0x6
-#define MFP_LPM_PULL_HIGH     	0x7
-#define MFP_LPM_PULL_LOW      	0x9
-#define MFP_LPM_FLOAT         	0x1
-#define MFP_LPM_PULL_NEITHER	0x0
-
-/*
- * The pullup and pulldown state of the MFP pin is by default determined by
- * selected alternate function. In case some buggy devices need to override
- * this default behavior,  pxa3xx_mfp_set_pull() can be invoked with one of
- * the following definition as the parameter.
- *
- * Definition       pull_sel  pullup_en  pulldown_en
- * MFP_PULL_HIGH        1         1        0
- * MFP_PULL_LOW         1         0        1
- * MFP_PULL_BOTH        1         1        1
- * MFP_PULL_NONE        1         0        0
- * MFP_PULL_DEFAULT     0         X        X
- *
- * NOTE: pxa3xx_mfp_set_pull() will modify the PULLUP_EN and PULLDOWN_EN
- * bits,  which will cause potential conflicts with the low power mode
- * setting, device drivers should take care of this
- */
-#define MFP_PULL_BOTH		(0x7u)
-#define MFP_PULL_HIGH		(0x6u)
-#define MFP_PULL_LOW		(0x5u)
-#define MFP_PULL_NONE		(0x4u)
-#define MFP_PULL_DEFAULT	(0x0u)
-
-#define MFP_AF0			(0)
-#define MFP_AF1			(1)
-#define MFP_AF2			(2)
-#define MFP_AF3			(3)
-#define MFP_AF4			(4)
-#define MFP_AF5			(5)
-#define MFP_AF6			(6)
-#define MFP_AF7			(7)
-
-#define MFP_DS01X		(0)
-#define MFP_DS02X		(1)
-#define MFP_DS03X		(2)
-#define MFP_DS04X		(3)
-#define MFP_DS06X		(4)
-#define MFP_DS08X		(5)
-#define MFP_DS10X		(6)
-#define MFP_DS12X		(7)
-
-#define MFP_EDGE_BOTH		0x3
-#define MFP_EDGE_RISE		0x2
-#define MFP_EDGE_FALL		0x1
-#define MFP_EDGE_NONE		0x0
-
-#define MFPR_AF_MASK		0x0007
-#define MFPR_DRV_MASK		0x1c00
-#define MFPR_RDH_MASK		0x0200
-#define MFPR_LPM_MASK		0xe180
-#define MFPR_PULL_MASK		0xe000
-#define MFPR_EDGE_MASK		0x0070
-
-#define MFPR_ALT_OFFSET		0
-#define MFPR_ERE_OFFSET		4
-#define MFPR_EFE_OFFSET		5
-#define MFPR_EC_OFFSET		6
-#define MFPR_SON_OFFSET		7
-#define MFPR_SD_OFFSET		8
-#define MFPR_SS_OFFSET		9
-#define MFPR_DRV_OFFSET		10
-#define MFPR_PD_OFFSET		13
-#define MFPR_PU_OFFSET		14
-#define MFPR_PS_OFFSET		15
-
-#define MFPR(af, drv, rdh, lpm, edge) \
-	(((af) & 0x7) | (((drv) & 0x7) << 10) |\
-	 (((rdh) & 0x1) << 9) |\
-	 (((lpm) & 0x3) << 7) |\
-	 (((lpm) & 0x4) << 12)|\
-	 (((lpm) & 0x8) << 10)|\
-	 ((!(edge)) << 6) |\
-	 (((edge) & 0x1) << 5) |\
-	 (((edge) & 0x2) << 3))
-
-/*
  * a possible MFP configuration is represented by a 32-bit integer
- * bit  0..15 - MFPR value (16-bit)
- * bit 16..31 - mfp pin index (used to obtain the MFPR offset)
+ *
+ * bit  0.. 9 - MFP Pin Number (1024 Pins Maximum)
+ * bit 10..12 - Alternate Function Selection
+ * bit 13..15 - Drive Strength
+ * bit 16..18 - Low Power Mode State
+ * bit 19..20 - Low Power Mode Edge Detection
+ * bit 21..22 - Run Mode Pull State
  *
  * to facilitate the definition, the following macros are provided
  *
- * MFPR_DEFAULT - default MFPR value, with
+ * MFP_CFG_DEFAULT - default MFP configuration value, with
  * 		  alternate function = 0,
- * 		  drive strength = fast 1mA (MFP_DS01X)
+ * 		  drive strength = fast 3mA (MFP_DS03X)
  * 		  low power mode = default
- * 		  release dalay hold = false (RDH bit)
  * 		  edge detection = none
  *
  * MFP_CFG	- default MFPR value with alternate function
@@ -334,251 +238,74 @@
  * 		  low power mode
  * MFP_CFG_X	- default MFPR value with alternate function,
  * 		  pin drive strength and low power mode
- *
- * use
- *
- * MFP_CFG_PIN	- to get the MFP pin index
- * MFP_CFG_VAL	- to get the corresponding MFPR value
  */
 
-typedef uint32_t mfp_cfg_t;
+typedef unsigned long mfp_cfg_t;
 
-#define MFP_CFG_PIN(mfp_cfg)	(((mfp_cfg) >> 16) & 0xffff)
-#define MFP_CFG_VAL(mfp_cfg)	((mfp_cfg) & 0xffff)
+#define MFP_PIN(x)		((x) & 0x3ff)
 
-/*
- * MFP register defaults to
- *   drive strength fast 3mA (010'b)
- *   edge detection logic disabled
- *   alternate function 0
- */
-#define MFPR_DEFAULT	(0x0840)
+#define MFP_AF0			(0x0 << 10)
+#define MFP_AF1			(0x1 << 10)
+#define MFP_AF2			(0x2 << 10)
+#define MFP_AF3			(0x3 << 10)
+#define MFP_AF4			(0x4 << 10)
+#define MFP_AF5			(0x5 << 10)
+#define MFP_AF6			(0x6 << 10)
+#define MFP_AF7			(0x7 << 10)
+#define MFP_AF_MASK		(0x7 << 10)
+#define MFP_AF(x)		(((x) >> 10) & 0x7)
+
+#define MFP_DS01X		(0x0 << 13)
+#define MFP_DS02X		(0x1 << 13)
+#define MFP_DS03X		(0x2 << 13)
+#define MFP_DS04X		(0x3 << 13)
+#define MFP_DS06X		(0x4 << 13)
+#define MFP_DS08X		(0x5 << 13)
+#define MFP_DS10X		(0x6 << 13)
+#define MFP_DS13X		(0x7 << 13)
+#define MFP_DS_MASK		(0x7 << 13)
+#define MFP_DS(x)		(((x) >> 13) & 0x7)
+
+#define MFP_LPM_INPUT		(0x0 << 16)
+#define MFP_LPM_DRIVE_LOW	(0x1 << 16)
+#define MFP_LPM_DRIVE_HIGH	(0x2 << 16)
+#define MFP_LPM_PULL_LOW	(0x3 << 16)
+#define MFP_LPM_PULL_HIGH	(0x4 << 16)
+#define MFP_LPM_FLOAT		(0x5 << 16)
+#define MFP_LPM_STATE_MASK	(0x7 << 16)
+#define MFP_LPM_STATE(x)	(((x) >> 16) & 0x7)
+
+#define MFP_LPM_EDGE_NONE	(0x0 << 19)
+#define MFP_LPM_EDGE_RISE	(0x1 << 19)
+#define MFP_LPM_EDGE_FALL	(0x2 << 19)
+#define MFP_LPM_EDGE_BOTH	(0x3 << 19)
+#define MFP_LPM_EDGE_MASK	(0x3 << 19)
+#define MFP_LPM_EDGE(x)		(((x) >> 19) & 0x3)
+
+#define MFP_PULL_NONE		(0x0 << 21)
+#define MFP_PULL_LOW		(0x1 << 21)
+#define MFP_PULL_HIGH		(0x2 << 21)
+#define MFP_PULL_BOTH		(0x3 << 21)
+#define MFP_PULL_MASK		(0x3 << 21)
+#define MFP_PULL(x)		(((x) >> 21) & 0x3)
+
+#define MFP_CFG_DEFAULT		(MFP_AF0 | MFP_DS03X | MFP_LPM_INPUT |\
+				 MFP_LPM_EDGE_NONE | MFP_PULL_NONE)
 
 #define MFP_CFG(pin, af)		\
-	((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af))
+	((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af))
 
 #define MFP_CFG_DRV(pin, af, drv)	\
-	((MFP_PIN_##pin << 16) | (MFPR_DEFAULT & ~MFPR_DRV_MASK) |\
-	 ((MFP_##drv) << 10) | (MFP_##af))
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK)) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv))
 
 #define MFP_CFG_LPM(pin, af, lpm)	\
-	((MFP_PIN_##pin << 16) | (MFPR_DEFAULT & ~MFPR_LPM_MASK) |\
-	 (((MFP_LPM_##lpm) & 0x3) << 7)  |\
-	 (((MFP_LPM_##lpm) & 0x4) << 12) |\
-	 (((MFP_LPM_##lpm) & 0x8) << 10) |\
-	 (MFP_##af))
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_LPM_STATE_MASK)) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_LPM_##lpm))
 
 #define MFP_CFG_X(pin, af, drv, lpm)	\
-	((MFP_PIN_##pin << 16) |\
-	 (MFPR_DEFAULT & ~(MFPR_DRV_MASK | MFPR_LPM_MASK)) |\
-	 ((MFP_##drv) << 10) | (MFP_##af) |\
-	 (((MFP_LPM_##lpm) & 0x3) << 7)  |\
-	 (((MFP_LPM_##lpm) & 0x4) << 12) |\
-	 (((MFP_LPM_##lpm) & 0x8) << 10))
-
-/* common MFP configurations - processor specific ones defined
- * in mfp-pxa3xx.h
- */
-#define GPIO0_GPIO		MFP_CFG(GPIO0, AF0)
-#define GPIO1_GPIO		MFP_CFG(GPIO1, AF0)
-#define GPIO2_GPIO		MFP_CFG(GPIO2, AF0)
-#define GPIO3_GPIO		MFP_CFG(GPIO3, AF0)
-#define GPIO4_GPIO		MFP_CFG(GPIO4, AF0)
-#define GPIO5_GPIO		MFP_CFG(GPIO5, AF0)
-#define GPIO6_GPIO		MFP_CFG(GPIO6, AF0)
-#define GPIO7_GPIO		MFP_CFG(GPIO7, AF0)
-#define GPIO8_GPIO		MFP_CFG(GPIO8, AF0)
-#define GPIO9_GPIO		MFP_CFG(GPIO9, AF0)
-#define GPIO10_GPIO		MFP_CFG(GPIO10, AF0)
-#define GPIO11_GPIO		MFP_CFG(GPIO11, AF0)
-#define GPIO12_GPIO		MFP_CFG(GPIO12, AF0)
-#define GPIO13_GPIO		MFP_CFG(GPIO13, AF0)
-#define GPIO14_GPIO		MFP_CFG(GPIO14, AF0)
-#define GPIO15_GPIO		MFP_CFG(GPIO15, AF0)
-#define GPIO16_GPIO		MFP_CFG(GPIO16, AF0)
-#define GPIO17_GPIO		MFP_CFG(GPIO17, AF0)
-#define GPIO18_GPIO		MFP_CFG(GPIO18, AF0)
-#define GPIO19_GPIO		MFP_CFG(GPIO19, AF0)
-#define GPIO20_GPIO		MFP_CFG(GPIO20, AF0)
-#define GPIO21_GPIO		MFP_CFG(GPIO21, AF0)
-#define GPIO22_GPIO		MFP_CFG(GPIO22, AF0)
-#define GPIO23_GPIO		MFP_CFG(GPIO23, AF0)
-#define GPIO24_GPIO		MFP_CFG(GPIO24, AF0)
-#define GPIO25_GPIO		MFP_CFG(GPIO25, AF0)
-#define GPIO26_GPIO		MFP_CFG(GPIO26, AF0)
-#define GPIO27_GPIO		MFP_CFG(GPIO27, AF0)
-#define GPIO28_GPIO		MFP_CFG(GPIO28, AF0)
-#define GPIO29_GPIO		MFP_CFG(GPIO29, AF0)
-#define GPIO30_GPIO		MFP_CFG(GPIO30, AF0)
-#define GPIO31_GPIO		MFP_CFG(GPIO31, AF0)
-#define GPIO32_GPIO		MFP_CFG(GPIO32, AF0)
-#define GPIO33_GPIO		MFP_CFG(GPIO33, AF0)
-#define GPIO34_GPIO		MFP_CFG(GPIO34, AF0)
-#define GPIO35_GPIO		MFP_CFG(GPIO35, AF0)
-#define GPIO36_GPIO		MFP_CFG(GPIO36, AF0)
-#define GPIO37_GPIO		MFP_CFG(GPIO37, AF0)
-#define GPIO38_GPIO		MFP_CFG(GPIO38, AF0)
-#define GPIO39_GPIO		MFP_CFG(GPIO39, AF0)
-#define GPIO40_GPIO		MFP_CFG(GPIO40, AF0)
-#define GPIO41_GPIO		MFP_CFG(GPIO41, AF0)
-#define GPIO42_GPIO		MFP_CFG(GPIO42, AF0)
-#define GPIO43_GPIO		MFP_CFG(GPIO43, AF0)
-#define GPIO44_GPIO		MFP_CFG(GPIO44, AF0)
-#define GPIO45_GPIO		MFP_CFG(GPIO45, AF0)
-
-#define GPIO47_GPIO		MFP_CFG(GPIO47, AF0)
-#define GPIO48_GPIO		MFP_CFG(GPIO48, AF0)
-
-#define GPIO53_GPIO		MFP_CFG(GPIO53, AF0)
-#define GPIO54_GPIO		MFP_CFG(GPIO54, AF0)
-#define GPIO55_GPIO		MFP_CFG(GPIO55, AF0)
-
-#define GPIO57_GPIO		MFP_CFG(GPIO57, AF0)
-
-#define GPIO63_GPIO		MFP_CFG(GPIO63, AF0)
-#define GPIO64_GPIO		MFP_CFG(GPIO64, AF0)
-#define GPIO65_GPIO		MFP_CFG(GPIO65, AF0)
-#define GPIO66_GPIO		MFP_CFG(GPIO66, AF0)
-#define GPIO67_GPIO		MFP_CFG(GPIO67, AF0)
-#define GPIO68_GPIO		MFP_CFG(GPIO68, AF0)
-#define GPIO69_GPIO		MFP_CFG(GPIO69, AF0)
-#define GPIO70_GPIO		MFP_CFG(GPIO70, AF0)
-#define GPIO71_GPIO		MFP_CFG(GPIO71, AF0)
-#define GPIO72_GPIO		MFP_CFG(GPIO72, AF0)
-#define GPIO73_GPIO		MFP_CFG(GPIO73, AF0)
-#define GPIO74_GPIO		MFP_CFG(GPIO74, AF0)
-#define GPIO75_GPIO		MFP_CFG(GPIO75, AF0)
-#define GPIO76_GPIO		MFP_CFG(GPIO76, AF0)
-#define GPIO77_GPIO		MFP_CFG(GPIO77, AF0)
-#define GPIO78_GPIO		MFP_CFG(GPIO78, AF0)
-#define GPIO79_GPIO		MFP_CFG(GPIO79, AF0)
-#define GPIO80_GPIO		MFP_CFG(GPIO80, AF0)
-#define GPIO81_GPIO		MFP_CFG(GPIO81, AF0)
-#define GPIO82_GPIO		MFP_CFG(GPIO82, AF0)
-#define GPIO83_GPIO		MFP_CFG(GPIO83, AF0)
-#define GPIO84_GPIO		MFP_CFG(GPIO84, AF0)
-#define GPIO85_GPIO		MFP_CFG(GPIO85, AF0)
-#define GPIO86_GPIO		MFP_CFG(GPIO86, AF0)
-#define GPIO87_GPIO		MFP_CFG(GPIO87, AF0)
-#define GPIO88_GPIO		MFP_CFG(GPIO88, AF0)
-#define GPIO89_GPIO		MFP_CFG(GPIO89, AF0)
-#define GPIO90_GPIO		MFP_CFG(GPIO90, AF0)
-#define GPIO91_GPIO		MFP_CFG(GPIO91, AF0)
-#define GPIO92_GPIO		MFP_CFG(GPIO92, AF0)
-#define GPIO93_GPIO		MFP_CFG(GPIO93, AF0)
-#define GPIO94_GPIO		MFP_CFG(GPIO94, AF0)
-#define GPIO95_GPIO		MFP_CFG(GPIO95, AF0)
-#define GPIO96_GPIO		MFP_CFG(GPIO96, AF0)
-#define GPIO97_GPIO		MFP_CFG(GPIO97, AF0)
-#define GPIO98_GPIO		MFP_CFG(GPIO98, AF0)
-#define GPIO99_GPIO		MFP_CFG(GPIO99, AF0)
-#define GPIO100_GPIO		MFP_CFG(GPIO100, AF0)
-#define GPIO101_GPIO		MFP_CFG(GPIO101, AF0)
-#define GPIO102_GPIO		MFP_CFG(GPIO102, AF0)
-#define GPIO103_GPIO		MFP_CFG(GPIO103, AF0)
-#define GPIO104_GPIO		MFP_CFG(GPIO104, AF0)
-#define GPIO105_GPIO		MFP_CFG(GPIO105, AF0)
-#define GPIO106_GPIO		MFP_CFG(GPIO106, AF0)
-#define GPIO107_GPIO		MFP_CFG(GPIO107, AF0)
-#define GPIO108_GPIO		MFP_CFG(GPIO108, AF0)
-#define GPIO109_GPIO		MFP_CFG(GPIO109, AF0)
-#define GPIO110_GPIO		MFP_CFG(GPIO110, AF0)
-#define GPIO111_GPIO		MFP_CFG(GPIO111, AF0)
-#define GPIO112_GPIO		MFP_CFG(GPIO112, AF0)
-#define GPIO113_GPIO		MFP_CFG(GPIO113, AF0)
-#define GPIO114_GPIO		MFP_CFG(GPIO114, AF0)
-#define GPIO115_GPIO		MFP_CFG(GPIO115, AF0)
-#define GPIO116_GPIO		MFP_CFG(GPIO116, AF0)
-#define GPIO117_GPIO		MFP_CFG(GPIO117, AF0)
-#define GPIO118_GPIO		MFP_CFG(GPIO118, AF0)
-#define GPIO119_GPIO		MFP_CFG(GPIO119, AF0)
-#define GPIO120_GPIO		MFP_CFG(GPIO120, AF0)
-#define GPIO121_GPIO		MFP_CFG(GPIO121, AF0)
-#define GPIO122_GPIO		MFP_CFG(GPIO122, AF0)
-#define GPIO123_GPIO		MFP_CFG(GPIO123, AF0)
-#define GPIO124_GPIO		MFP_CFG(GPIO124, AF0)
-#define GPIO125_GPIO		MFP_CFG(GPIO125, AF0)
-#define GPIO126_GPIO		MFP_CFG(GPIO126, AF0)
-#define GPIO127_GPIO		MFP_CFG(GPIO127, AF0)
-
-#define GPIO0_2_GPIO		MFP_CFG(GPIO0_2, AF0)
-#define GPIO1_2_GPIO		MFP_CFG(GPIO1_2, AF0)
-#define GPIO2_2_GPIO		MFP_CFG(GPIO2_2, AF0)
-#define GPIO3_2_GPIO		MFP_CFG(GPIO3_2, AF0)
-#define GPIO4_2_GPIO		MFP_CFG(GPIO4_2, AF0)
-#define GPIO5_2_GPIO		MFP_CFG(GPIO5_2, AF0)
-#define GPIO6_2_GPIO		MFP_CFG(GPIO6_2, AF0)
-
-/*
- * each MFP pin will have a MFPR register, since the offset of the
- * register varies between processors, the processor specific code
- * should initialize the pin offsets by pxa3xx_mfp_init_addr()
- *
- * pxa3xx_mfp_init_addr - accepts a table of "pxa3xx_mfp_addr_map"
- * structure, which represents a range of MFP pins from "start" to
- * "end", with the offset begining at "offset", to define a single
- * pin, let "end" = -1
- *
- * use
- *
- * MFP_ADDR_X() to define a range of pins
- * MFP_ADDR()   to define a single pin
- * MFP_ADDR_END to signal the end of pin offset definitions
- */
-struct pxa3xx_mfp_addr_map {
-	unsigned int	start;
-	unsigned int	end;
-	unsigned long	offset;
-};
-
-#define MFP_ADDR_X(start, end, offset) \
-	{ MFP_PIN_##start, MFP_PIN_##end, offset }
-
-#define MFP_ADDR(pin, offset) \
-	{ MFP_PIN_##pin, -1, offset }
-
-#define MFP_ADDR_END	{ MFP_PIN_INVALID, 0 }
-
-struct pxa3xx_mfp_pin {
-	unsigned long	mfpr_off;	/* MFPRxx register offset */
-	unsigned long	mfpr_val;	/* MFPRxx register value */
-};
-
-/*
- * pxa3xx_mfp_read()/pxa3xx_mfp_write() - for direct read/write access
- * to the MFPR register
- */
-unsigned long pxa3xx_mfp_read(int mfp);
-void pxa3xx_mfp_write(int mfp, unsigned long mfpr_val);
-
-/*
- * pxa3xx_mfp_set_afds - set MFP alternate function and drive strength
- * pxa3xx_mfp_set_rdh  - set MFP release delay hold on/off
- * pxa3xx_mfp_set_lpm  - set MFP low power mode state
- * pxa3xx_mfp_set_edge - set MFP edge detection in low power mode
- *
- * use these functions to override/change the default configuration
- * done by pxa3xx_mfp_set_config(s)
- */
-void pxa3xx_mfp_set_afds(int mfp, int af, int ds);
-void pxa3xx_mfp_set_rdh(int mfp, int rdh);
-void pxa3xx_mfp_set_lpm(int mfp, int lpm);
-void pxa3xx_mfp_set_edge(int mfp, int edge);
-
-/*
- * pxa3xx_mfp_config - configure the MFPR registers
- *
- * used by board specific initialization code
- */
-void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num);
-
-/*
- * pxa3xx_mfp_init_addr() - initialize the mapping between mfp pin
- * index and MFPR register offset
- *
- * used by processor specific code
- */
-void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *);
-void __init pxa3xx_init_mfp(void);
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
 
 #endif /* __ASM_ARCH_MFP_H */
diff --git a/include/asm-arm/arch-pxa/mmc.h b/include/asm-arm/arch-pxa/mmc.h
index ef4f570..6d1304c 100644
--- a/include/asm-arm/arch-pxa/mmc.h
+++ b/include/asm-arm/arch-pxa/mmc.h
@@ -17,5 +17,7 @@
 };
 
 extern void pxa_set_mci_info(struct pxamci_platform_data *info);
+extern void pxa3xx_set_mci2_info(struct pxamci_platform_data *info);
+extern void pxa3xx_set_mci3_info(struct pxamci_platform_data *info);
 
 #endif
diff --git a/include/asm-arm/arch-pxa/pcm027.h b/include/asm-arm/arch-pxa/pcm027.h
new file mode 100644
index 0000000..7beae14
--- /dev/null
+++ b/include/asm-arm/arch-pxa/pcm027.h
@@ -0,0 +1,75 @@
+/*
+ * linux/include/asm-arm/arch-pxa/pcm027.h
+ *
+ * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Definitions of CPU card resources only
+ */
+
+/* I2C RTC */
+#define PCM027_RTC_IRQ_GPIO	0
+#define PCM027_RTC_IRQ		IRQ_GPIO(PCM027_RTC_IRQ_GPIO)
+#define PCM027_RTC_IRQ_EDGE	IRQ_TYPE_EDGE_FALLING
+#define ADR_PCM027_RTC		0x51	/* I2C address */
+
+/* I2C EEPROM */
+#define ADR_PCM027_EEPROM	0x54	/* I2C address */
+
+/* Ethernet chip (SMSC91C111) */
+#define PCM027_ETH_IRQ_GPIO	52
+#define PCM027_ETH_IRQ		IRQ_GPIO(PCM027_ETH_IRQ_GPIO)
+#define PCM027_ETH_IRQ_EDGE	IRQ_TYPE_EDGE_RISING
+#define PCM027_ETH_PHYS		PXA_CS5_PHYS
+#define PCM027_ETH_SIZE		(1*1024*1024)
+
+/* CAN controller SJA1000 (unsupported yet) */
+#define PCM027_CAN_IRQ_GPIO	114
+#define PCM027_CAN_IRQ		IRQ_GPIO(PCM027_CAN_IRQ_GPIO)
+#define PCM027_CAN_IRQ_EDGE	IRQ_TYPE_EDGE_FALLING
+#define PCM027_CAN_PHYS		0x22000000
+#define PCM027_CAN_SIZE		0x100
+
+/* SPI GPIO expander (unsupported yet) */
+#define PCM027_EGPIO_IRQ_GPIO	27
+#define PCM027_EGPIO_IRQ	IRQ_GPIO(PCM027_EGPIO_IRQ_GPIO)
+#define PCM027_EGPIO_IRQ_EDGE	IRQ_TYPE_EDGE_FALLING
+#define PCM027_EGPIO_CS		24
+/*
+ * TODO: Switch this pin from dedicated usage to GPIO if
+ * more than the MAX7301 device is connected to this SPI bus
+ */
+#define PCM027_EGPIO_CS_MODE	GPIO24_SFRM_MD
+
+/* Flash memory */
+#define PCM027_FLASH_PHYS	0x00000000
+#define PCM027_FLASH_SIZE	0x02000000
+
+/* onboard LEDs connected to GPIO */
+#define PCM027_LED_CPU		90
+#define PCM027_LED_HEARD_BEAT	91
+
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ * TODO: Add your own basebaord init function and call it from
+ * inside pcm027_init(). This example here is for the developmen board.
+ * Refer pcm990-baseboard.c
+ */
+extern void pcm990_baseboard_init(void);
diff --git a/include/asm-arm/arch-pxa/pcm990_baseboard.h b/include/asm-arm/arch-pxa/pcm990_baseboard.h
new file mode 100644
index 0000000..b699d0d
--- /dev/null
+++ b/include/asm-arm/arch-pxa/pcm990_baseboard.h
@@ -0,0 +1,275 @@
+/*
+ * include/asm-arm/arch-pxa/pcm990_baseboard.h
+ *
+ * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <asm/arch/pcm027.h>
+
+/*
+ * definitions relevant only when the PCM-990
+ * development base board is in use
+ */
+
+/* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */
+#define PCM990_CTRL_INT_IRQ_GPIO	9
+#define PCM990_CTRL_INT_IRQ		IRQ_GPIO(PCM990_CTRL_INT_IRQ_GPIO)
+#define PCM990_CTRL_INT_IRQ_EDGE	IRQT_RISING
+#define PCM990_CTRL_PHYS		PXA_CS1_PHYS	/* 16-Bit */
+#define PCM990_CTRL_BASE		0xea000000
+#define PCM990_CTRL_SIZE		(1*1024*1024)
+
+#define PCM990_CTRL_PWR_IRQ_GPIO	14
+#define PCM990_CTRL_PWR_IRQ		IRQ_GPIO(PCM990_CTRL_PWR_IRQ_GPIO)
+#define PCM990_CTRL_PWR_IRQ_EDGE	IRQT_RISING
+
+/* visible CPLD (U7) registers */
+#define PCM990_CTRL_REG0	0x0000	/* RESET REGISTER */
+#define PCM990_CTRL_SYSRES	0x0001	/* System RESET REGISTER */
+#define PCM990_CTRL_RESOUT	0x0002	/* RESETOUT Enable REGISTER */
+#define PCM990_CTRL_RESGPIO	0x0004	/* RESETGPIO Enable REGISTER */
+
+#define PCM990_CTRL_REG1	0x0002	/* Power REGISTER */
+#define PCM990_CTRL_5VOFF	0x0001	/* Disable  5V Regulators */
+#define PCM990_CTRL_CANPWR	0x0004	/* Enable CANPWR ADUM */
+#define PCM990_CTRL_PM_5V	0x0008	/* Read 5V OK */
+
+#define PCM990_CTRL_REG2	0x0004	/* LED REGISTER */
+#define PCM990_CTRL_LEDPWR	0x0001	/* POWER LED enable */
+#define PCM990_CTRL_LEDBAS	0x0002	/* BASIS LED enable */
+#define PCM990_CTRL_LEDUSR	0x0004	/* USER LED enable */
+
+#define PCM990_CTRL_REG3	0x0006	/* LCD CTRL REGISTER 3 */
+#define PCM990_CTRL_LCDPWR	0x0001	/* RW LCD Power on */
+#define PCM990_CTRL_LCDON	0x0002	/* RW LCD Latch on */
+#define PCM990_CTRL_LCDPOS1	0x0004	/* RW POS 1 */
+#define PCM990_CTRL_LCDPOS2	0x0008	/* RW POS 2 */
+
+#define PCM990_CTRL_REG4	0x0008	/* MMC1 CTRL REGISTER 4 */
+#define PCM990_CTRL_MMC1PWR	0x0001 /* RW MMC1 Power on */
+
+#define PCM990_CTRL_REG5	0x000A	/* MMC2 CTRL REGISTER 5 */
+#define PCM990_CTRL_MMC2PWR	0x0001	/* RW MMC2 Power on */
+#define PCM990_CTRL_MMC2LED	0x0002	/* RW MMC2 LED */
+#define PCM990_CTRL_MMC2DE	0x0004	/* R MMC2 Card detect */
+#define PCM990_CTRL_MMC2WP	0x0008	/* R MMC2 Card write protect */
+
+#define PCM990_CTRL_REG6	0x000C	/* Interrupt Clear REGISTER */
+#define PCM990_CTRL_INTC0	0x0001	/* Clear Reg BT Detect */
+#define PCM990_CTRL_INTC1	0x0002	/* Clear Reg FR RI */
+#define PCM990_CTRL_INTC2	0x0004	/* Clear Reg MMC1 Detect */
+#define PCM990_CTRL_INTC3	0x0008	/* Clear Reg PM_5V off */
+
+#define PCM990_CTRL_REG7	0x000E	/* Interrupt Enable REGISTER */
+#define PCM990_CTRL_ENAINT0	0x0001	/* Enable Int BT Detect */
+#define PCM990_CTRL_ENAINT1	0x0002	/* Enable Int FR RI */
+#define PCM990_CTRL_ENAINT2	0x0004	/* Enable Int MMC1 Detect */
+#define PCM990_CTRL_ENAINT3	0x0008	/* Enable Int PM_5V off */
+
+#define PCM990_CTRL_REG8	0x0014	/* Uart REGISTER */
+#define PCM990_CTRL_FFSD	0x0001	/* BT Uart Enable */
+#define PCM990_CTRL_BTSD	0x0002	/* FF Uart Enable */
+#define PCM990_CTRL_FFRI	0x0004	/* FF Uart RI detect */
+#define PCM990_CTRL_BTRX	0x0008	/* BT Uart Rx detect */
+
+#define PCM990_CTRL_REG9	0x0010	/* AC97 Flash REGISTER */
+#define PCM990_CTRL_FLWP	0x0001	/* pC Flash Write Protect */
+#define PCM990_CTRL_FLDIS	0x0002	/* pC Flash Disable */
+#define PCM990_CTRL_AC97ENA	0x0004	/* Enable AC97 Expansion */
+
+#define PCM990_CTRL_REG10	0x0012	/* GPS-REGISTER */
+#define PCM990_CTRL_GPSPWR	0x0004	/* GPS-Modul Power on */
+#define PCM990_CTRL_GPSENA	0x0008	/* GPS-Modul Enable */
+
+#define PCM990_CTRL_REG11	0x0014	/* Accu REGISTER */
+#define PCM990_CTRL_ACENA	0x0001	/* Charge Enable */
+#define PCM990_CTRL_ACSEL	0x0002	/* Charge Akku -> DC Enable */
+#define PCM990_CTRL_ACPRES	0x0004	/* DC Present */
+#define PCM990_CTRL_ACALARM	0x0008	/* Error Akku */
+
+#define PCM990_CTRL_P2V(x)	((x) - PCM990_CTRL_PHYS + PCM990_CTRL_BASE)
+#define PCM990_CTRL_V2P(x)	((x) - PCM990_CTRL_BASE + PCM990_CTRL_PHYS)
+
+#ifndef __ASSEMBLY__
+#  define __PCM990_CTRL_REG(x) \
+		(*((volatile unsigned char *)PCM990_CTRL_P2V(x)))
+#else
+#  define __PCM990_CTRL_REG(x)	PCM990_CTRL_P2V(x)
+#endif
+
+#define PCM990_INTMSKENA __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7)
+#define PCM990_INTSETCLR __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6)
+#define PCM990_CTRL0	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG0)
+#define PCM990_CTRL1	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG1)
+#define PCM990_CTRL2	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG2)
+#define PCM990_CTRL3	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3)
+#define PCM990_CTRL4	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG4)
+#define PCM990_CTRL5	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5)
+#define PCM990_CTRL6	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6)
+#define PCM990_CTRL7	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7)
+#define PCM990_CTRL8	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG8)
+#define PCM990_CTRL9	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG9)
+#define PCM990_CTRL10	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG10)
+#define PCM990_CTRL11	__PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG11)
+
+
+/*
+ * IDE
+ */
+#define PCM990_IDE_IRQ_GPIO	13
+#define PCM990_IDE_IRQ		IRQ_GPIO(PCM990_IDE_IRQ_GPIO)
+#define PCM990_IDE_IRQ_EDGE	IRQT_RISING
+#define PCM990_IDE_PLD_PHYS	0x20000000	/* 16 bit wide */
+#define PCM990_IDE_PLD_BASE	0xee000000
+#define PCM990_IDE_PLD_SIZE	(1*1024*1024)
+
+/* visible CPLD (U6) registers */
+#define PCM990_IDE_PLD_REG0	0x1000	/* OFFSET IDE REGISTER 0 */
+#define PCM990_IDE_PM5V		0x0004	/* R System VCC_5V */
+#define PCM990_IDE_STBY		0x0008	/* R System StandBy */
+
+#define PCM990_IDE_PLD_REG1	0x1002	/* OFFSET IDE REGISTER 1 */
+#define PCM990_IDE_IDEMODE	0x0001	/* R TrueIDE Mode */
+#define PCM990_IDE_DMAENA	0x0004	/* RW DMA Enable */
+#define PCM990_IDE_DMA1_0	0x0008	/* RW 1=DREQ1 0=DREQ0 */
+
+#define PCM990_IDE_PLD_REG2	0x1004	/* OFFSET IDE REGISTER 2 */
+#define PCM990_IDE_RESENA	0x0001	/* RW IDE Reset Bit enable */
+#define PCM990_IDE_RES		0x0002	/* RW IDE Reset Bit */
+#define PCM990_IDE_RDY		0x0008	/* RDY */
+
+#define PCM990_IDE_PLD_REG3	0x1006	/* OFFSET IDE REGISTER 3 */
+#define PCM990_IDE_IDEOE	0x0001	/* RW Latch on Databus */
+#define PCM990_IDE_IDEON	0x0002	/* RW Latch on Control Address */
+#define PCM990_IDE_IDEIN	0x0004	/* RW Latch on Interrupt usw. */
+
+#define PCM990_IDE_PLD_REG4	0x1008	/* OFFSET IDE REGISTER 4 */
+#define PCM990_IDE_PWRENA	0x0001	/* RW IDE Power enable */
+#define PCM990_IDE_5V		0x0002	/* R IDE Power 5V */
+#define PCM990_IDE_PWG		0x0008	/* R IDE Power is on */
+
+#define PCM990_IDE_PLD_P2V(x) ((x) - PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_BASE)
+#define PCM990_IDE_PLD_V2P(x) ((x) - PCM990_IDE_PLD_BASE + PCM990_IDE_PLD_PHYS)
+
+#ifndef __ASSEMBLY__
+# define  __PCM990_IDE_PLD_REG(x) \
+	(*((volatile unsigned char *)PCM990_IDE_PLD_P2V(x)))
+#else
+# define  __PCM990_IDE_PLD_REG(x)	PCM990_IDE_PLD_P2V(x)
+#endif
+
+#define PCM990_IDE0 \
+	__PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG0)
+#define PCM990_IDE1 \
+	__PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG1)
+#define PCM990_IDE2 \
+	__PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG2)
+#define PCM990_IDE3 \
+	__PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG3)
+#define PCM990_IDE4 \
+	__PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG4)
+
+/*
+ * Compact Flash
+ */
+#define PCM990_CF_IRQ_GPIO	11
+#define PCM990_CF_IRQ		IRQ_GPIO(PCM990_CF_IRQ_GPIO)
+#define PCM990_CF_IRQ_EDGE	IRQT_RISING
+
+#define PCM990_CF_CD_GPIO	12
+#define PCM990_CF_CD		IRQ_GPIO(PCM990_CF_CD_GPIO)
+#define PCM990_CF_CD_EDGE	IRQT_RISING
+
+#define PCM990_CF_PLD_PHYS	0x30000000	/* 16 bit wide */
+#define PCM990_CF_PLD_BASE	0xef000000
+#define PCM990_CF_PLD_SIZE	(1*1024*1024)
+#define PCM990_CF_PLD_P2V(x)	((x) - PCM990_CF_PLD_PHYS + PCM990_CF_PLD_BASE)
+#define PCM990_CF_PLD_V2P(x)	((x) - PCM990_CF_PLD_BASE + PCM990_CF_PLD_PHYS)
+
+/* visible CPLD (U6) registers */
+#define PCM990_CF_PLD_REG0	0x1000	/* OFFSET CF REGISTER 0 */
+#define PCM990_CF_REG0_LED	0x0001	/* RW LED on */
+#define PCM990_CF_REG0_BLK	0x0002	/* RW LED flash when access */
+#define PCM990_CF_REG0_PM5V	0x0004	/* R System VCC_5V enable */
+#define PCM990_CF_REG0_STBY	0x0008	/* R System StandBy */
+
+#define PCM990_CF_PLD_REG1	0x1002	/* OFFSET CF REGISTER 1 */
+#define PCM990_CF_REG1_IDEMODE	0x0001	/* RW CF card run as TrueIDE */
+#define PCM990_CF_REG1_CF0	0x0002	/* RW CF card at ADDR 0x28000000 */
+
+#define PCM990_CF_PLD_REG2	0x1004	/* OFFSET CF REGISTER 2 */
+#define PCM990_CF_REG2_RES	0x0002	/* RW CF RESET BIT */
+#define PCM990_CF_REG2_RDYENA	0x0004	/* RW Enable CF_RDY */
+#define PCM990_CF_REG2_RDY	0x0008	/* R CF_RDY auf PWAIT */
+
+#define PCM990_CF_PLD_REG3	0x1006	/* OFFSET CF REGISTER 3 */
+#define PCM990_CF_REG3_CFOE	0x0001	/* RW Latch on Databus */
+#define PCM990_CF_REG3_CFON	0x0002	/* RW Latch on Control Address */
+#define PCM990_CF_REG3_CFIN	0x0004	/* RW Latch on Interrupt usw. */
+#define PCM990_CF_REG3_CFCD	0x0008	/* RW Latch on CD1/2 VS1/2 usw */
+
+#define PCM990_CF_PLD_REG4	0x1008	/* OFFSET CF REGISTER 4 */
+#define PCM990_CF_REG4_PWRENA	0x0001	/* RW CF Power on (CD1/2 = "00") */
+#define PCM990_CF_REG4_5_3V	0x0002	/* RW 1 = 5V CF_VCC 0 = 3 V CF_VCC */
+#define PCM990_CF_REG4_3B	0x0004	/* RW 3.0V Backup from VCC (5_3V=0) */
+#define PCM990_CF_REG4_PWG	0x0008	/* R CF-Power is on */
+
+#define PCM990_CF_PLD_REG5	0x100A	/* OFFSET CF REGISTER 5 */
+#define PCM990_CF_REG5_BVD1	0x0001	/* R CF /BVD1 */
+#define PCM990_CF_REG5_BVD2	0x0002	/* R CF /BVD2 */
+#define PCM990_CF_REG5_VS1	0x0004	/* R CF /VS1 */
+#define PCM990_CF_REG5_VS2	0x0008	/* R CF /VS2 */
+
+#define PCM990_CF_PLD_REG6	0x100C	/* OFFSET CF REGISTER 6 */
+#define PCM990_CF_REG6_CD1	0x0001	/* R CF Card_Detect1 */
+#define PCM990_CF_REG6_CD2	0x0002	/* R CF Card_Detect2 */
+
+#ifndef __ASSEMBLY__
+#  define  __PCM990_CF_PLD_REG(x) \
+	(*((volatile unsigned char *)PCM990_CF_PLD_P2V(x)))
+#else
+#  define  __PCM990_CF_PLD_REG(x)	PCM990_CF_PLD_P2V(x)
+#endif
+
+#define PCM990_CF0 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG0)
+#define PCM990_CF1 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG1)
+#define PCM990_CF2 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG2)
+#define PCM990_CF3 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG3)
+#define PCM990_CF4 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG4)
+#define PCM990_CF5 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG5)
+#define PCM990_CF6 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG6)
+
+/*
+ * Wolfson AC97 Touch
+ */
+#define PCM990_AC97_IRQ_GPIO	10
+#define PCM990_AC97_IRQ		IRQ_GPIO(PCM990_AC97_IRQ_GPIO)
+#define PCM990_AC97_IRQ_EDGE	IRQT_RISING
+
+/*
+ * MMC phyCORE
+ */
+#define PCM990_MMC0_IRQ_GPIO	9
+#define PCM990_MMC0_IRQ		IRQ_GPIO(PCM990_MMC0_IRQ_GPIO)
+#define PCM990_MMC0_IRQ_EDGE	IRQT_FALLING
+
+/*
+ * USB phyCore
+ */
+#define PCM990_USB_OVERCURRENT (88 | GPIO_ALT_FN_1_IN)
+#define PCM990_USB_PWR_EN (89 | GPIO_ALT_FN_2_OUT)
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 1bd398d..442494d 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1597,176 +1597,10 @@
 #define PWER_GPIO15	PWER_GPIO (15)	/* GPIO [15] wake-up enable        */
 #define PWER_RTC	0x80000000	/* RTC alarm wake-up enable        */
 
-
 /*
- * SSP Serial Port Registers
- * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different.
- * PXA255, PXA26x and PXA27x have extra ports, registers and bits.
+ * SSP Serial Port Registers - see include/asm-arm/arch-pxa/regs-ssp.h
  */
 
- /* Common PXA2xx bits first */
-#define SSCR0_DSS	(0x0000000f)	/* Data Size Select (mask) */
-#define SSCR0_DataSize(x)  ((x) - 1)	/* Data Size Select [4..16] */
-#define SSCR0_FRF	(0x00000030)	/* FRame Format (mask) */
-#define SSCR0_Motorola	(0x0 << 4)	/* Motorola's Serial Peripheral Interface (SPI) */
-#define SSCR0_TI	(0x1 << 4)	/* Texas Instruments' Synchronous Serial Protocol (SSP) */
-#define SSCR0_National	(0x2 << 4)	/* National Microwire */
-#define SSCR0_ECS	(1 << 6)	/* External clock select */
-#define SSCR0_SSE	(1 << 7)	/* Synchronous Serial Port Enable */
-#if defined(CONFIG_PXA25x)
-#define SSCR0_SCR	(0x0000ff00)	/* Serial Clock Rate (mask) */
-#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */
-#elif defined(CONFIG_PXA27x)
-#define SSCR0_SCR	(0x000fff00)	/* Serial Clock Rate (mask) */
-#define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */
-#define SSCR0_EDSS	(1 << 20)	/* Extended data size select */
-#define SSCR0_NCS	(1 << 21)	/* Network clock select */
-#define SSCR0_RIM	(1 << 22)	/* Receive FIFO overrrun interrupt mask */
-#define SSCR0_TUM	(1 << 23)	/* Transmit FIFO underrun interrupt mask */
-#define SSCR0_FRDC	(0x07000000)	/* Frame rate divider control (mask) */
-#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24)	/* Time slots per frame [1..8] */
-#define SSCR0_ADC	(1 << 30)	/* Audio clock select */
-#define SSCR0_MOD	(1 << 31)	/* Mode (normal or network) */
-#endif
-
-#define SSCR1_RIE	(1 << 0)	/* Receive FIFO Interrupt Enable */
-#define SSCR1_TIE	(1 << 1)	/* Transmit FIFO Interrupt Enable */
-#define SSCR1_LBM	(1 << 2)	/* Loop-Back Mode */
-#define SSCR1_SPO	(1 << 3)	/* Motorola SPI SSPSCLK polarity setting */
-#define SSCR1_SPH	(1 << 4)	/* Motorola SPI SSPSCLK phase setting */
-#define SSCR1_MWDS	(1 << 5)	/* Microwire Transmit Data Size */
-#define SSCR1_TFT	(0x000003c0)	/* Transmit FIFO Threshold (mask) */
-#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
-#define SSCR1_RFT	(0x00003c00)	/* Receive FIFO Threshold (mask) */
-#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */
-
-#define SSSR_TNF	(1 << 2)	/* Transmit FIFO Not Full */
-#define SSSR_RNE	(1 << 3)	/* Receive FIFO Not Empty */
-#define SSSR_BSY	(1 << 4)	/* SSP Busy */
-#define SSSR_TFS	(1 << 5)	/* Transmit FIFO Service Request */
-#define SSSR_RFS	(1 << 6)	/* Receive FIFO Service Request */
-#define SSSR_ROR	(1 << 7)	/* Receive FIFO Overrun */
-
-#define SSCR0_TIM		(1 << 23)	/* Transmit FIFO Under Run Interrupt Mask */
-#define SSCR0_RIM		(1 << 22)	/* Receive FIFO Over Run interrupt Mask */
-#define SSCR0_NCS		(1 << 21)	/* Network Clock Select */
-#define SSCR0_EDSS		(1 << 20)	/* Extended Data Size Select */
-
-/* extra bits in PXA255, PXA26x and PXA27x SSP ports */
-#define SSCR0_TISSP		(1 << 4)	/* TI Sync Serial Protocol */
-#define SSCR0_PSP		(3 << 4)	/* PSP - Programmable Serial Protocol */
-#define SSCR1_TTELP		(1 << 31)	/* TXD Tristate Enable Last Phase */
-#define SSCR1_TTE		(1 << 30)	/* TXD Tristate Enable */
-#define SSCR1_EBCEI		(1 << 29)	/* Enable Bit Count Error interrupt */
-#define SSCR1_SCFR		(1 << 28)	/* Slave Clock free Running */
-#define SSCR1_ECRA		(1 << 27)	/* Enable Clock Request A */
-#define SSCR1_ECRB		(1 << 26)	/* Enable Clock request B */
-#define SSCR1_SCLKDIR	(1 << 25)	/* Serial Bit Rate Clock Direction */
-#define SSCR1_SFRMDIR	(1 << 24)	/* Frame Direction */
-#define SSCR1_RWOT		(1 << 23)	/* Receive Without Transmit */
-#define SSCR1_TRAIL		(1 << 22)	/* Trailing Byte */
-#define SSCR1_TSRE		(1 << 21)	/* Transmit Service Request Enable */
-#define SSCR1_RSRE		(1 << 20)	/* Receive Service Request Enable */
-#define SSCR1_TINTE		(1 << 19)	/* Receiver Time-out Interrupt enable */
-#define SSCR1_PINTE		(1 << 18)	/* Peripheral Trailing Byte Interupt Enable */
-#define SSCR1_STRF		(1 << 15)	/* Select FIFO or EFWR */
-#define SSCR1_EFWR		(1 << 14)	/* Enable FIFO Write/Read */
-
-#define SSSR_BCE		(1 << 23)	/* Bit Count Error */
-#define SSSR_CSS		(1 << 22)	/* Clock Synchronisation Status */
-#define SSSR_TUR		(1 << 21)	/* Transmit FIFO Under Run */
-#define SSSR_EOC		(1 << 20)	/* End Of Chain */
-#define SSSR_TINT		(1 << 19)	/* Receiver Time-out Interrupt */
-#define SSSR_PINT		(1 << 18)	/* Peripheral Trailing Byte Interrupt */
-
-#define SSPSP_FSRT		(1 << 25)	/* Frame Sync Relative Timing */
-#define SSPSP_DMYSTOP(x)	((x) << 23)	/* Dummy Stop */
-#define SSPSP_SFRMWDTH(x)	((x) << 16)	/* Serial Frame Width */
-#define SSPSP_SFRMDLY(x)	((x) << 9)	/* Serial Frame Delay */
-#define SSPSP_DMYSTRT(x)	((x) << 7)	/* Dummy Start */
-#define SSPSP_STRTDLY(x)	((x) << 4)	/* Start Delay */
-#define SSPSP_ETDS			(1 << 3)	/* End of Transfer data State */
-#define SSPSP_SFRMP			(1 << 2)	/* Serial Frame Polarity */
-#define SSPSP_SCMODE(x)		((x) << 0)	/* Serial Bit Rate Clock Mode */
-
-#define SSACD_SCDB		(1 << 3)	/* SSPSYSCLK Divider Bypass */
-#define SSACD_ACPS(x)		((x) << 4)	/* Audio clock PLL select */
-#define SSACD_ACDS(x)		((x) << 0)	/* Audio clock divider select */
-
-#define SSCR0_P1	__REG(0x41000000)  /* SSP Port 1 Control Register 0 */
-#define SSCR1_P1	__REG(0x41000004)  /* SSP Port 1 Control Register 1 */
-#define SSSR_P1		__REG(0x41000008)  /* SSP Port 1 Status Register */
-#define SSITR_P1	__REG(0x4100000C)  /* SSP Port 1 Interrupt Test Register */
-#define SSDR_P1		__REG(0x41000010)  /* (Write / Read) SSP Port 1 Data Write Register/SSP Data Read Register */
-
-/* Support existing PXA25x drivers */
-#define SSCR0		SSCR0_P1  /* SSP Control Register 0 */
-#define SSCR1		SSCR1_P1  /* SSP Control Register 1 */
-#define SSSR		SSSR_P1	  /* SSP Status Register */
-#define SSITR		SSITR_P1  /* SSP Interrupt Test Register */
-#define SSDR		SSDR_P1	  /* (Write / Read) SSP Data Write Register/SSP Data Read Register */
-
-/* PXA27x ports */
-#if defined (CONFIG_PXA27x)
-#define SSTO_P1		__REG(0x41000028)  /* SSP Port 1 Time Out Register */
-#define SSPSP_P1	__REG(0x4100002C)  /* SSP Port 1 Programmable Serial Protocol */
-#define SSTSA_P1	__REG(0x41000030)  /* SSP Port 1 Tx Timeslot Active */
-#define SSRSA_P1	__REG(0x41000034)  /* SSP Port 1 Rx Timeslot Active */
-#define SSTSS_P1	__REG(0x41000038)  /* SSP Port 1 Timeslot Status */
-#define SSACD_P1	__REG(0x4100003C)  /* SSP Port 1 Audio Clock Divider */
-#define SSCR0_P2	__REG(0x41700000)  /* SSP Port 2 Control Register 0 */
-#define SSCR1_P2	__REG(0x41700004)  /* SSP Port 2 Control Register 1 */
-#define SSSR_P2		__REG(0x41700008)  /* SSP Port 2 Status Register */
-#define SSITR_P2	__REG(0x4170000C)  /* SSP Port 2 Interrupt Test Register */
-#define SSDR_P2		__REG(0x41700010)  /* (Write / Read) SSP Port 2 Data Write Register/SSP Data Read Register */
-#define SSTO_P2		__REG(0x41700028)  /* SSP Port 2 Time Out Register */
-#define SSPSP_P2	__REG(0x4170002C)  /* SSP Port 2 Programmable Serial Protocol */
-#define SSTSA_P2	__REG(0x41700030)  /* SSP Port 2 Tx Timeslot Active */
-#define SSRSA_P2	__REG(0x41700034)  /* SSP Port 2 Rx Timeslot Active */
-#define SSTSS_P2	__REG(0x41700038)  /* SSP Port 2 Timeslot Status */
-#define SSACD_P2	__REG(0x4170003C)  /* SSP Port 2 Audio Clock Divider */
-#define SSCR0_P3	__REG(0x41900000)  /* SSP Port 3 Control Register 0 */
-#define SSCR1_P3	__REG(0x41900004)  /* SSP Port 3 Control Register 1 */
-#define SSSR_P3		__REG(0x41900008)  /* SSP Port 3 Status Register */
-#define SSITR_P3	__REG(0x4190000C)  /* SSP Port 3 Interrupt Test Register */
-#define SSDR_P3		__REG(0x41900010)  /* (Write / Read) SSP Port 3 Data Write Register/SSP Data Read Register */
-#define SSTO_P3		__REG(0x41900028)  /* SSP Port 3 Time Out Register */
-#define SSPSP_P3	__REG(0x4190002C)  /* SSP Port 3 Programmable Serial Protocol */
-#define SSTSA_P3	__REG(0x41900030)  /* SSP Port 3 Tx Timeslot Active */
-#define SSRSA_P3	__REG(0x41900034)  /* SSP Port 3 Rx Timeslot Active */
-#define SSTSS_P3	__REG(0x41900038)  /* SSP Port 3 Timeslot Status */
-#define SSACD_P3	__REG(0x4190003C)  /* SSP Port 3 Audio Clock Divider */
-#else /* PXA255 (only port 2) and PXA26x ports*/
-#define SSTO_P1		__REG(0x41000028)  /* SSP Port 1 Time Out Register */
-#define SSPSP_P1	__REG(0x4100002C)  /* SSP Port 1 Programmable Serial Protocol */
-#define SSCR0_P2	__REG(0x41400000)  /* SSP Port 2 Control Register 0 */
-#define SSCR1_P2	__REG(0x41400004)  /* SSP Port 2 Control Register 1 */
-#define SSSR_P2		__REG(0x41400008)  /* SSP Port 2 Status Register */
-#define SSITR_P2	__REG(0x4140000C)  /* SSP Port 2 Interrupt Test Register */
-#define SSDR_P2		__REG(0x41400010)  /* (Write / Read) SSP Port 2 Data Write Register/SSP Data Read Register */
-#define SSTO_P2		__REG(0x41400028)  /* SSP Port 2 Time Out Register */
-#define SSPSP_P2	__REG(0x4140002C)  /* SSP Port 2 Programmable Serial Protocol */
-#define SSCR0_P3	__REG(0x41500000)  /* SSP Port 3 Control Register 0 */
-#define SSCR1_P3	__REG(0x41500004)  /* SSP Port 3 Control Register 1 */
-#define SSSR_P3		__REG(0x41500008)  /* SSP Port 3 Status Register */
-#define SSITR_P3	__REG(0x4150000C)  /* SSP Port 3 Interrupt Test Register */
-#define SSDR_P3		__REG(0x41500010)  /* (Write / Read) SSP Port 3 Data Write Register/SSP Data Read Register */
-#define SSTO_P3		__REG(0x41500028)  /* SSP Port 3 Time Out Register */
-#define SSPSP_P3	__REG(0x4150002C)  /* SSP Port 3 Programmable Serial Protocol */
-#endif
-
-#define SSCR0_P(x) (*(((x) == 1) ? &SSCR0_P1 : ((x) == 2) ? &SSCR0_P2 : ((x) == 3) ? &SSCR0_P3 : NULL))
-#define SSCR1_P(x) (*(((x) == 1) ? &SSCR1_P1 : ((x) == 2) ? &SSCR1_P2 : ((x) == 3) ? &SSCR1_P3 : NULL))
-#define SSSR_P(x) (*(((x) == 1) ? &SSSR_P1 : ((x) == 2) ? &SSSR_P2 : ((x) == 3) ? &SSSR_P3 : NULL))
-#define SSITR_P(x) (*(((x) == 1) ? &SSITR_P1 : ((x) == 2) ? &SSITR_P2 : ((x) == 3) ? &SSITR_P3 : NULL))
-#define SSDR_P(x) (*(((x) == 1) ? &SSDR_P1 : ((x) == 2) ? &SSDR_P2 : ((x) == 3) ? &SSDR_P3 : NULL))
-#define SSTO_P(x) (*(((x) == 1) ? &SSTO_P1 : ((x) == 2) ? &SSTO_P2 : ((x) == 3) ? &SSTO_P3 : NULL))
-#define SSPSP_P(x) (*(((x) == 1) ? &SSPSP_P1 : ((x) == 2) ? &SSPSP_P2 : ((x) == 3) ? &SSPSP_P3 : NULL))
-#define SSTSA_P(x) (*(((x) == 1) ? &SSTSA_P1 : ((x) == 2) ? &SSTSA_P2 : ((x) == 3) ? &SSTSA_P3 : NULL))
-#define SSRSA_P(x) (*(((x) == 1) ? &SSRSA_P1 : ((x) == 2) ? &SSRSA_P2 : ((x) == 3) ? &SSRSA_P3 : NULL))
-#define SSTSS_P(x) (*(((x) == 1) ? &SSTSS_P1 : ((x) == 2) ? &SSTSS_P2 : ((x) == 3) ? &SSTSS_P3 : NULL))
-#define SSACD_P(x) (*(((x) == 1) ? &SSACD_P1 : ((x) == 2) ? &SSACD_P2 : ((x) == 3) ? &SSACD_P3 : NULL))
-
 /*
  * MultiMediaCard (MMC) controller - see drivers/mmc/host/pxamci.h
  */
@@ -2014,71 +1848,8 @@
 
 #define LDCMD_PAL	(1 << 26)	/* instructs DMA to load palette buffer */
 
-/*
- * Memory controller
- */
-
-#define MDCNFG		__REG(0x48000000)  /* SDRAM Configuration Register 0 */
-#define MDREFR		__REG(0x48000004)  /* SDRAM Refresh Control Register */
-#define MSC0		__REG(0x48000008)  /* Static Memory Control Register 0 */
-#define MSC1		__REG(0x4800000C)  /* Static Memory Control Register 1 */
-#define MSC2		__REG(0x48000010)  /* Static Memory Control Register 2 */
-#define MECR		__REG(0x48000014)  /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
-#define SXLCR		__REG(0x48000018)  /* LCR value to be written to SDRAM-Timing Synchronous Flash */
-#define SXCNFG		__REG(0x4800001C)  /* Synchronous Static Memory Control Register */
-#define SXMRS		__REG(0x48000024)  /* MRS value to be written to Synchronous Flash or SMROM */
-#define MCMEM0		__REG(0x48000028)  /* Card interface Common Memory Space Socket 0 Timing */
-#define MCMEM1		__REG(0x4800002C)  /* Card interface Common Memory Space Socket 1 Timing */
-#define MCATT0		__REG(0x48000030)  /* Card interface Attribute Space Socket 0 Timing Configuration */
-#define MCATT1		__REG(0x48000034)  /* Card interface Attribute Space Socket 1 Timing Configuration */
-#define MCIO0		__REG(0x48000038)  /* Card interface I/O Space Socket 0 Timing Configuration */
-#define MCIO1		__REG(0x4800003C)  /* Card interface I/O Space Socket 1 Timing Configuration */
-#define MDMRS		__REG(0x48000040)  /* MRS value to be written to SDRAM */
-#define BOOT_DEF	__REG(0x48000044)  /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
-
-/*
- * More handy macros for PCMCIA
- *
- * Arg is socket number
- */
-#define MCMEM(s)	__REG2(0x48000028, (s)<<2 )  /* Card interface Common Memory Space Socket s Timing */
-#define MCATT(s)	__REG2(0x48000030, (s)<<2 )  /* Card interface Attribute Space Socket s Timing Configuration */
-#define MCIO(s)		__REG2(0x48000038, (s)<<2 )  /* Card interface I/O Space Socket s Timing Configuration */
-
-/* MECR register defines */
-#define MECR_NOS	(1 << 0)	/* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
-#define MECR_CIT	(1 << 1)	/* Card Is There: 0 -> no card, 1 -> card inserted */
-
-#define MDREFR_K0DB4	(1 << 29)	/* SDCLK0 Divide by 4 Control/Status */
-#define MDREFR_K2FREE	(1 << 25)	/* SDRAM Free-Running Control */
-#define MDREFR_K1FREE	(1 << 24)	/* SDRAM Free-Running Control */
-#define MDREFR_K0FREE	(1 << 23)	/* SDRAM Free-Running Control */
-#define MDREFR_SLFRSH	(1 << 22)	/* SDRAM Self-Refresh Control/Status */
-#define MDREFR_APD	(1 << 20)	/* SDRAM/SSRAM Auto-Power-Down Enable */
-#define MDREFR_K2DB2	(1 << 19)	/* SDCLK2 Divide by 2 Control/Status */
-#define MDREFR_K2RUN	(1 << 18)	/* SDCLK2 Run Control/Status */
-#define MDREFR_K1DB2	(1 << 17)	/* SDCLK1 Divide by 2 Control/Status */
-#define MDREFR_K1RUN	(1 << 16)	/* SDCLK1 Run Control/Status */
-#define MDREFR_E1PIN	(1 << 15)	/* SDCKE1 Level Control/Status */
-#define MDREFR_K0DB2	(1 << 14)	/* SDCLK0 Divide by 2 Control/Status */
-#define MDREFR_K0RUN	(1 << 13)	/* SDCLK0 Run Control/Status */
-#define MDREFR_E0PIN	(1 << 12)	/* SDCKE0 Level Control/Status */
-
-
 #ifdef CONFIG_PXA27x
 
-#define ARB_CNTRL	__REG(0x48000048)  /* Arbiter Control Register */
-
-#define ARB_DMA_SLV_PARK	(1<<31)	   /* Be parked with DMA slave when idle */
-#define ARB_CI_PARK		(1<<30)	   /* Be parked with Camera Interface when idle */
-#define ARB_EX_MEM_PARK 	(1<<29)	   /* Be parked with external MEMC when idle */
-#define ARB_INT_MEM_PARK	(1<<28)	   /* Be parked with internal MEMC when idle */
-#define ARB_USB_PARK		(1<<27)	   /* Be parked with USB when idle */
-#define ARB_LCD_PARK		(1<<26)	   /* Be parked with LCD when idle */
-#define ARB_DMA_PARK		(1<<25)	   /* Be parked with DMA when idle */
-#define ARB_CORE_PARK		(1<<24)	   /* Be parked with core when idle */
-#define ARB_LOCK_FLAG		(1<<23)	   /* Only Locking masters gain access to the bus */
-
 /*
  * Keypad
  */
@@ -2135,74 +1906,6 @@
 #define KPAS_SO         (0x1 << 31)
 #define KPASMKPx_SO     (0x1 << 31)
 
-/*
- * UHC: USB Host Controller (OHCI-like) register definitions
- */
-#define UHC_BASE_PHYS	(0x4C000000)
-#define UHCREV		__REG(0x4C000000) /* UHC HCI Spec Revision */
-#define UHCHCON		__REG(0x4C000004) /* UHC Host Control Register */
-#define UHCCOMS		__REG(0x4C000008) /* UHC Command Status Register */
-#define UHCINTS		__REG(0x4C00000C) /* UHC Interrupt Status Register */
-#define UHCINTE		__REG(0x4C000010) /* UHC Interrupt Enable */
-#define UHCINTD		__REG(0x4C000014) /* UHC Interrupt Disable */
-#define UHCHCCA		__REG(0x4C000018) /* UHC Host Controller Comm. Area */
-#define UHCPCED		__REG(0x4C00001C) /* UHC Period Current Endpt Descr */
-#define UHCCHED		__REG(0x4C000020) /* UHC Control Head Endpt Descr */
-#define UHCCCED		__REG(0x4C000024) /* UHC Control Current Endpt Descr */
-#define UHCBHED		__REG(0x4C000028) /* UHC Bulk Head Endpt Descr */
-#define UHCBCED		__REG(0x4C00002C) /* UHC Bulk Current Endpt Descr */
-#define UHCDHEAD	__REG(0x4C000030) /* UHC Done Head */
-#define UHCFMI		__REG(0x4C000034) /* UHC Frame Interval */
-#define UHCFMR		__REG(0x4C000038) /* UHC Frame Remaining */
-#define UHCFMN		__REG(0x4C00003C) /* UHC Frame Number */
-#define UHCPERS		__REG(0x4C000040) /* UHC Periodic Start */
-#define UHCLS		__REG(0x4C000044) /* UHC Low Speed Threshold */
-
-#define UHCRHDA		__REG(0x4C000048) /* UHC Root Hub Descriptor A */
-#define UHCRHDA_NOCP	(1 << 12)	/* No over current protection */
-
-#define UHCRHDB		__REG(0x4C00004C) /* UHC Root Hub Descriptor B */
-#define UHCRHS		__REG(0x4C000050) /* UHC Root Hub Status */
-#define UHCRHPS1	__REG(0x4C000054) /* UHC Root Hub Port 1 Status */
-#define UHCRHPS2	__REG(0x4C000058) /* UHC Root Hub Port 2 Status */
-#define UHCRHPS3	__REG(0x4C00005C) /* UHC Root Hub Port 3 Status */
-
-#define UHCSTAT		__REG(0x4C000060) /* UHC Status Register */
-#define UHCSTAT_UPS3	(1 << 16)	/* USB Power Sense Port3 */
-#define UHCSTAT_SBMAI	(1 << 15)	/* System Bus Master Abort Interrupt*/
-#define UHCSTAT_SBTAI	(1 << 14)	/* System Bus Target Abort Interrupt*/
-#define UHCSTAT_UPRI	(1 << 13)	/* USB Port Resume Interrupt */
-#define UHCSTAT_UPS2	(1 << 12)	/* USB Power Sense Port 2 */
-#define UHCSTAT_UPS1	(1 << 11)	/* USB Power Sense Port 1 */
-#define UHCSTAT_HTA	(1 << 10)	/* HCI Target Abort */
-#define UHCSTAT_HBA	(1 << 8)	/* HCI Buffer Active */
-#define UHCSTAT_RWUE	(1 << 7)	/* HCI Remote Wake Up Event */
-
-#define UHCHR           __REG(0x4C000064) /* UHC Reset Register */
-#define UHCHR_SSEP3	(1 << 11)	/* Sleep Standby Enable for Port3 */
-#define UHCHR_SSEP2	(1 << 10)	/* Sleep Standby Enable for Port2 */
-#define UHCHR_SSEP1	(1 << 9)	/* Sleep Standby Enable for Port1 */
-#define UHCHR_PCPL	(1 << 7)	/* Power control polarity low */
-#define UHCHR_PSPL	(1 << 6)	/* Power sense polarity low */
-#define UHCHR_SSE	(1 << 5)	/* Sleep Standby Enable */
-#define UHCHR_UIT	(1 << 4)	/* USB Interrupt Test */
-#define UHCHR_SSDC	(1 << 3)	/* Simulation Scale Down Clock */
-#define UHCHR_CGR	(1 << 2)	/* Clock Generation Reset */
-#define UHCHR_FHR	(1 << 1)	/* Force Host Controller Reset */
-#define UHCHR_FSBIR	(1 << 0)	/* Force System Bus Iface Reset */
-
-#define UHCHIE          __REG(0x4C000068) /* UHC Interrupt Enable Register*/
-#define UHCHIE_UPS3IE	(1 << 14)	/* Power Sense Port3 IntEn */
-#define UHCHIE_UPRIE	(1 << 13)	/* Port Resume IntEn */
-#define UHCHIE_UPS2IE	(1 << 12)	/* Power Sense Port2 IntEn */
-#define UHCHIE_UPS1IE	(1 << 11)	/* Power Sense Port1 IntEn */
-#define UHCHIE_TAIE	(1 << 10)	/* HCI Interface Transfer Abort
-					   Interrupt Enable*/
-#define UHCHIE_HBAIE	(1 << 8)	/* HCI Buffer Active IntEn */
-#define UHCHIE_RWIE	(1 << 7)	/* Remote Wake-up IntEn */
-
-#define UHCHIT          __REG(0x4C00006C) /* UHC Interrupt Test register */
-
 /* Camera Interface */
 #define CICR0		__REG(0x50000000)
 #define CICR1		__REG(0x50000004)
@@ -2350,6 +2053,77 @@
 
 #endif
 
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
+/*
+ * UHC: USB Host Controller (OHCI-like) register definitions
+ */
+#define UHC_BASE_PHYS	(0x4C000000)
+#define UHCREV		__REG(0x4C000000) /* UHC HCI Spec Revision */
+#define UHCHCON		__REG(0x4C000004) /* UHC Host Control Register */
+#define UHCCOMS		__REG(0x4C000008) /* UHC Command Status Register */
+#define UHCINTS		__REG(0x4C00000C) /* UHC Interrupt Status Register */
+#define UHCINTE		__REG(0x4C000010) /* UHC Interrupt Enable */
+#define UHCINTD		__REG(0x4C000014) /* UHC Interrupt Disable */
+#define UHCHCCA		__REG(0x4C000018) /* UHC Host Controller Comm. Area */
+#define UHCPCED		__REG(0x4C00001C) /* UHC Period Current Endpt Descr */
+#define UHCCHED		__REG(0x4C000020) /* UHC Control Head Endpt Descr */
+#define UHCCCED		__REG(0x4C000024) /* UHC Control Current Endpt Descr */
+#define UHCBHED		__REG(0x4C000028) /* UHC Bulk Head Endpt Descr */
+#define UHCBCED		__REG(0x4C00002C) /* UHC Bulk Current Endpt Descr */
+#define UHCDHEAD	__REG(0x4C000030) /* UHC Done Head */
+#define UHCFMI		__REG(0x4C000034) /* UHC Frame Interval */
+#define UHCFMR		__REG(0x4C000038) /* UHC Frame Remaining */
+#define UHCFMN		__REG(0x4C00003C) /* UHC Frame Number */
+#define UHCPERS		__REG(0x4C000040) /* UHC Periodic Start */
+#define UHCLS		__REG(0x4C000044) /* UHC Low Speed Threshold */
+
+#define UHCRHDA		__REG(0x4C000048) /* UHC Root Hub Descriptor A */
+#define UHCRHDA_NOCP	(1 << 12)	/* No over current protection */
+
+#define UHCRHDB		__REG(0x4C00004C) /* UHC Root Hub Descriptor B */
+#define UHCRHS		__REG(0x4C000050) /* UHC Root Hub Status */
+#define UHCRHPS1	__REG(0x4C000054) /* UHC Root Hub Port 1 Status */
+#define UHCRHPS2	__REG(0x4C000058) /* UHC Root Hub Port 2 Status */
+#define UHCRHPS3	__REG(0x4C00005C) /* UHC Root Hub Port 3 Status */
+
+#define UHCSTAT		__REG(0x4C000060) /* UHC Status Register */
+#define UHCSTAT_UPS3	(1 << 16)	/* USB Power Sense Port3 */
+#define UHCSTAT_SBMAI	(1 << 15)	/* System Bus Master Abort Interrupt*/
+#define UHCSTAT_SBTAI	(1 << 14)	/* System Bus Target Abort Interrupt*/
+#define UHCSTAT_UPRI	(1 << 13)	/* USB Port Resume Interrupt */
+#define UHCSTAT_UPS2	(1 << 12)	/* USB Power Sense Port 2 */
+#define UHCSTAT_UPS1	(1 << 11)	/* USB Power Sense Port 1 */
+#define UHCSTAT_HTA	(1 << 10)	/* HCI Target Abort */
+#define UHCSTAT_HBA	(1 << 8)	/* HCI Buffer Active */
+#define UHCSTAT_RWUE	(1 << 7)	/* HCI Remote Wake Up Event */
+
+#define UHCHR           __REG(0x4C000064) /* UHC Reset Register */
+#define UHCHR_SSEP3	(1 << 11)	/* Sleep Standby Enable for Port3 */
+#define UHCHR_SSEP2	(1 << 10)	/* Sleep Standby Enable for Port2 */
+#define UHCHR_SSEP1	(1 << 9)	/* Sleep Standby Enable for Port1 */
+#define UHCHR_PCPL	(1 << 7)	/* Power control polarity low */
+#define UHCHR_PSPL	(1 << 6)	/* Power sense polarity low */
+#define UHCHR_SSE	(1 << 5)	/* Sleep Standby Enable */
+#define UHCHR_UIT	(1 << 4)	/* USB Interrupt Test */
+#define UHCHR_SSDC	(1 << 3)	/* Simulation Scale Down Clock */
+#define UHCHR_CGR	(1 << 2)	/* Clock Generation Reset */
+#define UHCHR_FHR	(1 << 1)	/* Force Host Controller Reset */
+#define UHCHR_FSBIR	(1 << 0)	/* Force System Bus Iface Reset */
+
+#define UHCHIE          __REG(0x4C000068) /* UHC Interrupt Enable Register*/
+#define UHCHIE_UPS3IE	(1 << 14)	/* Power Sense Port3 IntEn */
+#define UHCHIE_UPRIE	(1 << 13)	/* Port Resume IntEn */
+#define UHCHIE_UPS2IE	(1 << 12)	/* Power Sense Port2 IntEn */
+#define UHCHIE_UPS1IE	(1 << 11)	/* Power Sense Port1 IntEn */
+#define UHCHIE_TAIE	(1 << 10)	/* HCI Interface Transfer Abort
+					   Interrupt Enable*/
+#define UHCHIE_HBAIE	(1 << 8)	/* HCI Buffer Active IntEn */
+#define UHCHIE_RWIE	(1 << 7)	/* Remote Wake-up IntEn */
+
+#define UHCHIT          __REG(0x4C00006C) /* UHC Interrupt Test register */
+
+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
+
 /* PWRMODE register M field values */
 
 #define PWRMODE_IDLE		0x1
diff --git a/include/asm-arm/arch-pxa/pxa2xx-regs.h b/include/asm-arm/arch-pxa/pxa2xx-regs.h
new file mode 100644
index 0000000..9553b54
--- /dev/null
+++ b/include/asm-arm/arch-pxa/pxa2xx-regs.h
@@ -0,0 +1,84 @@
+/*
+ *  linux/include/asm-arm/arch-pxa/pxa2xx-regs.h
+ *
+ *  Taken from pxa-regs.h by Russell King
+ *
+ *  Author:	Nicolas Pitre
+ *  Copyright:	MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PXA2XX_REGS_H
+#define __PXA2XX_REGS_H
+
+/*
+ * Memory controller
+ */
+
+#define MDCNFG		__REG(0x48000000)  /* SDRAM Configuration Register 0 */
+#define MDREFR		__REG(0x48000004)  /* SDRAM Refresh Control Register */
+#define MSC0		__REG(0x48000008)  /* Static Memory Control Register 0 */
+#define MSC1		__REG(0x4800000C)  /* Static Memory Control Register 1 */
+#define MSC2		__REG(0x48000010)  /* Static Memory Control Register 2 */
+#define MECR		__REG(0x48000014)  /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
+#define SXLCR		__REG(0x48000018)  /* LCR value to be written to SDRAM-Timing Synchronous Flash */
+#define SXCNFG		__REG(0x4800001C)  /* Synchronous Static Memory Control Register */
+#define SXMRS		__REG(0x48000024)  /* MRS value to be written to Synchronous Flash or SMROM */
+#define MCMEM0		__REG(0x48000028)  /* Card interface Common Memory Space Socket 0 Timing */
+#define MCMEM1		__REG(0x4800002C)  /* Card interface Common Memory Space Socket 1 Timing */
+#define MCATT0		__REG(0x48000030)  /* Card interface Attribute Space Socket 0 Timing Configuration */
+#define MCATT1		__REG(0x48000034)  /* Card interface Attribute Space Socket 1 Timing Configuration */
+#define MCIO0		__REG(0x48000038)  /* Card interface I/O Space Socket 0 Timing Configuration */
+#define MCIO1		__REG(0x4800003C)  /* Card interface I/O Space Socket 1 Timing Configuration */
+#define MDMRS		__REG(0x48000040)  /* MRS value to be written to SDRAM */
+#define BOOT_DEF	__REG(0x48000044)  /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
+
+/*
+ * More handy macros for PCMCIA
+ *
+ * Arg is socket number
+ */
+#define MCMEM(s)	__REG2(0x48000028, (s)<<2 )  /* Card interface Common Memory Space Socket s Timing */
+#define MCATT(s)	__REG2(0x48000030, (s)<<2 )  /* Card interface Attribute Space Socket s Timing Configuration */
+#define MCIO(s)		__REG2(0x48000038, (s)<<2 )  /* Card interface I/O Space Socket s Timing Configuration */
+
+/* MECR register defines */
+#define MECR_NOS	(1 << 0)	/* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
+#define MECR_CIT	(1 << 1)	/* Card Is There: 0 -> no card, 1 -> card inserted */
+
+#define MDREFR_K0DB4	(1 << 29)	/* SDCLK0 Divide by 4 Control/Status */
+#define MDREFR_K2FREE	(1 << 25)	/* SDRAM Free-Running Control */
+#define MDREFR_K1FREE	(1 << 24)	/* SDRAM Free-Running Control */
+#define MDREFR_K0FREE	(1 << 23)	/* SDRAM Free-Running Control */
+#define MDREFR_SLFRSH	(1 << 22)	/* SDRAM Self-Refresh Control/Status */
+#define MDREFR_APD	(1 << 20)	/* SDRAM/SSRAM Auto-Power-Down Enable */
+#define MDREFR_K2DB2	(1 << 19)	/* SDCLK2 Divide by 2 Control/Status */
+#define MDREFR_K2RUN	(1 << 18)	/* SDCLK2 Run Control/Status */
+#define MDREFR_K1DB2	(1 << 17)	/* SDCLK1 Divide by 2 Control/Status */
+#define MDREFR_K1RUN	(1 << 16)	/* SDCLK1 Run Control/Status */
+#define MDREFR_E1PIN	(1 << 15)	/* SDCKE1 Level Control/Status */
+#define MDREFR_K0DB2	(1 << 14)	/* SDCLK0 Divide by 2 Control/Status */
+#define MDREFR_K0RUN	(1 << 13)	/* SDCLK0 Run Control/Status */
+#define MDREFR_E0PIN	(1 << 12)	/* SDCKE0 Level Control/Status */
+
+
+#ifdef CONFIG_PXA27x
+
+#define ARB_CNTRL	__REG(0x48000048)  /* Arbiter Control Register */
+
+#define ARB_DMA_SLV_PARK	(1<<31)	   /* Be parked with DMA slave when idle */
+#define ARB_CI_PARK		(1<<30)	   /* Be parked with Camera Interface when idle */
+#define ARB_EX_MEM_PARK 	(1<<29)	   /* Be parked with external MEMC when idle */
+#define ARB_INT_MEM_PARK	(1<<28)	   /* Be parked with internal MEMC when idle */
+#define ARB_USB_PARK		(1<<27)	   /* Be parked with USB when idle */
+#define ARB_LCD_PARK		(1<<26)	   /* Be parked with LCD when idle */
+#define ARB_DMA_PARK		(1<<25)	   /* Be parked with DMA when idle */
+#define ARB_CORE_PARK		(1<<24)	   /* Be parked with core when idle */
+#define ARB_LOCK_FLAG		(1<<23)	   /* Only Locking masters gain access to the bus */
+
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-pxa/pxa2xx_spi.h b/include/asm-arm/arch-pxa/pxa2xx_spi.h
index acc7ec7..3459fb2 100644
--- a/include/asm-arm/arch-pxa/pxa2xx_spi.h
+++ b/include/asm-arm/arch-pxa/pxa2xx_spi.h
@@ -22,32 +22,8 @@
 #define PXA2XX_CS_ASSERT (0x01)
 #define PXA2XX_CS_DEASSERT (0x02)
 
-#if defined(CONFIG_PXA25x)
-#define CLOCK_SPEED_HZ 3686400
-#define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/2/(x+1))<<8)&0x0000ff00)
-#define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-#define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-#elif defined(CONFIG_PXA27x)
-#define CLOCK_SPEED_HZ 13000000
-#define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-#define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-#define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-#endif
-
-#define SSP1_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(1)))))
-#define SSP2_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(2)))))
-#define SSP3_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(3)))))
-
-enum pxa_ssp_type {
-	SSP_UNDEFINED = 0,
-	PXA25x_SSP,  /* pxa 210, 250, 255, 26x */
-	PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
-	PXA27x_SSP,
-};
-
 /* device.platform_data for SSP controller devices */
 struct pxa2xx_spi_master {
-	enum pxa_ssp_type ssp_type;
 	u32 clock_enable;
 	u16 num_chipselect;
 	u8 enable_dma;
diff --git a/include/asm-arm/arch-pxa/pxa3xx-regs.h b/include/asm-arm/arch-pxa/pxa3xx-regs.h
index 3900a0c..66d5411 100644
--- a/include/asm-arm/arch-pxa/pxa3xx-regs.h
+++ b/include/asm-arm/arch-pxa/pxa3xx-regs.h
@@ -14,6 +14,92 @@
 #define __ASM_ARCH_PXA3XX_REGS_H
 
 /*
+ * Slave Power Managment Unit
+ */
+#define ASCR		__REG(0x40f40000)	/* Application Subsystem Power Status/Configuration */
+#define ARSR		__REG(0x40f40004)	/* Application Subsystem Reset Status */
+#define AD3ER		__REG(0x40f40008)	/* Application Subsystem Wake-Up from D3 Enable */
+#define AD3SR		__REG(0x40f4000c)	/* Application Subsystem Wake-Up from D3 Status */
+#define AD2D0ER		__REG(0x40f40010)	/* Application Subsystem Wake-Up from D2 to D0 Enable */
+#define AD2D0SR		__REG(0x40f40014)	/* Application Subsystem Wake-Up from D2 to D0 Status */
+#define AD2D1ER		__REG(0x40f40018)	/* Application Subsystem Wake-Up from D2 to D1 Enable */
+#define AD2D1SR		__REG(0x40f4001c)	/* Application Subsystem Wake-Up from D2 to D1 Status */
+#define AD1D0ER		__REG(0x40f40020)	/* Application Subsystem Wake-Up from D1 to D0 Enable */
+#define AD1D0SR		__REG(0x40f40024)	/* Application Subsystem Wake-Up from D1 to D0 Status */
+#define AGENP		__REG(0x40f4002c)	/* Application Subsystem General Purpose */
+#define AD3R		__REG(0x40f40030)	/* Application Subsystem D3 Configuration */
+#define AD2R		__REG(0x40f40034)	/* Application Subsystem D2 Configuration */
+#define AD1R		__REG(0x40f40038)	/* Application Subsystem D1 Configuration */
+
+/*
+ * Application Subsystem Configuration bits.
+ */
+#define ASCR_RDH		(1 << 31)
+#define ASCR_D1S		(1 << 2)
+#define ASCR_D2S		(1 << 1)
+#define ASCR_D3S		(1 << 0)
+
+/*
+ * Application Reset Status bits.
+ */
+#define ARSR_GPR		(1 << 3)
+#define ARSR_LPMR		(1 << 2)
+#define ARSR_WDT		(1 << 1)
+#define ARSR_HWR		(1 << 0)
+
+/*
+ * Application Subsystem Wake-Up bits.
+ */
+#define ADXER_WRTC		(1 << 31)	/* RTC */
+#define ADXER_WOST		(1 << 30)	/* OS Timer */
+#define ADXER_WTSI		(1 << 29)	/* Touchscreen */
+#define ADXER_WUSBH		(1 << 28)	/* USB host */
+#define ADXER_WUSB2		(1 << 26)	/* USB client 2.0 */
+#define ADXER_WMSL0		(1 << 24)	/* MSL port 0*/
+#define ADXER_WDMUX3		(1 << 23)	/* USB EDMUX3 */
+#define ADXER_WDMUX2		(1 << 22)	/* USB EDMUX2 */
+#define ADXER_WKP		(1 << 21)	/* Keypad */
+#define ADXER_WUSIM1		(1 << 20)	/* USIM Port 1 */
+#define ADXER_WUSIM0		(1 << 19)	/* USIM Port 0 */
+#define ADXER_WOTG		(1 << 16)	/* USBOTG input */
+#define ADXER_MFP_WFLASH	(1 << 15)	/* MFP: Data flash busy */
+#define ADXER_MFP_GEN12		(1 << 14)	/* MFP: MMC3/GPIO/OST inputs */
+#define ADXER_MFP_WMMC2		(1 << 13)	/* MFP: MMC2 */
+#define ADXER_MFP_WMMC1		(1 << 12)	/* MFP: MMC1 */
+#define ADXER_MFP_WI2C		(1 << 11)	/* MFP: I2C */
+#define ADXER_MFP_WSSP4		(1 << 10)	/* MFP: SSP4 */
+#define ADXER_MFP_WSSP3		(1 << 9)	/* MFP: SSP3 */
+#define ADXER_MFP_WMAXTRIX	(1 << 8)	/* MFP: matrix keypad */
+#define ADXER_MFP_WUART3	(1 << 7)	/* MFP: UART3 */
+#define ADXER_MFP_WUART2	(1 << 6)	/* MFP: UART2 */
+#define ADXER_MFP_WUART1	(1 << 5)	/* MFP: UART1 */
+#define ADXER_MFP_WSSP2		(1 << 4)	/* MFP: SSP2 */
+#define ADXER_MFP_WSSP1		(1 << 3)	/* MFP: SSP1 */
+#define ADXER_MFP_WAC97		(1 << 2)	/* MFP: AC97 */
+#define ADXER_WEXTWAKE1		(1 << 1)	/* External Wake 1 */
+#define ADXER_WEXTWAKE0		(1 << 0)	/* External Wake 0 */
+
+/*
+ * AD3R/AD2R/AD1R bits.  R2-R5 are only defined for PXA320.
+ */
+#define ADXR_L2			(1 << 8)
+#define ADXR_R5			(1 << 5)
+#define ADXR_R4			(1 << 4)
+#define ADXR_R3			(1 << 3)
+#define ADXR_R2			(1 << 2)
+#define ADXR_R1			(1 << 1)
+#define ADXR_R0			(1 << 0)
+
+/*
+ * Values for PWRMODE CP15 register
+ */
+#define PXA3xx_PM_S3D4C4	0x07	/* aka deep sleep */
+#define PXA3xx_PM_S2D3C4	0x06	/* aka sleep */
+#define PXA3xx_PM_S0D2C2	0x03	/* aka standby */
+#define PXA3xx_PM_S0D1C2	0x02	/* aka LCD refresh */
+#define PXA3xx_PM_S0D0C1	0x01
+
+/*
  * Application Subsystem Clock
  */
 #define ACCR		__REG(0x41340000)	/* Application Subsystem Clock Configuration Register */
diff --git a/include/asm-arm/arch-pxa/regs-ssp.h b/include/asm-arm/arch-pxa/regs-ssp.h
new file mode 100644
index 0000000..991cb68
--- /dev/null
+++ b/include/asm-arm/arch-pxa/regs-ssp.h
@@ -0,0 +1,112 @@
+#ifndef __ASM_ARCH_REGS_SSP_H
+#define __ASM_ARCH_REGS_SSP_H
+
+/*
+ * SSP Serial Port Registers
+ * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different.
+ * PXA255, PXA26x and PXA27x have extra ports, registers and bits.
+ */
+
+#define SSCR0		(0x00)  /* SSP Control Register 0 */
+#define SSCR1		(0x04)  /* SSP Control Register 1 */
+#define SSSR		(0x08)  /* SSP Status Register */
+#define SSITR		(0x0C)  /* SSP Interrupt Test Register */
+#define SSDR		(0x10)  /* SSP Data Write/Data Read Register */
+
+#define SSTO		(0x28)  /* SSP Time Out Register */
+#define SSPSP		(0x2C)  /* SSP Programmable Serial Protocol */
+#define SSTSA		(0x30)  /* SSP Tx Timeslot Active */
+#define SSRSA		(0x34)  /* SSP Rx Timeslot Active */
+#define SSTSS		(0x38)  /* SSP Timeslot Status */
+#define SSACD		(0x3C)  /* SSP Audio Clock Divider */
+
+/* Common PXA2xx bits first */
+#define SSCR0_DSS	(0x0000000f)	/* Data Size Select (mask) */
+#define SSCR0_DataSize(x)  ((x) - 1)	/* Data Size Select [4..16] */
+#define SSCR0_FRF	(0x00000030)	/* FRame Format (mask) */
+#define SSCR0_Motorola	(0x0 << 4)	/* Motorola's Serial Peripheral Interface (SPI) */
+#define SSCR0_TI	(0x1 << 4)	/* Texas Instruments' Synchronous Serial Protocol (SSP) */
+#define SSCR0_National	(0x2 << 4)	/* National Microwire */
+#define SSCR0_ECS	(1 << 6)	/* External clock select */
+#define SSCR0_SSE	(1 << 7)	/* Synchronous Serial Port Enable */
+#if defined(CONFIG_PXA25x)
+#define SSCR0_SCR	(0x0000ff00)	/* Serial Clock Rate (mask) */
+#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */
+#elif defined(CONFIG_PXA27x)
+#define SSCR0_SCR	(0x000fff00)	/* Serial Clock Rate (mask) */
+#define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */
+#define SSCR0_EDSS	(1 << 20)	/* Extended data size select */
+#define SSCR0_NCS	(1 << 21)	/* Network clock select */
+#define SSCR0_RIM	(1 << 22)	/* Receive FIFO overrrun interrupt mask */
+#define SSCR0_TUM	(1 << 23)	/* Transmit FIFO underrun interrupt mask */
+#define SSCR0_FRDC	(0x07000000)	/* Frame rate divider control (mask) */
+#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24)	/* Time slots per frame [1..8] */
+#define SSCR0_ADC	(1 << 30)	/* Audio clock select */
+#define SSCR0_MOD	(1 << 31)	/* Mode (normal or network) */
+#endif
+
+#define SSCR1_RIE	(1 << 0)	/* Receive FIFO Interrupt Enable */
+#define SSCR1_TIE	(1 << 1)	/* Transmit FIFO Interrupt Enable */
+#define SSCR1_LBM	(1 << 2)	/* Loop-Back Mode */
+#define SSCR1_SPO	(1 << 3)	/* Motorola SPI SSPSCLK polarity setting */
+#define SSCR1_SPH	(1 << 4)	/* Motorola SPI SSPSCLK phase setting */
+#define SSCR1_MWDS	(1 << 5)	/* Microwire Transmit Data Size */
+#define SSCR1_TFT	(0x000003c0)	/* Transmit FIFO Threshold (mask) */
+#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
+#define SSCR1_RFT	(0x00003c00)	/* Receive FIFO Threshold (mask) */
+#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */
+
+#define SSSR_TNF	(1 << 2)	/* Transmit FIFO Not Full */
+#define SSSR_RNE	(1 << 3)	/* Receive FIFO Not Empty */
+#define SSSR_BSY	(1 << 4)	/* SSP Busy */
+#define SSSR_TFS	(1 << 5)	/* Transmit FIFO Service Request */
+#define SSSR_RFS	(1 << 6)	/* Receive FIFO Service Request */
+#define SSSR_ROR	(1 << 7)	/* Receive FIFO Overrun */
+
+#define SSCR0_TIM		(1 << 23)	/* Transmit FIFO Under Run Interrupt Mask */
+#define SSCR0_RIM		(1 << 22)	/* Receive FIFO Over Run interrupt Mask */
+#define SSCR0_NCS		(1 << 21)	/* Network Clock Select */
+#define SSCR0_EDSS		(1 << 20)	/* Extended Data Size Select */
+
+/* extra bits in PXA255, PXA26x and PXA27x SSP ports */
+#define SSCR0_TISSP		(1 << 4)	/* TI Sync Serial Protocol */
+#define SSCR0_PSP		(3 << 4)	/* PSP - Programmable Serial Protocol */
+#define SSCR1_TTELP		(1 << 31)	/* TXD Tristate Enable Last Phase */
+#define SSCR1_TTE		(1 << 30)	/* TXD Tristate Enable */
+#define SSCR1_EBCEI		(1 << 29)	/* Enable Bit Count Error interrupt */
+#define SSCR1_SCFR		(1 << 28)	/* Slave Clock free Running */
+#define SSCR1_ECRA		(1 << 27)	/* Enable Clock Request A */
+#define SSCR1_ECRB		(1 << 26)	/* Enable Clock request B */
+#define SSCR1_SCLKDIR		(1 << 25)	/* Serial Bit Rate Clock Direction */
+#define SSCR1_SFRMDIR		(1 << 24)	/* Frame Direction */
+#define SSCR1_RWOT		(1 << 23)	/* Receive Without Transmit */
+#define SSCR1_TRAIL		(1 << 22)	/* Trailing Byte */
+#define SSCR1_TSRE		(1 << 21)	/* Transmit Service Request Enable */
+#define SSCR1_RSRE		(1 << 20)	/* Receive Service Request Enable */
+#define SSCR1_TINTE		(1 << 19)	/* Receiver Time-out Interrupt enable */
+#define SSCR1_PINTE		(1 << 18)	/* Peripheral Trailing Byte Interupt Enable */
+#define SSCR1_STRF		(1 << 15)	/* Select FIFO or EFWR */
+#define SSCR1_EFWR		(1 << 14)	/* Enable FIFO Write/Read */
+
+#define SSSR_BCE		(1 << 23)	/* Bit Count Error */
+#define SSSR_CSS		(1 << 22)	/* Clock Synchronisation Status */
+#define SSSR_TUR		(1 << 21)	/* Transmit FIFO Under Run */
+#define SSSR_EOC		(1 << 20)	/* End Of Chain */
+#define SSSR_TINT		(1 << 19)	/* Receiver Time-out Interrupt */
+#define SSSR_PINT		(1 << 18)	/* Peripheral Trailing Byte Interrupt */
+
+#define SSPSP_FSRT		(1 << 25)	/* Frame Sync Relative Timing */
+#define SSPSP_DMYSTOP(x)	((x) << 23)	/* Dummy Stop */
+#define SSPSP_SFRMWDTH(x)	((x) << 16)	/* Serial Frame Width */
+#define SSPSP_SFRMDLY(x)	((x) << 9)	/* Serial Frame Delay */
+#define SSPSP_DMYSTRT(x)	((x) << 7)	/* Dummy Start */
+#define SSPSP_STRTDLY(x)	((x) << 4)	/* Start Delay */
+#define SSPSP_ETDS		(1 << 3)	/* End of Transfer data State */
+#define SSPSP_SFRMP		(1 << 2)	/* Serial Frame Polarity */
+#define SSPSP_SCMODE(x)		((x) << 0)	/* Serial Bit Rate Clock Mode */
+
+#define SSACD_SCDB		(1 << 3)	/* SSPSYSCLK Divider Bypass */
+#define SSACD_ACPS(x)		((x) << 4)	/* Audio clock PLL select */
+#define SSACD_ACDS(x)		((x) << 0)	/* Audio clock divider select */
+
+#endif /* __ASM_ARCH_REGS_SSP_H */
diff --git a/include/asm-arm/arch-pxa/sharpsl.h b/include/asm-arm/arch-pxa/sharpsl.h
index 2b0fe77..3b1d4a7 100644
--- a/include/asm-arm/arch-pxa/sharpsl.h
+++ b/include/asm-arm/arch-pxa/sharpsl.h
@@ -16,7 +16,7 @@
  */
 
 struct corgits_machinfo {
-	unsigned long (*get_hsync_len)(void);
+	unsigned long (*get_hsync_invperiod)(void);
 	void (*put_hsync)(void);
 	void (*wait_hsync)(void);
 };
diff --git a/include/asm-arm/arch-pxa/spitz.h b/include/asm-arm/arch-pxa/spitz.h
index 4953dd32..bd14365 100644
--- a/include/asm-arm/arch-pxa/spitz.h
+++ b/include/asm-arm/arch-pxa/spitz.h
@@ -156,5 +156,3 @@
 extern struct platform_device spitzscoop2_device;
 extern struct platform_device spitzssp_device;
 extern struct sharpsl_charger_machinfo spitz_pm_machinfo;
-
-extern void spitz_lcd_power(int on, struct fb_var_screeninfo *var);
diff --git a/include/asm-arm/arch-pxa/ssp.h b/include/asm-arm/arch-pxa/ssp.h
index ea20055..a012882 100644
--- a/include/asm-arm/arch-pxa/ssp.h
+++ b/include/asm-arm/arch-pxa/ssp.h
@@ -13,10 +13,37 @@
  *       PXA255     SSP, NSSP
  *       PXA26x     SSP, NSSP, ASSP
  *       PXA27x     SSP1, SSP2, SSP3
+ *       PXA3xx     SSP1, SSP2, SSP3, SSP4
  */
 
-#ifndef SSP_H
-#define SSP_H
+#ifndef __ASM_ARCH_SSP_H
+#define __ASM_ARCH_SSP_H
+
+#include <linux/list.h>
+
+enum pxa_ssp_type {
+	SSP_UNDEFINED = 0,
+	PXA25x_SSP,  /* pxa 210, 250, 255, 26x */
+	PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
+	PXA27x_SSP,
+};
+
+struct ssp_device {
+	struct platform_device *pdev;
+	struct list_head	node;
+
+	struct clk	*clk;
+	void __iomem	*mmio_base;
+	unsigned long	phys_base;
+
+	const char	*label;
+	int		port_id;
+	int		type;
+	int		use_count;
+	int		irq;
+	int		drcmr_rx;
+	int		drcmr_tx;
+};
 
 /*
  * SSP initialisation flags
@@ -31,6 +58,7 @@
 };
 
 struct ssp_dev {
+	struct ssp_device *ssp;
 	u32 port;
 	u32 mode;
 	u32 flags;
@@ -50,4 +78,6 @@
 int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
 void ssp_exit(struct ssp_dev *dev);
 
-#endif
+struct ssp_device *ssp_request(int port, const char *label);
+void ssp_free(struct ssp_device *);
+#endif /* __ASM_ARCH_SSP_H */
diff --git a/include/asm-arm/arch-pxa/uncompress.h b/include/asm-arm/arch-pxa/uncompress.h
index 178aa2e..dadf4c2 100644
--- a/include/asm-arm/arch-pxa/uncompress.h
+++ b/include/asm-arm/arch-pxa/uncompress.h
@@ -9,19 +9,21 @@
  * published by the Free Software Foundation.
  */
 
-#define FFUART		((volatile unsigned long *)0x40100000)
-#define BTUART		((volatile unsigned long *)0x40200000)
-#define STUART		((volatile unsigned long *)0x40700000)
-#define HWUART		((volatile unsigned long *)0x41600000)
+#include <linux/serial_reg.h>
+#include <asm/arch/pxa-regs.h>
+
+#define __REG(x)	((volatile unsigned long *)x)
 
 #define UART		FFUART
 
 
 static inline void putc(char c)
 {
-	while (!(UART[5] & 0x20))
+	if (!(UART[UART_IER] & IER_UUE))
+		return;
+	while (!(UART[UART_LSR] & LSR_TDRQ))
 		barrier();
-	UART[0] = c;
+	UART[UART_TX] = c;
 }
 
 /*
diff --git a/include/asm-arm/arch-pxa/zylonite.h b/include/asm-arm/arch-pxa/zylonite.h
index f58b591..5f717d6 100644
--- a/include/asm-arm/arch-pxa/zylonite.h
+++ b/include/asm-arm/arch-pxa/zylonite.h
@@ -3,9 +3,18 @@
 
 #define ZYLONITE_ETH_PHYS	0x14000000
 
+#define EXT_GPIO(x)		(128 + (x))
+
 /* the following variables are processor specific and initialized
  * by the corresponding zylonite_pxa3xx_init()
  */
+struct platform_mmc_slot {
+	int gpio_cd;
+	int gpio_wp;
+};
+
+extern struct platform_mmc_slot zylonite_mmc_slot[];
+
 extern int gpio_backlight;
 extern int gpio_eth_irq;
 
diff --git a/include/asm-arm/arch-s3c2410/debug-macro.S b/include/asm-arm/arch-s3c2410/debug-macro.S
index 9c8cd9a..89076c3 100644
--- a/include/asm-arm/arch-s3c2410/debug-macro.S
+++ b/include/asm-arm/arch-s3c2410/debug-macro.S
@@ -92,11 +92,9 @@
 #if defined(CONFIG_CPU_LLSERIAL_S3C2410_ONLY)
 #define fifo_full  fifo_full_s3c2410
 #define fifo_level fifo_level_s3c2410
-#warning 2410only
 #elif !defined(CONFIG_CPU_LLSERIAL_S3C2440_ONLY)
 #define fifo_full  fifo_full_s3c24xx
 #define fifo_level fifo_level_s3c24xx
-#warning generic
 #endif
 
 /* include the reset of the code which will do the work */
diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h
index c6e8d8f..4f291d9 100644
--- a/include/asm-arm/arch-s3c2410/dma.h
+++ b/include/asm-arm/arch-s3c2410/dma.h
@@ -214,6 +214,7 @@
 	unsigned long		 dev_addr;
 	unsigned long		 load_timeout;
 	unsigned int		 flags;		/* channel flags */
+	unsigned int		 hw_cfg;	/* last hw config */
 
 	struct s3c24xx_dma_map	*map;		/* channel hw maps */
 
diff --git a/include/asm-arm/arch-s3c2410/hardware.h b/include/asm-arm/arch-s3c2410/hardware.h
index 6dadf58..29592c3 100644
--- a/include/asm-arm/arch-s3c2410/hardware.h
+++ b/include/asm-arm/arch-s3c2410/hardware.h
@@ -50,6 +50,17 @@
 
 extern int s3c2410_gpio_getirq(unsigned int pin);
 
+/* s3c2410_gpio_irq2pin
+ *
+ * turn the given irq number into the corresponding GPIO number
+ *
+ * returns:
+ *	< 0 = no pin
+ *	>=0 = gpio pin number
+*/
+
+extern int s3c2410_gpio_irq2pin(unsigned int irq);
+
 #ifdef CONFIG_CPU_S3C2400
 
 extern int s3c2400_gpio_getirq(unsigned int pin);
@@ -87,6 +98,18 @@
 
 extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
 
+/* s3c2410_gpio_getpull
+ *
+ * Read the state of the pull-up on a given pin
+ *
+ * return:
+ *	< 0 => error code
+ *	  0 => enabled
+ *	  1 => disabled
+*/
+
+extern int s3c2410_gpio_getpull(unsigned int pin);
+
 extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
 
 extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
@@ -99,6 +122,11 @@
 
 #endif /* CONFIG_CPU_S3C2440 */
 
+#ifdef CONFIG_CPU_S3C2412
+
+extern int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state);
+
+#endif /* CONFIG_CPU_S3C2412 */
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h
index 996f654..d858b3e 100644
--- a/include/asm-arm/arch-s3c2410/irqs.h
+++ b/include/asm-arm/arch-s3c2410/irqs.h
@@ -160,4 +160,7 @@
 #define NR_IRQS (IRQ_S3C2440_AC97+1)
 #endif
 
+/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */
+#define FIQ_START		IRQ_EINT0
+
 #endif /* __ASM_ARCH_IRQ_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-clock.h b/include/asm-arm/arch-s3c2410/regs-clock.h
index e39656b..dba9df9 100644
--- a/include/asm-arm/arch-s3c2410/regs-clock.h
+++ b/include/asm-arm/arch-s3c2410/regs-clock.h
@@ -138,6 +138,8 @@
 #define S3C2412_CLKDIVN_PDIVN		(1<<2)
 #define S3C2412_CLKDIVN_HDIVN_MASK	(3<<0)
 #define S3C2421_CLKDIVN_ARMDIVN		(1<<3)
+#define S3C2412_CLKDIVN_DVSEN		(1<<4)
+#define S3C2412_CLKDIVN_HALFHCLK	(1<<5)
 #define S3C2412_CLKDIVN_USB48DIV	(1<<6)
 #define S3C2412_CLKDIVN_UARTDIV_MASK	(15<<8)
 #define S3C2412_CLKDIVN_UARTDIV_SHIFT	(8)
diff --git a/include/asm-arm/arch-s3c2410/regs-dsc.h b/include/asm-arm/arch-s3c2410/regs-dsc.h
index c074851..1235df7 100644
--- a/include/asm-arm/arch-s3c2410/regs-dsc.h
+++ b/include/asm-arm/arch-s3c2410/regs-dsc.h
@@ -19,7 +19,7 @@
 #define S3C2412_DSC1	   S3C2410_GPIOREG(0xe0)
 #endif
 
-#if defined(CONFIG_CPU_S3C2440)
+#if defined(CONFIG_CPU_S3C244X)
 
 #define S3C2440_DSC0	   S3C2410_GPIOREG(0xc4)
 #define S3C2440_DSC1	   S3C2410_GPIOREG(0xc8)
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index b693158..0ad75d7 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -1133,12 +1133,16 @@
 #define S3C2412_GPBSLPCON	S3C2410_GPIOREG(0x1C)
 #define S3C2412_GPCSLPCON	S3C2410_GPIOREG(0x2C)
 #define S3C2412_GPDSLPCON	S3C2410_GPIOREG(0x3C)
-#define S3C2412_GPESLPCON	S3C2410_GPIOREG(0x4C)
 #define S3C2412_GPFSLPCON	S3C2410_GPIOREG(0x5C)
 #define S3C2412_GPGSLPCON	S3C2410_GPIOREG(0x6C)
 #define S3C2412_GPHSLPCON	S3C2410_GPIOREG(0x7C)
 
 /* definitions for each pin bit */
+#define S3C2412_GPIO_SLPCON_LOW	 ( 0x00 )
+#define S3C2412_GPIO_SLPCON_HIGH ( 0x01 )
+#define S3C2412_GPIO_SLPCON_IN   ( 0x02 )
+#define S3C2412_GPIO_SLPCON_PULL ( 0x03 )
+
 #define S3C2412_SLPCON_LOW(x)	( 0x00 << ((x) * 2))
 #define S3C2412_SLPCON_HIGH(x)	( 0x01 << ((x) * 2))
 #define S3C2412_SLPCON_IN(x)	( 0x02 << ((x) * 2))
diff --git a/include/asm-arm/arch-s3c2410/regs-mem.h b/include/asm-arm/arch-s3c2410/regs-mem.h
index e4d8234..312ff93 100644
--- a/include/asm-arm/arch-s3c2410/regs-mem.h
+++ b/include/asm-arm/arch-s3c2410/regs-mem.h
@@ -98,16 +98,19 @@
 #define S3C2410_BANKCON_Tacp3		(0x1 << 2)
 #define S3C2410_BANKCON_Tacp4		(0x2 << 2)
 #define S3C2410_BANKCON_Tacp6		(0x3 << 2)
+#define S3C2410_BANKCON_Tacp_SHIFT	(2)
 
 #define S3C2410_BANKCON_Tcah0		(0x0 << 4)
 #define S3C2410_BANKCON_Tcah1		(0x1 << 4)
 #define S3C2410_BANKCON_Tcah2		(0x2 << 4)
 #define S3C2410_BANKCON_Tcah4		(0x3 << 4)
+#define S3C2410_BANKCON_Tcah_SHIFT	(4)
 
 #define S3C2410_BANKCON_Tcoh0		(0x0 << 6)
 #define S3C2410_BANKCON_Tcoh1		(0x1 << 6)
 #define S3C2410_BANKCON_Tcoh2		(0x2 << 6)
 #define S3C2410_BANKCON_Tcoh4		(0x3 << 6)
+#define S3C2410_BANKCON_Tcoh_SHIFT	(6)
 
 #define S3C2410_BANKCON_Tacc1		(0x0 << 8)
 #define S3C2410_BANKCON_Tacc2		(0x1 << 8)
@@ -117,16 +120,19 @@
 #define S3C2410_BANKCON_Tacc8		(0x5 << 8)
 #define S3C2410_BANKCON_Tacc10		(0x6 << 8)
 #define S3C2410_BANKCON_Tacc14		(0x7 << 8)
+#define S3C2410_BANKCON_Tacc_SHIFT	(8)
 
 #define S3C2410_BANKCON_Tcos0		(0x0 << 11)
 #define S3C2410_BANKCON_Tcos1		(0x1 << 11)
 #define S3C2410_BANKCON_Tcos2		(0x2 << 11)
 #define S3C2410_BANKCON_Tcos4		(0x3 << 11)
+#define S3C2410_BANKCON_Tcos_SHIFT	(11)
 
 #define S3C2410_BANKCON_Tacs0		(0x0 << 13)
 #define S3C2410_BANKCON_Tacs1		(0x1 << 13)
 #define S3C2410_BANKCON_Tacs2		(0x2 << 13)
 #define S3C2410_BANKCON_Tacs4		(0x3 << 13)
+#define S3C2410_BANKCON_Tacs_SHIFT	(13)
 
 #define S3C2410_BANKCON_SRAM		(0x0 << 15)
 #define S3C2400_BANKCON_EDODRAM		(0x2 << 15)
diff --git a/include/asm-arm/arch-s3c2410/regs-power.h b/include/asm-arm/arch-s3c2410/regs-power.h
index f79987b..13d13b7 100644
--- a/include/asm-arm/arch-s3c2410/regs-power.h
+++ b/include/asm-arm/arch-s3c2410/regs-power.h
@@ -23,7 +23,8 @@
 #define S3C2412_INFORM2		S3C24XX_PWRREG(0x78)
 #define S3C2412_INFORM3		S3C24XX_PWRREG(0x7C)
 
-#define S3C2412_PWRCFG_BATF_IGNORE		(0<<0)
+#define S3C2412_PWRCFG_BATF_IRQ			(1<<0)
+#define S3C2412_PWRCFG_BATF_IGNORE		(2<<0)
 #define S3C2412_PWRCFG_BATF_SLEEP		(3<<0)
 #define S3C2412_PWRCFG_BATF_MASK		(3<<0)
 
diff --git a/include/asm-arm/arch-s3c2410/system.h b/include/asm-arm/arch-s3c2410/system.h
index 6389178..14de4e5 100644
--- a/include/asm-arm/arch-s3c2410/system.h
+++ b/include/asm-arm/arch-s3c2410/system.h
@@ -20,6 +20,9 @@
 #include <asm/plat-s3c/regs-watchdog.h>
 #include <asm/arch/regs-clock.h>
 
+#include <linux/clk.h>
+#include <linux/err.h>
+
 void (*s3c24xx_idle)(void);
 void (*s3c24xx_reset_hook)(void);
 
@@ -59,6 +62,8 @@
 static void
 arch_reset(char mode)
 {
+	struct clk *wdtclk;
+
 	if (mode == 's') {
 		cpu_reset(0);
 	}
@@ -70,19 +75,28 @@
 
 	__raw_writel(0, S3C2410_WTCON);	  /* disable watchdog, to be safe  */
 
+	wdtclk = clk_get(NULL, "watchdog");
+	if (!IS_ERR(wdtclk)) {
+		clk_enable(wdtclk);
+	} else
+		printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
+
 	/* put initial values into count and data */
-	__raw_writel(0x100, S3C2410_WTCNT);
-	__raw_writel(0x100, S3C2410_WTDAT);
+	__raw_writel(0x80, S3C2410_WTCNT);
+	__raw_writel(0x80, S3C2410_WTDAT);
 
 	/* set the watchdog to go and reset... */
 	__raw_writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16|S3C2410_WTCON_RSTEN |
 		     S3C2410_WTCON_PRESCALE(0x20), S3C2410_WTCON);
 
 	/* wait for reset to assert... */
-	mdelay(5000);
+	mdelay(500);
 
 	printk(KERN_ERR "Watchdog reset failed to assert reset\n");
 
+	/* delay to allow the serial port to show the message */
+	mdelay(50);
+
 	/* we'll take a jump through zero as a poor second */
 	cpu_reset(0);
 }
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index 6c1c968..759a97b 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -94,6 +94,14 @@
 # endif
 #endif
 
+#if defined(CONFIG_CPU_FEROCEON)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE feroceon
+# endif
+#endif
+
 #if defined(CONFIG_CPU_V6)
 //# ifdef _CACHE
 #  define MULTI_CACHE 1
diff --git a/include/asm-arm/fpstate.h b/include/asm-arm/fpstate.h
index f31cda5..392eb53 100644
--- a/include/asm-arm/fpstate.h
+++ b/include/asm-arm/fpstate.h
@@ -17,14 +17,18 @@
 /*
  * VFP storage area has:
  *  - FPEXC, FPSCR, FPINST and FPINST2.
- *  - 16 double precision data registers
- *  - an implementation-dependant word of state for FLDMX/FSTMX
+ *  - 16 or 32 double precision data registers
+ *  - an implementation-dependant word of state for FLDMX/FSTMX (pre-ARMv6)
  * 
  *  FPEXC will always be non-zero once the VFP has been used in this process.
  */
 
 struct vfp_hard_struct {
+#ifdef CONFIG_VFPv3
+	__u64 fpregs[32];
+#else
 	__u64 fpregs[16];
+#endif
 #if __LINUX_ARM_ARCH__ < 6
 	__u32 fpmx_state;
 #endif
@@ -35,6 +39,7 @@
 	 */
 	__u32 fpinst;
 	__u32 fpinst2;
+
 #ifdef CONFIG_SMP
 	__u32 cpu;
 #endif
diff --git a/include/asm-arm/kprobes.h b/include/asm-arm/kprobes.h
new file mode 100644
index 0000000..4e7bd32
--- /dev/null
+++ b/include/asm-arm/kprobes.h
@@ -0,0 +1,79 @@
+/*
+ * include/asm-arm/kprobes.h
+ *
+ * Copyright (C) 2006, 2007 Motorola Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _ARM_KPROBES_H
+#define _ARM_KPROBES_H
+
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/percpu.h>
+
+#define ARCH_SUPPORTS_KRETPROBES
+#define __ARCH_WANT_KPROBES_INSN_SLOT
+#define MAX_INSN_SIZE			2
+#define MAX_STACK_SIZE			64	/* 32 would probably be OK */
+
+/*
+ * This undefined instruction must be unique and
+ * reserved solely for kprobes' use.
+ */
+#define KPROBE_BREAKPOINT_INSTRUCTION	0xe7f001f8
+
+#define regs_return_value(regs)		((regs)->ARM_r0)
+#define flush_insn_slot(p)		do { } while (0)
+#define kretprobe_blacklist_size	0
+
+typedef u32 kprobe_opcode_t;
+
+struct kprobe;
+typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *);
+
+/* Architecture specific copy of original instruction. */
+struct arch_specific_insn {
+	kprobe_opcode_t		*insn;
+	kprobe_insn_handler_t	*insn_handler;
+};
+
+struct prev_kprobe {
+	struct kprobe *kp;
+	unsigned int status;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+	unsigned int kprobe_status;
+	struct prev_kprobe prev_kprobe;
+	struct pt_regs jprobe_saved_regs;
+	char jprobes_stack[MAX_STACK_SIZE];
+};
+
+void arch_remove_kprobe(struct kprobe *);
+
+int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr);
+int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
+int kprobe_exceptions_notify(struct notifier_block *self,
+			     unsigned long val, void *data);
+
+enum kprobe_insn {
+	INSN_REJECTED,
+	INSN_GOOD,
+	INSN_GOOD_NO_SLOT
+};
+
+enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t,
+					struct arch_specific_insn *);
+void __init arm_kprobe_decode_init(void);
+
+#endif /* _ARM_KPROBES_H */
diff --git a/include/asm-arm/plat-s3c24xx/dma.h b/include/asm-arm/plat-s3c24xx/dma.h
index 2c59406..c78efe3 100644
--- a/include/asm-arm/plat-s3c24xx/dma.h
+++ b/include/asm-arm/plat-s3c24xx/dma.h
@@ -32,6 +32,7 @@
 	struct s3c24xx_dma_addr  hw_addr;
 
 	unsigned long		 channels[S3C2410_DMA_CHANNELS];
+	unsigned long		 channels_rx[S3C2410_DMA_CHANNELS];
 };
 
 struct s3c24xx_dma_selection {
@@ -41,6 +42,10 @@
 
 	void	(*select)(struct s3c2410_dma_chan *chan,
 			  struct s3c24xx_dma_map *map);
+
+	void	(*direction)(struct s3c2410_dma_chan *chan,
+			     struct s3c24xx_dma_map *map,
+			     enum s3c2410_dmasrc dir);
 };
 
 extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
diff --git a/include/asm-arm/plat-s3c24xx/irq.h b/include/asm-arm/plat-s3c24xx/irq.h
index 8af6d95..45746a9 100644
--- a/include/asm-arm/plat-s3c24xx/irq.h
+++ b/include/asm-arm/plat-s3c24xx/irq.h
@@ -15,7 +15,9 @@
 
 #define EXTINT_OFF (IRQ_EINT4 - 4)
 
+/* these are exported for arch/arm/mach-* usage */
 extern struct irq_chip s3c_irq_level_chip;
+extern struct irq_chip s3c_irq_chip;
 
 static inline void
 s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
diff --git a/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h b/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h
new file mode 100644
index 0000000..25d4058
--- /dev/null
+++ b/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h
@@ -0,0 +1,72 @@
+/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h
+ *
+ * Copyright 2007 Simtec Electronics <linux@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2412 IIS register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H
+#define __ASM_ARCH_REGS_S3C2412_IIS_H
+
+#define S3C2412_IISCON			(0x00)
+#define S3C2412_IISMOD			(0x04)
+#define S3C2412_IISFIC			(0x08)
+#define S3C2412_IISPSR			(0x0C)
+#define S3C2412_IISTXD			(0x10)
+#define S3C2412_IISRXD			(0x14)
+
+#define S3C2412_IISCON_LRINDEX		(1 << 11)
+#define S3C2412_IISCON_TXFIFO_EMPTY	(1 << 10)
+#define S3C2412_IISCON_RXFIFO_EMPTY	(1 << 9)
+#define S3C2412_IISCON_TXFIFO_FULL	(1 << 8)
+#define S3C2412_IISCON_RXFIFO_FULL	(1 << 7)
+#define S3C2412_IISCON_TXDMA_PAUSE	(1 << 6)
+#define S3C2412_IISCON_RXDMA_PAUSE	(1 << 5)
+#define S3C2412_IISCON_TXCH_PAUSE	(1 << 4)
+#define S3C2412_IISCON_RXCH_PAUSE	(1 << 3)
+#define S3C2412_IISCON_TXDMA_ACTIVE	(1 << 2)
+#define S3C2412_IISCON_RXDMA_ACTIVE	(1 << 1)
+#define S3C2412_IISCON_IIS_ACTIVE	(1 << 0)
+
+#define S3C2412_IISMOD_MASTER_INTERNAL	(0 << 10)
+#define S3C2412_IISMOD_MASTER_EXTERNAL	(1 << 10)
+#define S3C2412_IISMOD_SLAVE		(2 << 10)
+#define S3C2412_IISMOD_MASTER_MASK	(3 << 10)
+#define S3C2412_IISMOD_MODE_TXONLY	(0 << 8)
+#define S3C2412_IISMOD_MODE_RXONLY	(1 << 8)
+#define S3C2412_IISMOD_MODE_TXRX	(2 << 8)
+#define S3C2412_IISMOD_MODE_MASK	(3 << 8)
+#define S3C2412_IISMOD_LR_LLOW		(0 << 7)
+#define S3C2412_IISMOD_LR_RLOW		(1 << 7)
+#define S3C2412_IISMOD_SDF_IIS		(0 << 5)
+#define S3C2412_IISMOD_SDF_MSB		(0 << 5)
+#define S3C2412_IISMOD_SDF_LSB		(0 << 5)
+#define S3C2412_IISMOD_SDF_MASK		(3 << 5)
+#define S3C2412_IISMOD_RCLK_256FS	(0 << 3)
+#define S3C2412_IISMOD_RCLK_512FS	(1 << 3)
+#define S3C2412_IISMOD_RCLK_384FS	(2 << 3)
+#define S3C2412_IISMOD_RCLK_768FS	(3 << 3)
+#define S3C2412_IISMOD_RCLK_MASK 	(3 << 3)
+#define S3C2412_IISMOD_BCLK_32FS	(0 << 1)
+#define S3C2412_IISMOD_BCLK_48FS	(1 << 1)
+#define S3C2412_IISMOD_BCLK_16FS	(2 << 1)
+#define S3C2412_IISMOD_BCLK_24FS	(3 << 1)
+#define S3C2412_IISMOD_BCLK_MASK	(3 << 1)
+#define S3C2412_IISMOD_8BIT		(1 << 0)
+
+#define S3C2412_IISPSR_PSREN		(1 << 15)
+
+#define S3C2412_IISFIC_TXFLUSH		(1 << 15)
+#define S3C2412_IISFIC_RXFLUSH		(1 << 7)
+#define S3C2412_IISFIC_TXCOUNT(x)	(((x) >>  8) & 0xf)
+#define S3C2412_IISFIC_RXCOUNT(x)	(((x) >>  0) & 0xf)
+
+
+
+#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */
+
diff --git a/include/asm-arm/plat-s3c24xx/regs-spi.h b/include/asm-arm/plat-s3c24xx/regs-spi.h
index 4a499a1..ea565b0 100644
--- a/include/asm-arm/plat-s3c24xx/regs-spi.h
+++ b/include/asm-arm/plat-s3c24xx/regs-spi.h
@@ -17,6 +17,21 @@
 
 #define S3C2410_SPCON	(0x00)
 
+#define S3C2412_SPCON_RXFIFO_RB2	(0<<14)
+#define S3C2412_SPCON_RXFIFO_RB4	(1<<14)
+#define S3C2412_SPCON_RXFIFO_RB12	(2<<14)
+#define S3C2412_SPCON_RXFIFO_RB14	(3<<14)
+#define S3C2412_SPCON_TXFIFO_RB2	(0<<12)
+#define S3C2412_SPCON_TXFIFO_RB4	(1<<12)
+#define S3C2412_SPCON_TXFIFO_RB12	(2<<12)
+#define S3C2412_SPCON_TXFIFO_RB14	(3<<12)
+#define S3C2412_SPCON_RXFIFO_RESET	(1<<11) /* RxFIFO reset */
+#define S3C2412_SPCON_TXFIFO_RESET	(1<<10) /* TxFIFO reset */
+#define S3C2412_SPCON_RXFIFO_EN		(1<<9)  /* RxFIFO Enable */
+#define S3C2412_SPCON_TXFIFO_EN		(1<<8)  /* TxFIFO Enable */
+
+#define S3C2412_SPCON_DIRC_RX	  (1<<7)
+
 #define S3C2410_SPCON_SMOD_DMA	  (2<<5)	/* DMA mode */
 #define S3C2410_SPCON_SMOD_INT	  (1<<5)	/* interrupt mode */
 #define S3C2410_SPCON_SMOD_POLL   (0<<5)	/* polling mode */
@@ -34,10 +49,19 @@
 
 #define S3C2410_SPSTA	 (0x04)
 
+#define S3C2412_SPSTA_RXFIFO_AE		(1<<11)
+#define S3C2412_SPSTA_TXFIFO_AE		(1<<10)
+#define S3C2412_SPSTA_RXFIFO_ERROR	(1<<9)
+#define S3C2412_SPSTA_TXFIFO_ERROR	(1<<8)
+#define S3C2412_SPSTA_RXFIFO_FIFO	(1<<7)
+#define S3C2412_SPSTA_RXFIFO_EMPTY	(1<<6)
+#define S3C2412_SPSTA_TXFIFO_NFULL	(1<<5)
+#define S3C2412_SPSTA_TXFIFO_EMPTY	(1<<4)
+
 #define S3C2410_SPSTA_DCOL	  (1<<2)	/* Data Collision Error */
 #define S3C2410_SPSTA_MULD	  (1<<1)	/* Multi Master Error */
 #define S3C2410_SPSTA_READY	  (1<<0)	/* Data Tx/Rx ready */
-
+#define S3C2412_SPSTA_READY_ORG	  (1<<3)
 
 #define S3C2410_SPPIN	 (0x08)
 
@@ -46,9 +70,13 @@
 #define S3C2400_SPPIN_nCS     	  (1<<1)	/* SPI Card Select */
 #define S3C2410_SPPIN_KEEP	  (1<<0)	/* Master Out keep */
 
-
 #define S3C2410_SPPRE	 (0x0C)
 #define S3C2410_SPTDAT	 (0x10)
 #define S3C2410_SPRDAT	 (0x14)
 
+#define S3C2412_TXFIFO	 (0x18)
+#define S3C2412_RXFIFO	 (0x18)
+#define S3C2412_SPFIC	 (0x24)
+
+
 #endif /* __ASM_ARCH_REGS_SPI_H */
diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h
index 5599d4e..a4ce457 100644
--- a/include/asm-arm/proc-fns.h
+++ b/include/asm-arm/proc-fns.h
@@ -185,6 +185,14 @@
 #   define CPU_NAME cpu_xsc3
 #  endif
 # endif
+# ifdef CONFIG_CPU_FEROCEON
+#  ifdef CPU_NAME
+#   undef  MULTI_CPU
+#   define MULTI_CPU
+#  else
+#   define CPU_NAME cpu_feroceon
+#  endif
+# endif
 # ifdef CONFIG_CPU_V6
 #  ifdef CPU_NAME
 #   undef  MULTI_CPU
diff --git a/include/asm-arm/traps.h b/include/asm-arm/traps.h
index d4f34dc..f1541af 100644
--- a/include/asm-arm/traps.h
+++ b/include/asm-arm/traps.h
@@ -15,4 +15,13 @@
 void register_undef_hook(struct undef_hook *hook);
 void unregister_undef_hook(struct undef_hook *hook);
 
+static inline int in_exception_text(unsigned long ptr)
+{
+	extern char __exception_text_start[];
+	extern char __exception_text_end[];
+
+	return ptr >= (unsigned long)&__exception_text_start &&
+	       ptr < (unsigned long)&__exception_text_end;
+}
+
 #endif
diff --git a/include/asm-arm/vfp.h b/include/asm-arm/vfp.h
index bd6be9d..5f9a2cb 100644
--- a/include/asm-arm/vfp.h
+++ b/include/asm-arm/vfp.h
@@ -7,7 +7,11 @@
 
 #define FPSID			cr0
 #define FPSCR			cr1
+#define MVFR1			cr6
+#define MVFR0			cr7
 #define FPEXC			cr8
+#define FPINST			cr9
+#define FPINST2			cr10
 
 /* FPSID bits */
 #define FPSID_IMPLEMENTER_BIT	(24)
@@ -28,6 +32,19 @@
 /* FPEXC bits */
 #define FPEXC_EX		(1 << 31)
 #define FPEXC_EN		(1 << 30)
+#define FPEXC_DEX		(1 << 29)
+#define FPEXC_FP2V		(1 << 28)
+#define FPEXC_VV		(1 << 27)
+#define FPEXC_TFV		(1 << 26)
+#define FPEXC_LENGTH_BIT	(8)
+#define FPEXC_LENGTH_MASK	(7 << FPEXC_LENGTH_BIT)
+#define FPEXC_IDF		(1 << 7)
+#define FPEXC_IXF		(1 << 4)
+#define FPEXC_UFF		(1 << 3)
+#define FPEXC_OFF		(1 << 2)
+#define FPEXC_DZF		(1 << 1)
+#define FPEXC_IOF		(1 << 0)
+#define FPEXC_TRAP_MASK		(FPEXC_IDF|FPEXC_IXF|FPEXC_UFF|FPEXC_OFF|FPEXC_DZF|FPEXC_IOF)
 
 /* FPSCR bits */
 #define FPSCR_DEFAULT_NAN	(1<<25)
@@ -55,20 +72,9 @@
 #define FPSCR_IXC		(1<<4)
 #define FPSCR_IDC		(1<<7)
 
-/*
- * VFP9-S specific.
- */
-#define FPINST			cr9
-#define FPINST2			cr10
-
-/* FPEXC bits */
-#define FPEXC_FPV2		(1<<28)
-#define FPEXC_LENGTH_BIT	(8)
-#define FPEXC_LENGTH_MASK	(7 << FPEXC_LENGTH_BIT)
-#define FPEXC_INV		(1 << 7)
-#define FPEXC_UFC		(1 << 3)
-#define FPEXC_OFC		(1 << 2)
-#define FPEXC_IOC		(1 << 0)
+/* MVFR0 bits */
+#define MVFR0_A_SIMD_BIT	(0)
+#define MVFR0_A_SIMD_MASK	(0xf << MVFR0_A_SIMD_BIT)
 
 /* Bit patterns for decoding the packaged operation descriptors */
 #define VFPOPDESC_LENGTH_BIT	(9)
diff --git a/include/asm-arm/vfpmacros.h b/include/asm-arm/vfpmacros.h
index 27fe028..cccb389 100644
--- a/include/asm-arm/vfpmacros.h
+++ b/include/asm-arm/vfpmacros.h
@@ -15,19 +15,33 @@
 	.endm
 
 	@ read all the working registers back into the VFP
-	.macro	VFPFLDMIA, base
+	.macro	VFPFLDMIA, base, tmp
 #if __LINUX_ARM_ARCH__ < 6
 	LDC	p11, cr0, [\base],#33*4		    @ FLDMIAX \base!, {d0-d15}
 #else
 	LDC	p11, cr0, [\base],#32*4		    @ FLDMIAD \base!, {d0-d15}
 #endif
+#ifdef CONFIG_VFPv3
+	VFPFMRX	\tmp, MVFR0			    @ Media and VFP Feature Register 0
+	and	\tmp, \tmp, #MVFR0_A_SIMD_MASK	    @ A_SIMD field
+	cmp	\tmp, #2			    @ 32 x 64bit registers?
+	ldceql	p11, cr0, [\base],#32*4		    @ FLDMIAD \base!, {d16-d31}
+	addne	\base, \base, #32*4		    @ step over unused register space
+#endif
 	.endm
 
 	@ write all the working registers out of the VFP
-	.macro	VFPFSTMIA, base
+	.macro	VFPFSTMIA, base, tmp
 #if __LINUX_ARM_ARCH__ < 6
 	STC	p11, cr0, [\base],#33*4		    @ FSTMIAX \base!, {d0-d15}
 #else
 	STC	p11, cr0, [\base],#32*4		    @ FSTMIAD \base!, {d0-d15}
 #endif
+#ifdef CONFIG_VFPv3
+	VFPFMRX	\tmp, MVFR0			    @ Media and VFP Feature Register 0
+	and	\tmp, \tmp, #MVFR0_A_SIMD_MASK	    @ A_SIMD field
+	cmp	\tmp, #2			    @ 32 x 64bit registers?
+	stceql	p11, cr0, [\base],#32*4		    @ FSTMIAD \base!, {d16-d31}
+	addne	\base, \base, #32*4		    @ step over unused register space
+#endif
 	.endm
diff --git a/include/asm-avr32/arch-at32ap/cpu.h b/include/asm-avr32/arch-at32ap/cpu.h
index 0dc2026..44d0bfa 100644
--- a/include/asm-avr32/arch-at32ap/cpu.h
+++ b/include/asm-avr32/arch-at32ap/cpu.h
@@ -30,5 +30,6 @@
 #define cpu_is_at91sam9261()	(0)
 #define cpu_is_at91sam9263()	(0)
 #define cpu_is_at91sam9rl()	(0)
+#define cpu_is_at91cap9()	(0)
 
 #endif /* __ASM_ARCH_CPU_H */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 49b7a4c..71e7a84 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -34,83 +34,10 @@
 #define BLKDEV_MIN_RQ	4
 #define BLKDEV_MAX_RQ	128	/* Default maximum */
 
-/*
- * This is the per-process anticipatory I/O scheduler state.
- */
-struct as_io_context {
-	spinlock_t lock;
-
-	void (*dtor)(struct as_io_context *aic); /* destructor */
-	void (*exit)(struct as_io_context *aic); /* called on task exit */
-
-	unsigned long state;
-	atomic_t nr_queued; /* queued reads & sync writes */
-	atomic_t nr_dispatched; /* number of requests gone to the drivers */
-
-	/* IO History tracking */
-	/* Thinktime */
-	unsigned long last_end_request;
-	unsigned long ttime_total;
-	unsigned long ttime_samples;
-	unsigned long ttime_mean;
-	/* Layout pattern */
-	unsigned int seek_samples;
-	sector_t last_request_pos;
-	u64 seek_total;
-	sector_t seek_mean;
-};
-
-struct cfq_queue;
-struct cfq_io_context {
-	struct rb_node rb_node;
-	void *key;
-
-	struct cfq_queue *cfqq[2];
-
-	struct io_context *ioc;
-
-	unsigned long last_end_request;
-	sector_t last_request_pos;
-
-	unsigned long ttime_total;
-	unsigned long ttime_samples;
-	unsigned long ttime_mean;
-
-	unsigned int seek_samples;
-	u64 seek_total;
-	sector_t seek_mean;
-
-	struct list_head queue_list;
-
-	void (*dtor)(struct io_context *); /* destructor */
-	void (*exit)(struct io_context *); /* called on task exit */
-};
-
-/*
- * This is the per-process I/O subsystem state.  It is refcounted and
- * kmalloc'ed. Currently all fields are modified in process io context
- * (apart from the atomic refcount), so require no locking.
- */
-struct io_context {
-	atomic_t refcount;
-	struct task_struct *task;
-
-	unsigned int ioprio_changed;
-
-	/*
-	 * For request batching
-	 */
-	unsigned long last_waited; /* Time last woken after wait for request */
-	int nr_batch_requests;     /* Number of requests left in the batch */
-
-	struct as_io_context *aic;
-	struct rb_root cic_root;
-	void *ioc_data;
-};
-
-void put_io_context(struct io_context *ioc);
+int put_io_context(struct io_context *ioc);
 void exit_io_context(void);
 struct io_context *get_io_context(gfp_t gfp_flags, int node);
+struct io_context *alloc_io_context(gfp_t gfp_flags, int node);
 void copy_io_context(struct io_context **pdst, struct io_context **psrc);
 void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
 
@@ -429,6 +356,8 @@
 	unsigned int		max_segment_size;
 
 	unsigned long		seg_boundary_mask;
+	void			*dma_drain_buffer;
+	unsigned int		dma_drain_size;
 	unsigned int		dma_alignment;
 
 	struct blk_queue_tag	*queue_tags;
@@ -537,6 +466,8 @@
 #define blk_fua_rq(rq)		((rq)->cmd_flags & REQ_FUA)
 #define blk_bidi_rq(rq)		((rq)->next_rq != NULL)
 #define blk_empty_barrier(rq)	(blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors)
+/* rq->queuelist of dequeued request must be list_empty() */
+#define blk_queued_rq(rq)	(!list_empty(&(rq)->queuelist))
 
 #define list_entry_rq(ptr)	list_entry((ptr), struct request, queuelist)
 
@@ -716,29 +647,32 @@
 }
 
 /*
- * end_request() and friends. Must be called with the request queue spinlock
- * acquired. All functions called within end_request() _must_be_ atomic.
+ * blk_end_request() and friends.
+ * __blk_end_request() and end_request() must be called with
+ * the request queue spinlock acquired.
  *
  * Several drivers define their own end_request and call
- * end_that_request_first() and end_that_request_last()
- * for parts of the original function. This prevents
- * code duplication in drivers.
+ * blk_end_request() for parts of the original function.
+ * This prevents code duplication in drivers.
  */
-extern int end_that_request_first(struct request *, int, int);
-extern int end_that_request_chunk(struct request *, int, int);
-extern void end_that_request_last(struct request *, int);
+extern int blk_end_request(struct request *rq, int error, int nr_bytes);
+extern int __blk_end_request(struct request *rq, int error, int nr_bytes);
+extern int blk_end_bidi_request(struct request *rq, int error, int nr_bytes,
+				int bidi_bytes);
 extern void end_request(struct request *, int);
 extern void end_queued_request(struct request *, int);
 extern void end_dequeued_request(struct request *, int);
+extern int blk_end_request_callback(struct request *rq, int error, int nr_bytes,
+				    int (drv_callback)(struct request *));
 extern void blk_complete_request(struct request *);
 
 /*
- * end_that_request_first/chunk() takes an uptodate argument. we account
- * any value <= as an io error. 0 means -EIO for compatability reasons,
- * any other < 0 value is the direct error type. An uptodate value of
- * 1 indicates successful io completion
+ * blk_end_request() takes bytes instead of sectors as a complete size.
+ * blk_rq_bytes() returns bytes left to complete in the entire request.
+ * blk_rq_cur_bytes() returns bytes left to complete in the current segment.
  */
-#define end_io_error(uptodate)	(unlikely((uptodate) <= 0))
+extern unsigned int blk_rq_bytes(struct request *rq);
+extern unsigned int blk_rq_cur_bytes(struct request *rq);
 
 static inline void blkdev_dequeue_request(struct request *req)
 {
@@ -760,6 +694,8 @@
 extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
 extern void blk_queue_hardsect_size(struct request_queue *, unsigned short);
 extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b);
+extern int blk_queue_dma_drain(struct request_queue *q, void *buf,
+			       unsigned int size);
 extern void blk_queue_segment_boundary(struct request_queue *, unsigned long);
 extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn);
 extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
@@ -836,12 +772,7 @@
 
 static inline int queue_dma_alignment(struct request_queue *q)
 {
-	int retval = 511;
-
-	if (q && q->dma_alignment)
-		retval = q->dma_alignment;
-
-	return retval;
+	return q ? q->dma_alignment : 511;
 }
 
 /* assumes size > 256 */
@@ -894,6 +825,12 @@
 {
 }
 
+static inline int put_io_context(struct io_context *ioc)
+{
+	return 1;
+}
+
+
 #endif /* CONFIG_BLOCK */
 
 #endif
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 7e11d23..06dadba 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -148,7 +148,7 @@
 extern void blk_trace_shutdown(struct request_queue *);
 extern void __blk_add_trace(struct blk_trace *, sector_t, int, int, u32, int, int, void *);
 extern int do_blk_trace_setup(struct request_queue *q,
-	struct block_device *bdev, struct blk_user_trace_setup *buts);
+	char *name, dev_t dev, struct blk_user_trace_setup *buts);
 
 
 /**
@@ -282,6 +282,11 @@
 	__blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r);
 }
 
+extern int blk_trace_setup(request_queue_t *q, char *name, dev_t dev,
+			   char __user *arg);
+extern int blk_trace_startstop(request_queue_t *q, int start);
+extern int blk_trace_remove(request_queue_t *q);
+
 #else /* !CONFIG_BLK_DEV_IO_TRACE */
 #define blk_trace_ioctl(bdev, cmd, arg)		(-ENOTTY)
 #define blk_trace_shutdown(q)			do { } while (0)
@@ -290,7 +295,10 @@
 #define blk_add_trace_generic(q, rq, rw, what)	do { } while (0)
 #define blk_add_trace_pdu_int(q, what, bio, pdu)	do { } while (0)
 #define blk_add_trace_remap(q, bio, dev, f, t)	do {} while (0)
-#define do_blk_trace_setup(q, bdev, buts)	(-ENOTTY)
+#define do_blk_trace_setup(q, name, dev, buts)	(-ENOTTY)
+#define blk_trace_setup(q, name, dev, arg)	(-ENOTTY)
+#define blk_trace_startstop(q, start)		(-ENOTTY)
+#define blk_trace_remove(q)			(-ENOTTY)
 #endif /* CONFIG_BLK_DEV_IO_TRACE */
 #endif /* __KERNEL__ */
 #endif
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 6e35b92..3902690 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -267,10 +267,10 @@
 #define HID_QUIRK_2WHEEL_MOUSE_HACK_5		0x00000100
 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON		0x00000200
 #define HID_QUIRK_MIGHTYMOUSE			0x00000400
-#define HID_QUIRK_POWERBOOK_HAS_FN		0x00000800
-#define HID_QUIRK_POWERBOOK_FN_ON		0x00001000
+#define HID_QUIRK_APPLE_HAS_FN			0x00000800
+#define HID_QUIRK_APPLE_FN_ON			0x00001000
 #define HID_QUIRK_INVERT_HWHEEL			0x00002000
-#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD        0x00004000
+#define HID_QUIRK_APPLE_ISO_KEYBOARD		0x00004000
 #define HID_QUIRK_BAD_RELATIVE_KEYS		0x00008000
 #define HID_QUIRK_SKIP_OUTPUT_REPORTS		0x00010000
 #define HID_QUIRK_IGNORE_MOUSE			0x00020000
@@ -281,6 +281,9 @@
 #define HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL	0x00400000
 #define HID_QUIRK_LOGITECH_EXPANDED_KEYMAP	0x00800000
 #define HID_QUIRK_IGNORE_HIDINPUT		0x01000000
+#define HID_QUIRK_2WHEEL_MOUSE_HACK_B8		0x02000000
+#define HID_QUIRK_HWHEEL_WHEEL_INVERT		0x04000000
+#define HID_QUIRK_MICROSOFT_KEYS		0x08000000
 
 /*
  * Separate quirks for runtime report descriptor fixup
@@ -291,6 +294,8 @@
 #define HID_QUIRK_RDESC_SWAPPED_MIN_MAX		0x00000004
 #define HID_QUIRK_RDESC_PETALYNX		0x00000008
 #define HID_QUIRK_RDESC_MACBOOK_JIS		0x00000010
+#define HID_QUIRK_RDESC_BUTTON_CONSUMER		0x00000020
+#define HID_QUIRK_RDESC_SAMSUNG_REMOTE		0x00000040
 
 /*
  * This is the global environment of the parser. This information is
@@ -456,6 +461,8 @@
 
 	void *driver_data;
 
+	__s32 delayed_value;						/* For A4 Tech mice hwheel quirk */
+
 	/* device-specific function pointers */
 	int (*hidinput_input_event) (struct input_dev *, unsigned int, unsigned int, int);
 	int (*hid_open) (struct hid_device *);
@@ -469,7 +476,7 @@
 	/* handler for raw output data, used by hidraw */
 	int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
-	unsigned long pb_pressed_fn[BITS_TO_LONGS(KEY_CNT)];
+	unsigned long apple_pressed_fn[BITS_TO_LONGS(KEY_CNT)];
 	unsigned long pb_pressed_numlock[BITS_TO_LONGS(KEY_CNT)];
 #endif
 };
@@ -520,6 +527,9 @@
 int hid_set_field(struct hid_field *, unsigned, __s32);
 int hid_input_report(struct hid_device *, int type, u8 *, int, int);
 int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
+int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long **, int *);
+void hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
+int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32);
 void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt);
 void hid_output_report(struct hid_report *report, __u8 *data);
 void hid_free_device(struct hid_device *device);
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 796019b..e6b3f70 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -137,7 +137,6 @@
 		.time_slice	= HZ, 					\
 		.nr_cpus_allowed = NR_CPUS,				\
 	},								\
-	.ioprio		= 0,						\
 	.tasks		= LIST_HEAD_INIT(tsk.tasks),			\
 	.ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children),		\
 	.ptrace_list	= LIST_HEAD_INIT(tsk.ptrace_list),		\
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
new file mode 100644
index 0000000..593b222
--- /dev/null
+++ b/include/linux/iocontext.h
@@ -0,0 +1,95 @@
+#ifndef IOCONTEXT_H
+#define IOCONTEXT_H
+
+#include <linux/radix-tree.h>
+
+/*
+ * This is the per-process anticipatory I/O scheduler state.
+ */
+struct as_io_context {
+	spinlock_t lock;
+
+	void (*dtor)(struct as_io_context *aic); /* destructor */
+	void (*exit)(struct as_io_context *aic); /* called on task exit */
+
+	unsigned long state;
+	atomic_t nr_queued; /* queued reads & sync writes */
+	atomic_t nr_dispatched; /* number of requests gone to the drivers */
+
+	/* IO History tracking */
+	/* Thinktime */
+	unsigned long last_end_request;
+	unsigned long ttime_total;
+	unsigned long ttime_samples;
+	unsigned long ttime_mean;
+	/* Layout pattern */
+	unsigned int seek_samples;
+	sector_t last_request_pos;
+	u64 seek_total;
+	sector_t seek_mean;
+};
+
+struct cfq_queue;
+struct cfq_io_context {
+	void *key;
+	unsigned long dead_key;
+
+	struct cfq_queue *cfqq[2];
+
+	struct io_context *ioc;
+
+	unsigned long last_end_request;
+	sector_t last_request_pos;
+
+	unsigned long ttime_total;
+	unsigned long ttime_samples;
+	unsigned long ttime_mean;
+
+	unsigned int seek_samples;
+	u64 seek_total;
+	sector_t seek_mean;
+
+	struct list_head queue_list;
+
+	void (*dtor)(struct io_context *); /* destructor */
+	void (*exit)(struct io_context *); /* called on task exit */
+};
+
+/*
+ * I/O subsystem state of the associated processes.  It is refcounted
+ * and kmalloc'ed. These could be shared between processes.
+ */
+struct io_context {
+	atomic_t refcount;
+	atomic_t nr_tasks;
+
+	/* all the fields below are protected by this lock */
+	spinlock_t lock;
+
+	unsigned short ioprio;
+	unsigned short ioprio_changed;
+
+	/*
+	 * For request batching
+	 */
+	unsigned long last_waited; /* Time last woken after wait for request */
+	int nr_batch_requests;     /* Number of requests left in the batch */
+
+	struct as_io_context *aic;
+	struct radix_tree_root radix_root;
+	void *ioc_data;
+};
+
+static inline struct io_context *ioc_task_link(struct io_context *ioc)
+{
+	/*
+	 * if ref count is zero, don't allow sharing (ioc is going away, it's
+	 * a race).
+	 */
+	if (ioc && atomic_inc_not_zero(&ioc->refcount))
+		return ioc;
+
+	return NULL;
+}
+
+#endif
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h
index baf2938..2a3bb1b 100644
--- a/include/linux/ioprio.h
+++ b/include/linux/ioprio.h
@@ -2,6 +2,7 @@
 #define IOPRIO_H
 
 #include <linux/sched.h>
+#include <linux/iocontext.h>
 
 /*
  * Gives us 8 prio classes with 13-bits of data for each class
@@ -45,18 +46,18 @@
  * the cpu scheduler nice value to an io priority
  */
 #define IOPRIO_NORM	(4)
-static inline int task_ioprio(struct task_struct *task)
+static inline int task_ioprio(struct io_context *ioc)
 {
-	if (ioprio_valid(task->ioprio))
-		return IOPRIO_PRIO_DATA(task->ioprio);
+	if (ioprio_valid(ioc->ioprio))
+		return IOPRIO_PRIO_DATA(ioc->ioprio);
 
 	return IOPRIO_NORM;
 }
 
-static inline int task_ioprio_class(struct task_struct *task)
+static inline int task_ioprio_class(struct io_context *ioc)
 {
-	if (ioprio_valid(task->ioprio))
-		return IOPRIO_PRIO_CLASS(task->ioprio);
+	if (ioprio_valid(ioc->ioprio))
+		return IOPRIO_PRIO_CLASS(ioc->ioprio);
 
 	return IOPRIO_CLASS_BE;
 }
diff --git a/include/linux/mv643xx.h b/include/linux/mv643xx.h
index d2ae618..69327b7 100644
--- a/include/linux/mv643xx.h
+++ b/include/linux/mv643xx.h
@@ -15,6 +15,7 @@
 
 #include <asm/types.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
 
 /****************************************/
 /* Processor Address Space              */
@@ -863,7 +864,6 @@
 /* I2C Registers                        */
 /****************************************/
 
-#define MV64XXX_I2C_CTLR_NAME					"mv64xxx_i2c"
 #define MV64XXX_I2C_OFFSET                                          0xc000
 #define MV64XXX_I2C_REG_BLOCK_SIZE                                  0x0020
 
@@ -968,14 +968,6 @@
 	u32	brg_clk_freq;
 };
 
-/* i2c Platform Device, Driver Data */
-struct mv64xxx_i2c_pdata {
-	u32	freq_m;
-	u32	freq_n;
-	u32	timeout;	/* In milliseconds */
-	u32	retries;
-};
-
 /* Watchdog Platform Device, Driver Data */
 #define	MV64x60_WDT_NAME			"mv64x60_wdt"
 
diff --git a/include/linux/mv643xx_i2c.h b/include/linux/mv643xx_i2c.h
new file mode 100644
index 0000000..5db5152
--- /dev/null
+++ b/include/linux/mv643xx_i2c.h
@@ -0,0 +1,22 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _MV64XXX_I2C_H_
+#define _MV64XXX_I2C_H_
+
+#include <linux/types.h>
+
+#define MV64XXX_I2C_CTLR_NAME	"mv64xxx_i2c"
+
+/* i2c Platform Device, Driver Data */
+struct mv64xxx_i2c_pdata {
+	u32	freq_m;
+	u32	freq_n;
+	u32	timeout;	/* In milliseconds */
+};
+
+#endif /*_MV64XXX_I2C_H_*/
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index e3ff21d..a3d567a 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -7,6 +7,12 @@
 #include <linux/string.h>
 #include <asm/io.h>
 
+struct sg_table {
+	struct scatterlist *sgl;	/* the list */
+	unsigned int nents;		/* number of mapped entries */
+	unsigned int orig_nents;	/* original size of list */
+};
+
 /*
  * Notes on SG table design.
  *
@@ -106,31 +112,6 @@
 	sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
 }
 
-/**
- * sg_next - return the next scatterlist entry in a list
- * @sg:		The current sg entry
- *
- * Description:
- *   Usually the next entry will be @sg@ + 1, but if this sg element is part
- *   of a chained scatterlist, it could jump to the start of a new
- *   scatterlist array.
- *
- **/
-static inline struct scatterlist *sg_next(struct scatterlist *sg)
-{
-#ifdef CONFIG_DEBUG_SG
-	BUG_ON(sg->sg_magic != SG_MAGIC);
-#endif
-	if (sg_is_last(sg))
-		return NULL;
-
-	sg++;
-	if (unlikely(sg_is_chain(sg)))
-		sg = sg_chain_ptr(sg);
-
-	return sg;
-}
-
 /*
  * Loop over each sg element, following the pointer to a new list if necessary
  */
@@ -138,40 +119,6 @@
 	for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
 
 /**
- * sg_last - return the last scatterlist entry in a list
- * @sgl:	First entry in the scatterlist
- * @nents:	Number of entries in the scatterlist
- *
- * Description:
- *   Should only be used casually, it (currently) scan the entire list
- *   to get the last entry.
- *
- *   Note that the @sgl@ pointer passed in need not be the first one,
- *   the important bit is that @nents@ denotes the number of entries that
- *   exist from @sgl@.
- *
- **/
-static inline struct scatterlist *sg_last(struct scatterlist *sgl,
-					  unsigned int nents)
-{
-#ifndef ARCH_HAS_SG_CHAIN
-	struct scatterlist *ret = &sgl[nents - 1];
-#else
-	struct scatterlist *sg, *ret = NULL;
-	unsigned int i;
-
-	for_each_sg(sgl, sg, nents, i)
-		ret = sg;
-
-#endif
-#ifdef CONFIG_DEBUG_SG
-	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
-	BUG_ON(!sg_is_last(ret));
-#endif
-	return ret;
-}
-
-/**
  * sg_chain - Chain two sglists together
  * @prv:	First scatterlist
  * @prv_nents:	Number of entries in prv
@@ -223,47 +170,6 @@
 }
 
 /**
- * sg_init_table - Initialize SG table
- * @sgl:	   The SG table
- * @nents:	   Number of entries in table
- *
- * Notes:
- *   If this is part of a chained sg table, sg_mark_end() should be
- *   used only on the last table part.
- *
- **/
-static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
-{
-	memset(sgl, 0, sizeof(*sgl) * nents);
-#ifdef CONFIG_DEBUG_SG
-	{
-		unsigned int i;
-		for (i = 0; i < nents; i++)
-			sgl[i].sg_magic = SG_MAGIC;
-	}
-#endif
-	sg_mark_end(&sgl[nents - 1]);
-}
-
-/**
- * sg_init_one - Initialize a single entry sg list
- * @sg:		 SG entry
- * @buf:	 Virtual address for IO
- * @buflen:	 IO length
- *
- * Notes:
- *   This should not be used on a single entry that is part of a larger
- *   table. Use sg_init_table() for that.
- *
- **/
-static inline void sg_init_one(struct scatterlist *sg, const void *buf,
-			       unsigned int buflen)
-{
-	sg_init_table(sg, 1);
-	sg_set_buf(sg, buf, buflen);
-}
-
-/**
  * sg_phys - Return physical address of an sg entry
  * @sg:	     SG entry
  *
@@ -293,4 +199,24 @@
 	return page_address(sg_page(sg)) + sg->offset;
 }
 
+struct scatterlist *sg_next(struct scatterlist *);
+struct scatterlist *sg_last(struct scatterlist *s, unsigned int);
+void sg_init_table(struct scatterlist *, unsigned int);
+void sg_init_one(struct scatterlist *, const void *, unsigned int);
+
+typedef struct scatterlist *(sg_alloc_fn)(unsigned int, gfp_t);
+typedef void (sg_free_fn)(struct scatterlist *, unsigned int);
+
+void __sg_free_table(struct sg_table *, unsigned int, sg_free_fn *);
+void sg_free_table(struct sg_table *);
+int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t,
+		     sg_alloc_fn *);
+int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
+
+/*
+ * Maximum number of entries that will be allocated in one piece, if
+ * a list larger than this is required then chaining will be utilized.
+ */
+#define SG_MAX_SINGLE_ALLOC		(PAGE_SIZE / sizeof(struct scatterlist))
+
 #endif /* _LINUX_SCATTERLIST_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index df5b24e..2d0546e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -27,6 +27,7 @@
 #define CLONE_NEWUSER		0x10000000	/* New user namespace */
 #define CLONE_NEWPID		0x20000000	/* New pid namespace */
 #define CLONE_NEWNET		0x40000000	/* New network namespace */
+#define CLONE_IO		0x80000000	/* Clone io context */
 
 /*
  * Scheduling policies
@@ -975,7 +976,6 @@
 	struct hlist_head preempt_notifiers;
 #endif
 
-	unsigned short ioprio;
 	/*
 	 * fpu_counter contains the number of consecutive context switches
 	 * that the FPU is used. If this is over a threshold, the lazy fpu
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index abd7479..a457fca 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -8,7 +8,6 @@
 #include <linux/scatterlist.h>
 
 struct request;
-struct scatterlist;
 struct Scsi_Host;
 struct scsi_device;
 
@@ -68,8 +67,8 @@
 	void *request_buffer;		/* Actual requested buffer */
 
 	/* These elements define the operation we ultimately want to perform */
+	struct sg_table sg_table;
 	unsigned short use_sg;	/* Number of pieces of scatter-gather */
-	unsigned short __use_sg;
 
 	unsigned underflow;	/* Return error if less than
 				   this amount is transferred */
@@ -128,14 +127,14 @@
 				 size_t *offset, size_t *len);
 extern void scsi_kunmap_atomic_sg(void *virt);
 
-extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
+extern int scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
 extern void scsi_free_sgtable(struct scsi_cmnd *);
 
 extern int scsi_dma_map(struct scsi_cmnd *cmd);
 extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
 
 #define scsi_sg_count(cmd) ((cmd)->use_sg)
-#define scsi_sglist(cmd) ((struct scatterlist *)(cmd)->request_buffer)
+#define scsi_sglist(cmd) ((cmd)->sg_table.sgl)
 #define scsi_bufflen(cmd) ((cmd)->request_bufflen)
 
 static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid)
diff --git a/kernel/fork.c b/kernel/fork.c
index 39d22b3..314f510 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -51,6 +51,7 @@
 #include <linux/random.h>
 #include <linux/tty.h>
 #include <linux/proc_fs.h>
+#include <linux/blkdev.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -791,6 +792,31 @@
 	return error;
 }
 
+static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
+{
+#ifdef CONFIG_BLOCK
+	struct io_context *ioc = current->io_context;
+
+	if (!ioc)
+		return 0;
+	/*
+	 * Share io context with parent, if CLONE_IO is set
+	 */
+	if (clone_flags & CLONE_IO) {
+		tsk->io_context = ioc_task_link(ioc);
+		if (unlikely(!tsk->io_context))
+			return -ENOMEM;
+	} else if (ioprio_valid(ioc->ioprio)) {
+		tsk->io_context = alloc_io_context(GFP_KERNEL, -1);
+		if (unlikely(!tsk->io_context))
+			return -ENOMEM;
+
+		tsk->io_context->ioprio = ioc->ioprio;
+	}
+#endif
+	return 0;
+}
+
 /*
  *	Helper to unshare the files of the current task.
  *	We don't want to expose copy_files internals to
@@ -1156,15 +1182,17 @@
 		goto bad_fork_cleanup_mm;
 	if ((retval = copy_namespaces(clone_flags, p)))
 		goto bad_fork_cleanup_keys;
+	if ((retval = copy_io(clone_flags, p)))
+		goto bad_fork_cleanup_namespaces;
 	retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
 	if (retval)
-		goto bad_fork_cleanup_namespaces;
+		goto bad_fork_cleanup_io;
 
 	if (pid != &init_struct_pid) {
 		retval = -ENOMEM;
 		pid = alloc_pid(task_active_pid_ns(p));
 		if (!pid)
-			goto bad_fork_cleanup_namespaces;
+			goto bad_fork_cleanup_io;
 
 		if (clone_flags & CLONE_NEWPID) {
 			retval = pid_ns_prepare_proc(task_active_pid_ns(p));
@@ -1234,9 +1262,6 @@
 	/* Need tasklist lock for parent etc handling! */
 	write_lock_irq(&tasklist_lock);
 
-	/* for sys_ioprio_set(IOPRIO_WHO_PGRP) */
-	p->ioprio = current->ioprio;
-
 	/*
 	 * The task hasn't been attached yet, so its cpus_allowed mask will
 	 * not be changed, nor will its assigned CPU.
@@ -1328,6 +1353,8 @@
 bad_fork_free_pid:
 	if (pid != &init_struct_pid)
 		free_pid(pid);
+bad_fork_cleanup_io:
+	put_io_context(p->io_context);
 bad_fork_cleanup_namespaces:
 	exit_task_namespaces(p);
 bad_fork_cleanup_keys:
diff --git a/lib/Makefile b/lib/Makefile
index b6793ed..89841dc 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -6,7 +6,7 @@
 	 rbtree.o radix-tree.o dump_stack.o \
 	 idr.o int_sqrt.o extable.o prio_tree.o \
 	 sha1.o irq_regs.o reciprocal_div.o argv_split.o \
-	 proportions.o prio_heap.o
+	 proportions.o prio_heap.o scatterlist.o
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
new file mode 100644
index 0000000..acca490
--- /dev/null
+++ b/lib/scatterlist.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2007 Jens Axboe <jens.axboe@oracle.com>
+ *
+ * Scatterlist handling helpers.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+
+/**
+ * sg_next - return the next scatterlist entry in a list
+ * @sg:		The current sg entry
+ *
+ * Description:
+ *   Usually the next entry will be @sg@ + 1, but if this sg element is part
+ *   of a chained scatterlist, it could jump to the start of a new
+ *   scatterlist array.
+ *
+ **/
+struct scatterlist *sg_next(struct scatterlist *sg)
+{
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		return NULL;
+
+	sg++;
+	if (unlikely(sg_is_chain(sg)))
+		sg = sg_chain_ptr(sg);
+
+	return sg;
+}
+EXPORT_SYMBOL(sg_next);
+
+/**
+ * sg_last - return the last scatterlist entry in a list
+ * @sgl:	First entry in the scatterlist
+ * @nents:	Number of entries in the scatterlist
+ *
+ * Description:
+ *   Should only be used casually, it (currently) scans the entire list
+ *   to get the last entry.
+ *
+ *   Note that the @sgl@ pointer passed in need not be the first one,
+ *   the important bit is that @nents@ denotes the number of entries that
+ *   exist from @sgl@.
+ *
+ **/
+struct scatterlist *sg_last(struct scatterlist *sgl, unsigned int nents)
+{
+#ifndef ARCH_HAS_SG_CHAIN
+	struct scatterlist *ret = &sgl[nents - 1];
+#else
+	struct scatterlist *sg, *ret = NULL;
+	unsigned int i;
+
+	for_each_sg(sgl, sg, nents, i)
+		ret = sg;
+
+#endif
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+	BUG_ON(!sg_is_last(ret));
+#endif
+	return ret;
+}
+EXPORT_SYMBOL(sg_last);
+
+/**
+ * sg_init_table - Initialize SG table
+ * @sgl:	   The SG table
+ * @nents:	   Number of entries in table
+ *
+ * Notes:
+ *   If this is part of a chained sg table, sg_mark_end() should be
+ *   used only on the last table part.
+ *
+ **/
+void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+	memset(sgl, 0, sizeof(*sgl) * nents);
+#ifdef CONFIG_DEBUG_SG
+	{
+		unsigned int i;
+		for (i = 0; i < nents; i++)
+			sgl[i].sg_magic = SG_MAGIC;
+	}
+#endif
+	sg_mark_end(&sgl[nents - 1]);
+}
+EXPORT_SYMBOL(sg_init_table);
+
+/**
+ * sg_init_one - Initialize a single entry sg list
+ * @sg:		 SG entry
+ * @buf:	 Virtual address for IO
+ * @buflen:	 IO length
+ *
+ **/
+void sg_init_one(struct scatterlist *sg, const void *buf, unsigned int buflen)
+{
+	sg_init_table(sg, 1);
+	sg_set_buf(sg, buf, buflen);
+}
+EXPORT_SYMBOL(sg_init_one);
+
+/*
+ * The default behaviour of sg_alloc_table() is to use these kmalloc/kfree
+ * helpers.
+ */
+static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask)
+{
+	if (nents == SG_MAX_SINGLE_ALLOC)
+		return (struct scatterlist *) __get_free_page(gfp_mask);
+	else
+		return kmalloc(nents * sizeof(struct scatterlist), gfp_mask);
+}
+
+static void sg_kfree(struct scatterlist *sg, unsigned int nents)
+{
+	if (nents == SG_MAX_SINGLE_ALLOC)
+		free_page((unsigned long) sg);
+	else
+		kfree(sg);
+}
+
+/**
+ * __sg_free_table - Free a previously mapped sg table
+ * @table:	The sg table header to use
+ * @max_ents:	The maximum number of entries per single scatterlist
+ * @free_fn:	Free function
+ *
+ *  Description:
+ *    Free an sg table previously allocated and setup with
+ *    __sg_alloc_table().  The @max_ents value must be identical to
+ *    that previously used with __sg_alloc_table().
+ *
+ **/
+void __sg_free_table(struct sg_table *table, unsigned int max_ents,
+		     sg_free_fn *free_fn)
+{
+	struct scatterlist *sgl, *next;
+
+	if (unlikely(!table->sgl))
+		return;
+
+	sgl = table->sgl;
+	while (table->orig_nents) {
+		unsigned int alloc_size = table->orig_nents;
+		unsigned int sg_size;
+
+		/*
+		 * If we have more than max_ents segments left,
+		 * then assign 'next' to the sg table after the current one.
+		 * sg_size is then one less than alloc size, since the last
+		 * element is the chain pointer.
+		 */
+		if (alloc_size > max_ents) {
+			next = sg_chain_ptr(&sgl[max_ents - 1]);
+			alloc_size = max_ents;
+			sg_size = alloc_size - 1;
+		} else {
+			sg_size = alloc_size;
+			next = NULL;
+		}
+
+		table->orig_nents -= sg_size;
+		free_fn(sgl, alloc_size);
+		sgl = next;
+	}
+
+	table->sgl = NULL;
+}
+EXPORT_SYMBOL(__sg_free_table);
+
+/**
+ * sg_free_table - Free a previously allocated sg table
+ * @table:	The mapped sg table header
+ *
+ **/
+void sg_free_table(struct sg_table *table)
+{
+	__sg_free_table(table, SG_MAX_SINGLE_ALLOC, sg_kfree);
+}
+EXPORT_SYMBOL(sg_free_table);
+
+/**
+ * __sg_alloc_table - Allocate and initialize an sg table with given allocator
+ * @table:	The sg table header to use
+ * @nents:	Number of entries in sg list
+ * @max_ents:	The maximum number of entries the allocator returns per call
+ * @gfp_mask:	GFP allocation mask
+ * @alloc_fn:	Allocator to use
+ *
+ * Description:
+ *   This function returns a @table @nents long. The allocator is
+ *   defined to return scatterlist chunks of maximum size @max_ents.
+ *   Thus if @nents is bigger than @max_ents, the scatterlists will be
+ *   chained in units of @max_ents.
+ *
+ * Notes:
+ *   If this function returns non-0 (eg failure), the caller must call
+ *   __sg_free_table() to cleanup any leftover allocations.
+ *
+ **/
+int __sg_alloc_table(struct sg_table *table, unsigned int nents,
+		     unsigned int max_ents, gfp_t gfp_mask,
+		     sg_alloc_fn *alloc_fn)
+{
+	struct scatterlist *sg, *prv;
+	unsigned int left;
+
+#ifndef ARCH_HAS_SG_CHAIN
+	BUG_ON(nents > max_ents);
+#endif
+
+	memset(table, 0, sizeof(*table));
+
+	left = nents;
+	prv = NULL;
+	do {
+		unsigned int sg_size, alloc_size = left;
+
+		if (alloc_size > max_ents) {
+			alloc_size = max_ents;
+			sg_size = alloc_size - 1;
+		} else
+			sg_size = alloc_size;
+
+		left -= sg_size;
+
+		sg = alloc_fn(alloc_size, gfp_mask);
+		if (unlikely(!sg))
+			return -ENOMEM;
+
+		sg_init_table(sg, alloc_size);
+		table->nents = table->orig_nents += sg_size;
+
+		/*
+		 * If this is the first mapping, assign the sg table header.
+		 * If this is not the first mapping, chain previous part.
+		 */
+		if (prv)
+			sg_chain(prv, max_ents, sg);
+		else
+			table->sgl = sg;
+
+		/*
+		 * If no more entries after this one, mark the end
+		 */
+		if (!left)
+			sg_mark_end(&sg[sg_size - 1]);
+
+		/*
+		 * only really needed for mempool backed sg allocations (like
+		 * SCSI), a possible improvement here would be to pass the
+		 * table pointer into the allocator and let that clear these
+		 * flags
+		 */
+		gfp_mask &= ~__GFP_WAIT;
+		gfp_mask |= __GFP_HIGH;
+		prv = sg;
+	} while (left);
+
+	return 0;
+}
+EXPORT_SYMBOL(__sg_alloc_table);
+
+/**
+ * sg_alloc_table - Allocate and initialize an sg table
+ * @table:	The sg table header to use
+ * @nents:	Number of entries in sg list
+ * @gfp_mask:	GFP allocation mask
+ *
+ *  Description:
+ *    Allocate and initialize an sg table. If @nents@ is larger than
+ *    SG_MAX_SINGLE_ALLOC a chained sg table will be setup.
+ *
+ **/
+int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
+{
+	int ret;
+
+	ret = __sg_alloc_table(table, nents, SG_MAX_SINGLE_ALLOC,
+			       gfp_mask, sg_kmalloc);
+	if (unlikely(ret))
+		__sg_free_table(table, SG_MAX_SINGLE_ALLOC, sg_kfree);
+
+	return ret;
+}
+EXPORT_SYMBOL(sg_alloc_table);
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
index b48c729..8849041 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -835,7 +835,7 @@
 static irqreturn_t
 waveartist_intr(int irq, void *dev_id)
 {
-	wavnc_info *devc = (wavnc_info *)dev_id;
+	wavnc_info *devc = dev_id;
 	int	   irqstatus, status;
 
 	spin_lock(&waveartist_lock);