diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index cb12ae175aa2de80b3114434c20e64cac4857593..53a63890aea49a9def4240e426ddce1db32439c8 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -141,6 +141,7 @@ architectures:
 - 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 a04f507e7f2ca94f1b959d0e03dac7f0a3c73575..e53b0ed9d00a39718c2010f6bf44538f3df15742 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -180,8 +180,8 @@ config ARCH_AT91
 	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 @@ config ARCH_EP93XX
 	bool "EP93xx-based"
 	select ARM_AMBA
 	select ARM_VIC
+	select GENERIC_GPIO
 	help
 	  This enables support for the Cirrus EP93xx series of CPUs.
 
@@ -366,6 +367,7 @@ config ARCH_SA1100
 	select ARCH_DISCONTIGMEM_ENABLE
 	select ARCH_MTD_XIP
 	select GENERIC_GPIO
+	select GENERIC_TIME
 	help
 	  Support for StrongARM 11x0 based boards.
 
@@ -409,6 +411,17 @@ config ARCH_OMAP
 	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"
@@ -477,6 +490,8 @@ source "arch/arm/mach-davinci/Kconfig"
 
 source "arch/arm/mach-ks8695/Kconfig"
 
+source "arch/arm/mach-msm/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
@@ -657,6 +672,7 @@ config HZ
 	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
@@ -951,7 +967,7 @@ config FPE_FASTFPE
 
 config VFP
 	bool "VFP-format floating point maths"
-	depends on CPU_V6 || CPU_ARM926T
+	depends on CPU_V6 || CPU_ARM926T || CPU_V7
 	help
 	  Say Y to include VFP support code in the kernel. This is needed
 	  if your hardware includes a VFP unit.
@@ -961,6 +977,18 @@ config VFP
 
 	  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 18101f5f5f249b0377c1fe4299c9094f6db16af7..192ee01a9ba20b00fef403afa3ffb07d04ec0d19 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -43,6 +43,12 @@ config DEBUG_ERRORS
 	  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 63b8c6d5606ad34a6ba799df038e3e886c4e3fd7..453ad8e15d6995ce876683476791dbfd28f8b678 100644
--- a/arch/arm/Kconfig.instrumentation
+++ b/arch/arm/Kconfig.instrumentation
@@ -43,6 +43,16 @@ config OPROFILE_MPCORE
 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 35e56c99ad1ddbaf64c76faecefe258cb88ed072..dd220d1898439c8ea7a89aa61897c10406a70328 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -139,6 +139,7 @@ endif
  machine-$(CONFIG_ARCH_KS8695)     := ks8695
   incdir-$(CONFIG_ARCH_MXC)	   := mxc
  machine-$(CONFIG_ARCH_MX3)	   := mx3
+ 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 5fde99f9d9f93dafbf2e555a646b3f08ebbbc561..de9d9ee50958089bcf8fb7217fd1c48617d6097c 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -44,10 +44,6 @@ ifeq ($(CONFIG_PXA_SHARPSL),y)
 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 11782ccd93a1d705019bf37f03be3e7f1bf19308..0000000000000000000000000000000000000000
--- 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/common/rtctime.c b/arch/arm/common/rtctime.c
index bf1075e1f571d32794e92fd01aa18c2594a53971..f53bca46e23cadb5e35dd847173b5028a7ffa1c8 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 0000000000000000000000000000000000000000..e32e73648129d36ac9726b10d2723b7d38e918db
--- /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/collie_defconfig b/arch/arm/configs/collie_defconfig
index 970c8c772eb71a31d046f3316bd388b3f1cf0336..4264e273202d21a9df214b818b1f409583d020d0 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -367,7 +367,6 @@ 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_OBSOLETE_CHIPS=y
 CONFIG_MTD_SHARP=y
 # CONFIG_MTD_XIP is not set
 
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
index add03c9e55531bcb0e7e17d617154aa8aa843236..988b4d13e76f5c9da6389615a74c0533ac703eba 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_VECTORS_BASE=0xffff0000
 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=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=y
@@ -69,7 +70,6 @@ CONFIG_FUTEX=y
 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_IOP13XX=y
 # 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_IQ81340SC=y
 CONFIG_MACH_IQ81340MC=y
 
 #
-# IOP13XX IMU Support
+# Boot options
+#
+
+#
+# Power management
 #
-# CONFIG_IOP_IMU is not set
 CONFIG_PLAT_IOP=y
 
 #
@@ -185,10 +189,7 @@ CONFIG_PCI=y
 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_MANUAL=y
 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 @@ CONFIG_BINFMT_AOUT=y
 # Power management options
 #
 # CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
 
 #
 # Networking
@@ -285,6 +288,7 @@ CONFIG_IP_PNP_BOOTP=y
 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_IPV6=y
 # 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 @@ CONFIG_IPV6=y
 #
 # 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_MTD_BLOCK=y
 # 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_START=0xfa000000
 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_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_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_WAIT_SCAN=m
 # 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_SAS_ATTRS=y
 # 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_BLK_DEV_DM=y
 # 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_NETDEVICES=y
 # 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_NETDEV_1000=y
 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_E1000_NAPI=y
 # 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_E1000_NAPI=y
 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=y
 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_UNIX98_PTYS=y
 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_I2C_IOP3XX=y
 # 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_HWMON=y
 # 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_HWMON=y
 # 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,29 +814,18 @@ CONFIG_HWMON=y
 # 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
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
+# CONFIG_WATCHDOG is not set
 
 #
-# LED drivers
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# LED Triggers
+# Multifunction device drivers
 #
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
@@ -840,14 +837,16 @@ CONFIG_DAB=y
 #
 # 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_DUMMY_CONSOLE=y
 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_ARCH_HAS_EHCI=y
 #
 # 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
 
 #
@@ -894,12 +893,6 @@ CONFIG_DMA_ENGINE=y
 #
 # CONFIG_NET_DMA is not set
 
-#
-# DMA Devices
-#
-# CONFIG_INTEL_IOATDMA is not set
-CONFIG_INTEL_IOP_ADMA=y
-
 #
 # File systems
 #
@@ -912,7 +905,6 @@ CONFIG_EXT3_FS_XATTR=y
 # 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_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
 
 #
@@ -969,10 +960,12 @@ CONFIG_ECRYPT_FS=y
 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_CRAMFS=y
 # 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_MSDOS_PARTITION=y
 # 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_DEFAULT="iso8859-1"
 # 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_ENABLE_MUST_CHECK=y
 # 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_DEBUG_USER=y
 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_ECB=y
 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_TEA=y
 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 027aef22b4d15ae54b88908e2a4742b1372f8704..83f40d4041a6650a2e6f35bfa0256cf549c4ff2a 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_VECTORS_BASE=0xffff0000
 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=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 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_FUTEX=y
 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_IOP32X=y
 # 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_IQ80321=y
 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_XSCALE_PMU=y
 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_MANUAL=y
 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 @@ CONFIG_BINFMT_AOUT=y
 # Power management options
 #
 # CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
 
 #
 # Networking
@@ -282,6 +291,7 @@ CONFIG_IP_PNP_BOOTP=y
 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_IPV6=y
 # 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 @@ CONFIG_IPV6=y
 #
 # 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_MTD_BLOCK=y
 # 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_START=0x0
 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_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_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_WAIT_SCAN=m
 # 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_WAIT_SCAN=m
 # 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_SATA_VITESSE=y
 # 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_BLK_DEV_DM=y
 # 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_NETDEVICES=y
 # 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_MII=y
 # 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_NETDEV_1000=y
 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_R8169=y
 # 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_R8169=y
 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_NETDEV_10000=y
 # 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=y
 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_UNIX98_PTYS=y
 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_I2C_IOP3XX=y
 # 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_HWMON=y
 # 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_HWMON=y
 # 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,29 +917,18 @@ CONFIG_HWMON=y
 # 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
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
+# CONFIG_WATCHDOG is not set
 
 #
-# LED drivers
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# LED Triggers
+# Multifunction device drivers
 #
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
@@ -935,14 +941,16 @@ CONFIG_DAB=y
 #
 # 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_DUMMY_CONSOLE=y
 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=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
@@ -1070,28 +1080,66 @@ CONFIG_USB_MON=y
 #
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
+# 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
 
 #
-# Real Time Clock
+# RTC interfaces
 #
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
+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
 
 #
-# DMA Engine support
+# I2C RTC drivers
 #
-CONFIG_DMA_ENGINE=y
+# 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
 
 #
-# DMA Clients
+# SPI RTC drivers
 #
-CONFIG_NET_DMA=y
+
+#
+# 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_IOATDMA is not set
 CONFIG_INTEL_IOP_ADMA=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
 
 #
 # File systems
@@ -1105,7 +1153,6 @@ CONFIG_EXT3_FS_XATTR=y
 # 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_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
 
 #
@@ -1162,10 +1208,12 @@ CONFIG_ECRYPT_FS=y
 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_CRAMFS=y
 # 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_MSDOS_PARTITION=y
 # 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_BUGVERBOSE=y
 # 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_DEBUG_LL=y
 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_ECB=y
 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_TEA=y
 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 721ee64a13f7fb740034a27ef646064f0a2355ff..917afb5ccfacba602b1041b35f6689e5cbb1fc66 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_VECTORS_BASE=0xffff0000
 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=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 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_FUTEX=y
 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_IOP33X=y
 # 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_IOP3XX_ATU=y
 #
 CONFIG_ARCH_IQ80331=y
 CONFIG_MACH_IQ80332=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
 CONFIG_PLAT_IOP=y
 
 #
@@ -179,11 +188,8 @@ CONFIG_XSCALE_PMU=y
 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_MANUAL=y
 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 @@ CONFIG_BINFMT_AOUT=y
 # Power management options
 #
 # CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
 
 #
 # Networking
@@ -279,6 +287,7 @@ CONFIG_IP_PNP_BOOTP=y
 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_IPV6=y
 # 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 @@ CONFIG_IPV6=y
 #
 # 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_MTD_BLOCK=y
 # 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_START=0x0
 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_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_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_WAIT_SCAN=m
 # 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_WAIT_SCAN=m
 # 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_BLK_DEV_DM=y
 # 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_NETDEVICES=y
 # 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_NETDEV_1000=y
 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_E1000_NAPI=y
 # 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_E1000_NAPI=y
 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=y
 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_UNIX98_PTYS=y
 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_I2C_IOP3XX=y
 # 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_HWMON=y
 # 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_HWMON=y
 # 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,29 +816,18 @@ CONFIG_HWMON=y
 # 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
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
+# CONFIG_WATCHDOG is not set
 
 #
-# LED drivers
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# LED Triggers
+# Multifunction device drivers
 #
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
@@ -837,14 +839,16 @@ CONFIG_DAB=y
 #
 # 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_DUMMY_CONSOLE=y
 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_ARCH_HAS_EHCI=y
 #
 # 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
 
 #
@@ -891,12 +895,6 @@ CONFIG_DMA_ENGINE=y
 #
 CONFIG_NET_DMA=y
 
-#
-# DMA Devices
-#
-# CONFIG_INTEL_IOATDMA is not set
-CONFIG_INTEL_IOP_ADMA=y
-
 #
 # File systems
 #
@@ -909,7 +907,6 @@ CONFIG_EXT3_FS_XATTR=y
 # 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_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
 
 #
@@ -969,10 +965,7 @@ CONFIG_CRAMFS=y
 # 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_MSDOS_PARTITION=y
 # 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_BUGVERBOSE=y
 # 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_DEBUG_LL=y
 #
 # 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/msm_defconfig b/arch/arm/configs/msm_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..ae4c5e62086ac454b7e4e140ec66f0acc74dcfbf
--- /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/kernel/Makefile b/arch/arm/kernel/Makefile
index 593b56509f4f5e5eda354016a52f92ba3f4a7905..faa7619211534c541f61e370985cf1480f247f52 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
 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 0a3e9ad297d8ba8be45967e811be5d226941eb90..2f080a35a2d9240181a6edd745394e0942a128e2 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -216,7 +216,7 @@ void __init isa_init_dma(dma_t *dma)
 
 		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 29dec080a60431dd88bfa7b732940449054374ad..a46d5b456765e1416485d2d6eca7919b764c9756 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 @@ common_invalid:
 #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 @@ common_invalid:
 	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 @@ svc_preempt:
 
 	.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 @@ __und_usr:
  * 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 @@ __und_usr:
  *  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 @@ call_fpe:
 	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 @@ do_fpe:
 	.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 33e6cc2ffd3bacbf3c8d030efac78684f52da623..6c90c50a9ee3bc12578ef1ac40fc66678a4ace4e 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -72,7 +72,7 @@ no_work_pending:
 	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 0000000000000000000000000000000000000000..d51bc8b60557243cda3bef93c1e5d29a2c198eca
--- /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 0000000000000000000000000000000000000000..a22a98c43ca5911e9b8f9328509fbd4b9a973ca3
--- /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/traps.c b/arch/arm/kernel/traps.c
index c34db4e868fa530c50b0e6baa7123c88eab76ec8..5595fdd75e8200ec0e8d5ea8a54c750ed0398e1f 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 @@ __setup("user_debug=", user_debug_setup);
 
 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 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 		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 5ff5406666b437c9a8a5b848279d60735b601bc6..30f732c7fdb505b9762b6d12f4fbc6ebf5ebb5ae 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -94,6 +94,7 @@ SECTIONS
 			TEXT_TEXT
 			SCHED_TEXT
 			LOCK_TEXT
+			KPROBES_TEXT
 #ifdef CONFIG_MMU
 			*(.fixup)
 #endif
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 05a9f8a1b45ee5320ddcf3c1d6f18aef96f326be..5b0422cdde76e7504010d8b4a8971ef3d0ca7455 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -22,6 +22,9 @@ config ARCH_AT91SAM9263
 config ARCH_AT91SAM9RL
 	bool "AT91SAM9RL"
 
+config ARCH_AT91CAP9
+	bool "AT91CAP9"
+
 config ARCH_AT91X40
 	bool "AT91x40"
 
@@ -178,6 +181,21 @@ endif
 
 # ----------------------------------------------------------
 
+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 @@ comment "AT91 Board Options"
 
 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 @@ config AT91_PROGRAMMABLE_CLOCKS
 	  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 a21f08c64ea664677ae114873464c8a84c019a76..bf5f293dccf8f5ffee383d9ffb91874d48fb209a 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -8,7 +8,6 @@ obj-n		:=
 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_AT91SAM9260)	+= at91sam9260.o at91sam926x_time.o at91sam9260_d
 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_KB9200)	+= board-kb9202.o
 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 @@ obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
 # 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 e667dcc7cd344a2c1bdd4a87579909d5df331061..071a2506a69fb5ed8abdea4cf51e1fa45ffc22fd 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 0000000000000000000000000000000000000000..48d27d8000b0e8da5f696ad902c36c19fe7b6f6f
--- /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 0000000000000000000000000000000000000000..c50fad9cd143abb0929b070ce03233b06f2dba9d
--- /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 2cad2bf864be3955a445f5ea7482d7a6edd30701..d688c1dbd92565ed2ef3b9e4c867183c868159f2 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -301,28 +301,28 @@ void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks
 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 9296833f91ccd576c7c5dbbacffbf94cb7a28518..ef6aeb86e9805ba402c58cc70afdece13b009419 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 @@ static struct platform_device at91rm9200_usbh_device = {
 	.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 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91rm9200_eth_device = {
 	.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 @@ void __init at91_add_device_cf(struct at91_cf_data *data) {}
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91rm9200_mmc_device = {
 	.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 at91_nand_data nand_data;
 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 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91rm9200_spi_device = {
 	.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 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
 		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 @@ static void __init at91_add_device_watchdog(void) {}
 
 
 /* --------------------------------------------------------------------
- *  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);
+
+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)
+{
+	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);
+}
 
-void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+/*
+ * 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)
 {
-	/* Enable GPIO to access the LEDs */
-	at91_set_gpio_output(cpu_led, 1);
-	at91_set_gpio_output(timer_led, 1);
+	struct platform_device *pdev;
 
-	at91_leds_cpu	= cpu_led;
-	at91_leds_timer	= timer_led;
+	/*
+	 * 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 @@ static struct atmel_uart_data dbgu_data = {
 	.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 @@ static struct atmel_uart_data uart0_data = {
 	.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 @@ static struct atmel_uart_data uart1_data = {
 	.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 @@ static struct atmel_uart_data uart2_data = {
 	.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 @@ static struct atmel_uart_data uart3_data = {
 	.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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 	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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 		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 @@ void __init at91_add_device_serial(void)
 	}
 }
 #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 e47381e8aaba625e7abb5b6ff8cd0acc89ea04f5..18d06612ce8a0e921d52b8451cd4eda588d6f51f 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -327,30 +327,30 @@ void __init at91sam9260_initialize(unsigned long main_clock)
 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 3091bf47d8c96dafb90e694005c3d2f99df7e1df..105f8403860bbd648842bf2e1479b165262d38fb 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 @@ static struct platform_device at91_usbh_device = {
 	.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 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9260_eth_device = {
 	.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 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {}
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9260_mmc_device = {
 	.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 at91_nand_data nand_data;
 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 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
 		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 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9260_spi0_device = {
 	.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 @@ static struct platform_device at91sam9260_spi1_device = {
 	.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 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
 
 
 /* --------------------------------------------------------------------
- *  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 @@ static struct atmel_uart_data dbgu_data = {
 	.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 @@ static struct atmel_uart_data uart0_data = {
 	.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 @@ static struct atmel_uart_data uart1_data = {
 	.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 @@ static struct atmel_uart_data uart2_data = {
 	.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 @@ static struct atmel_uart_data uart3_data = {
 	.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 @@ static struct atmel_uart_data uart4_data = {
 	.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 @@ static struct atmel_uart_data uart5_data = {
 	.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 @@ static inline void configure_usart5_pins(void)
 	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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 	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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 		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 @@ void __init at91_add_device_serial(void)
 	}
 }
 #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 @@ void __init at91_add_device_serial(void) {}
  */
 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 dfe8c39c9fb9343a01910eee7ab7ef345ec8e527..90b87e1877d9006e7555f735c34876a401d5e3ee 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -279,25 +279,25 @@ void __init at91sam9261_initialize(unsigned long main_clock)
 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 64979a9023c2cb4e0a674cbb8cc9303ae0066074..245641263fce1cc1269d55e3b9abda85159235c5 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 @@ static struct platform_device at91sam9261_usbh_device = {
 	.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 @@ static struct platform_device at91sam9261_udc_device = {
 
 void __init at91_add_device_udc(struct at91_udc_data *data)
 {
-	unsigned long x;
-
 	if (!data)
 		return;
 
@@ -116,9 +115,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data)
 		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 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9261_mmc_device = {
 	.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 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
 		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 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9261_spi0_device = {
 	.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 @@ static struct platform_device at91sam9261_spi1_device = {
 	.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 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91_lcdc_device = {
 	.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 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
 		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 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
 	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 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
 
 
 /* --------------------------------------------------------------------
- *  LEDs
+ *  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 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)
+{
+	platform_device_register(&at91sam9261_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ *  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
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  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);
+
+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);
+}
 
-void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+/*
+ * 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)
 {
-	/* Enable GPIO to access the LEDs */
-	at91_set_gpio_output(cpu_led, 1);
-	at91_set_gpio_output(timer_led, 1);
+	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;
+	}
 
-	at91_leds_cpu	= cpu_led;
-	at91_leds_timer	= timer_led;
+	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
 
 
@@ -584,12 +789,15 @@ static struct atmel_uart_data dbgu_data = {
 	.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 @@ static struct atmel_uart_data uart0_data = {
 	.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 @@ static struct atmel_uart_data uart1_data = {
 	.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 @@ static struct atmel_uart_data uart2_data = {
 	.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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 	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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 		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 @@ void __init at91_add_device_serial(void)
 	}
 }
 #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 @@ void __init at91_add_device_serial(void) {}
  */
 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 00e27b177857e3dbe2623d8a4512c7251dbc7100..a53ba0f743519cd188c762e2f352eed89f44a8e8 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -304,34 +304,34 @@ void __init at91sam9263_initialize(unsigned long main_clock)
 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 ac329a98e9596ce1e56e784cab86b0c4f1fdab62..0b12e1adcc8e6588445dd6029a9d8f0dc0ebc872 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 @@ static struct platform_device at91_usbh_device = {
 	.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 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9263_eth_device = {
 	.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 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {}
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9263_mmc0_device = {
 	.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 @@ static struct platform_device at91sam9263_mmc1_device = {
 	.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 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
 		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 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9263_spi0_device = {
 	.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 @@ static struct platform_device at91sam9263_spi1_device = {
 	.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 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9263_ac97_device = {
 	.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 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91_lcdc_device = {
 	.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 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
 
 
 /* --------------------------------------------------------------------
- *  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)
+{
+	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_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)
 {
-	/* Enable GPIO to access the LEDs */
-	at91_set_gpio_output(cpu_led, 1);
-	at91_set_gpio_output(timer_led, 1);
+	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;
+	}
 
-	at91_leds_cpu	= cpu_led;
-	at91_leds_timer	= timer_led;
+	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
 
 
@@ -778,12 +997,15 @@ static struct atmel_uart_data dbgu_data = {
 	.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 @@ static struct atmel_uart_data uart0_data = {
 	.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 @@ static struct atmel_uart_data uart1_data = {
 	.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 @@ static struct atmel_uart_data uart2_data = {
 	.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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 	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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 		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 @@ void __init at91_add_device_serial(void)
 }
 #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 @@ void __init at91_add_device_serial(void) {}
  */
 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 2bd60a3dc6233cac740694121785f8edac22f81a..f43b5c33e45d7c77be4ecd37df3526fa6819cf8c 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 @@ static struct platform_device at91sam9rl_mmc_device = {
 	.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 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91sam9rl_spi_device = {
 	.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 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
  * -------------------------------------------------------------------- */
 
 #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 @@ static struct platform_device at91_lcdc_device = {
 	.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 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
 
 
 /* --------------------------------------------------------------------
- *  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);
+	platform_device_register(&at91sam9rl_rtc_device);
+}
+#else
+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),
+};
 
-	at91_leds_cpu	= cpu_led;
-	at91_leds_timer	= timer_led;
+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
-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	= 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 @@ static struct atmel_uart_data dbgu_data = {
 	.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 @@ static struct atmel_uart_data uart0_data = {
 	.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 @@ static struct atmel_uart_data uart1_data = {
 	.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 @@ static struct atmel_uart_data uart2_data = {
 	.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 @@ static struct atmel_uart_data uart3_data = {
 	.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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 	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 @@ void __init at91_init_serial(struct at91_uart_config *config)
 		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 @@ void __init at91_add_device_serial(void)
 	}
 }
 #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 @@ void __init at91_add_device_serial(void) {}
  */
 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 0000000000000000000000000000000000000000..1854371315411bef6dbbaac7d6b86a2e18c1cdd7
--- /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 d0aa20c9383e355da4e313e35fd533cb49269263..0e2a11fc5bbd587315b0a6f0a78d8ee3ef31dc25 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 @@ static struct platform_device csb_flash = {
 	.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 @@ static void __init csb337_board_init(void)
 	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 40c9e4331706b0a32cac592603bfba036ccefa88..0a897efeba8e5321dc8fdfec5da831aa7a554f73 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -183,6 +183,14 @@ static struct platform_device dk_flash = {
 	.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 @@ static void __init dk_board_init(void)
 	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 53a5ef9e72eeec7844007282896002f0e0f8552e..0574e50a30dd096bbb5f012ac522895518b8a880 100644
--- a/arch/arm/mach-at91/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -141,6 +141,25 @@ static struct platform_device ek_flash = {
 	.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 @@ static void __init ek_board_init(void)
 #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 550ae59a3aca89524def4fdf310d9ce015c848a7..aa29ea58ca09ee9b99286b78a022264d800c71bc 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -280,6 +280,68 @@ static struct spi_board_info ek_spi_devices[] = {
  * 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_videomode at91_tft_vga_modes[] = {
 	},
 };
 
-static struct fb_monspecs at91fb_default_monspecs = {
+static struct fb_monspecs at91fb_default_tft_monspecs = {
 	.manufacturer	= "HIT",
 	.monitor        = "TX09D50VM1CCA",
 
@@ -308,11 +370,11 @@ static struct fb_monspecs at91fb_default_monspecs = {
 	.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 @@ static void at91_lcdc_power_control(int on)
 		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 atmel_lcdfb_info __initdata ek_lcdc_data;
 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 ab9dcc0754541f5f952e934c439e525beebf6b7a..f09347a86e7116c31d59c43468b1b749b8adba85 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 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
  * MACB Ethernet device
  */
 static struct at91_eth_data __initdata ek_macb_data = {
+	.phy_irq_pin	= AT91_PIN_PE31,
 	.is_rmii	= 1,
 };
 
@@ -263,6 +266,55 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
 #endif
 
 
+/*
+ * 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
  */
@@ -271,6 +323,30 @@ static struct atmel_ac97_data ek_ac97_data = {
 };
 
 
+/*
+ * 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 @@ static void __init ek_board_init(void)
 	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 57c3b647ce834f06a790f04f48d18b11e7fd5d65..ec76eeaafd4566aece7f89c5057adf7bc4b76c8a 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -574,6 +574,8 @@ int __init at91_clock_init(unsigned long main_clock)
 	} 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 77d4c0a378421b8044dcb1aa6e3847d2b6304951..b5daf7f5e011a797cc6b88f75ae9b9170a451174 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -15,6 +15,7 @@ extern void __init at91sam9261_initialize(unsigned long main_clock);
 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 at91sam9261_init_interrupts(unsigned int priority[]);
 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 aa2d365c93fb65a7bbacd45263b77262b24b4b4a..6aeddd68d8af040e048489d4ebff70fa94a79663 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 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 
 /*--------------------------------------------------------------------------*/
 
+#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 0d5144973988e6484681d0cde72d233e93378cfb..9cdcda500fe8195324cfe86d4cc1670381142ac1 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 @@ static int __init leds_init(void)
 }
 
 __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 98cb61482917a921d5ddaec2bc13925999097a0b..4b120cc361359760a542eaea0825365bba5e6b33 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -80,6 +80,11 @@ static int at91_pm_verify_clocks(void)
 			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-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index f1074ff02fdbb5fdaebe505157e1a36651a70185..91f6a07a51d54d16d28b8111f953b9b4fe0a04a3 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>
@@ -153,38 +153,41 @@ static unsigned char gpio_int_enabled[3];
 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]));
 
-static unsigned char data_register_offset[8] = {
-	0x00, 0x04, 0x08, 0x0c, 0x20, 0x30, 0x38, 0x40,
+	__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]));
+}
+
+/* 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;
@@ -195,14 +198,10 @@ void gpio_line_config(int line, int direction)
 
 	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);
@@ -215,39 +214,58 @@ void gpio_line_config(int line, int direction)
 	}
 	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);
 
 
 /*************************************************************************
@@ -261,47 +279,67 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
 	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));
@@ -310,7 +348,7 @@ static void ep93xx_gpio_irq_mask(unsigned int irq)
 
 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);
@@ -325,38 +363,54 @@ static void ep93xx_gpio_irq_unmask(unsigned int irq)
  */
 static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
 {
-	int port;
-	int line;
-
-	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);
+	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);
+
+	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;
-
-	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);
-	}
+	gpio_int_enabled[port] |= port_mask;
+
+	desc->status &= ~IRQ_TYPE_SENSE_MASK;
+	desc->status |= type & IRQ_TYPE_SENSE_MASK;
+
 	update_gpio_int_params(port);
 
 	return 0;
@@ -364,7 +418,8 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
 
 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,
@@ -373,15 +428,16 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
 
 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-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index d4d8134ce567ae5dfd8402b1945f0c17cc7fbd5d..d55fa4e9bb43066a366e18537f1905b1fd593363 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -440,7 +440,7 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	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 @@ static irqreturn_t v3_irq(int irq, void *devid)
 	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 2b086ab2668ca24bd990ef0219c2385c64f4921a..74c65ce221dee74ab6aca8b467a42e12241af4e1 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 @@ subsys_initcall(glantank_pci_init);
  * 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 @@ static struct platform_device glantank_serial_device = {
 	.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 @@ static void __init glantank_init_machine(void)
 	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-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index 16356ffc86ae9824b3f522e475323a7c87295e3b..5fea5a132939abc1c608bec1a04940b7ae7612d6 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 7a85ced567184c06487742bad59c9db0a5cce56f..d3a779a7a35fbb8d29cc77be82101386c7fad8fb 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 c41a6b5a0accbe986eafbbbf50f603c5c203e669..5c5d4d66dee800e5277f451249339d8755b1d509 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 e35644961aa442d9766a168088bee79713bd3151..f0f70ba1e46d7c6a14d6b0ccb8ca10ede4777e5e 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 acd71e9c38a703792cc08d739ba1f0db81a2909b..6f10dc208320ed0d0906372cf6bd8c04bed87a07 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 2a07a281fa8ae927f9957575f4c448a81bad8815..730a3af12c985f53467c6281209f864dc9e5cd74 100644
--- a/arch/arm/mach-ks8695/Makefile
+++ b/arch/arm/mach-ks8695/Makefile
@@ -9,7 +9,7 @@ obj-n				:=
 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 2feeef81d84328ee3a3a3414718264b7f418b386..05ac2bd040205e5dd949b96d164727daa8ea60dd 100644
--- a/arch/arm/mach-ks8695/board-micrel.c
+++ b/arch/arm/mach-ks8695/board-micrel.c
@@ -40,7 +40,7 @@ static void __init micrel_init(void)
 	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 b1aa3cb3d4a3a782132fde8dd0655d94e16dc5c5..5e46191c0af967a8cc9a36b30c49c594af8ebc0a 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 @@ int irq_to_gpio(unsigned int irq)
 	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 0000000000000000000000000000000000000000..3f4e0330cb1a67f19380ca589044946099cfb1de
--- /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-msm/Kconfig b/arch/arm/mach-msm/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..3553babbbf0541653a899ee3b18317736a01ba79
--- /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 0000000000000000000000000000000000000000..d12f2365585096d2d8ee3ffe04652a13d66318ca
--- /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 0000000000000000000000000000000000000000..24dfbf8c07c47dc8d4e9bb5a01daf62b6a780fd5
--- /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 0000000000000000000000000000000000000000..86dfb2b5261c5073fa6be44ecf726beed01c78fe
--- /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 0000000000000000000000000000000000000000..3f5d3362f887da2de2f3bab432a9cdec0a967f19
--- /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 0000000000000000000000000000000000000000..8b0f339b32746d802e7b3e9c26b74a6b74a842cb
--- /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 0000000000000000000000000000000000000000..2b1cb7f16943e7fbd39f61169e43f3f05e661601
--- /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 0000000000000000000000000000000000000000..c39edb994a883b40aaf12f0bc8617a448d3bf4f6
--- /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 0000000000000000000000000000000000000000..24158040b789805167ce05a06108445efbffc989
--- /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 0000000000000000000000000000000000000000..bd4732d1ab3eea55159334d54ef66578088cfcd3
--- /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-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 182a98a9df4c9e33cd55169bdae113d01daed629..e2c8ffd75cff45ceaa6a28f00acf2fc58edbdc2f 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 5b575e687a2a0c65f89cfb4830beba6df6e1cd2b..4e016179f31229f3ab1352b30ca291622c4f21ae 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>
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index e47010fec27548920c95f397b35699642a2edcb8..ed7094a70064c2c0b50b04b204a2b76f8a0be38e 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 c275d517764a91013b47003f8f2d91da86d96582..a9a0f6610c3deef2427ee72f6b80ae7c1885c53e 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/pm.c b/arch/arm/mach-omap1/pm.c
index d9805e3d930400de42e49afd8216e3a8c71bb745..06b7e54a01280f8b92a33fe9cd66f8d3bd7fb492 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -639,7 +639,7 @@ static void omap_pm_finish(void)
 }
 
 
-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-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 3bb49c17c858e063e0405046bf4e298ee5379471..94e38cc2bb6c6ce37169e4fbdde4343476173dc2 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>
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 422afee88169414dbd5cb74f57f481b7cbc240e5..b2eb38543d1c3e4b73890e3af0053357a550cfab 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -67,7 +67,7 @@ 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;
+	struct ssp_dev *dev = dev_id;
 	unsigned int status = SSSR_P(dev->port);
 
 	SSSR_P(dev->port) = status; /* clear status bits */
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 587864fe25fb09f169b519dcc16d54dbb13c773d..66175471fff30492ebf45e8a4518b20af5915344 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -530,7 +530,7 @@ static struct s3c2410fb_mach_info __initdata bast_fb_info = {
 
 	.displays = bast_lcd_info,
 	.num_displays = ARRAY_SIZE(bast_lcd_info),
-	.default_display = 4,
+	.default_display = 1,
 };
 
 /* Standard BAST devices */
@@ -540,7 +540,6 @@ static struct platform_device *bast_devices[] __initdata = {
 	&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 9f43f3f124f561eeec3efa9b5bbc16a9c083b5e1..3aade7b78fe5929a4deddb621f858b424336d8af 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -365,7 +365,6 @@ static struct platform_device *vr1000_devices[] __initdata = {
 	&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 bcd562ac1d3da4899dca3b73ac3e9184e6c2d55e..6aec86a5da56aac0ca0a88ac0c97ebaec6a86712 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -60,7 +60,7 @@ usb_simtec_powercontrol(int port, int to)
 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 8e8fe48ea47f24f9deb1419f5a0ed7c48693a5a3..0b43431d4b7535204cd3af019ddefdc0da55e0e0 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -10,6 +10,7 @@ config CPU_S3C2412
 	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 f8e011691b31436de06a5c7b4fb987f1f6774e63..267f3348301e4dcfe4ad1e5777abc7301ded0597 100644
--- a/arch/arm/mach-s3c2412/Makefile
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -12,8 +12,9 @@ obj-				:=
 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 458993601897044244a767bc357f21e0f1d183b1..2697a65ba7271bcb58d80aeb24e2550872350979 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -217,7 +217,7 @@ static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
 
 	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 @@ static struct clk clk_msysclk = {
 	.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 @@ static struct clk *clks[] __initdata = {
 	&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 @@ int __init s3c2412_baseclk_add(void)
 	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 @@ int __init s3c2412_baseclk_add(void)
 		}
 	}
 
+	/* 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 53c1d5bbce1953540918e175874b72455126d0ed..1dd8649935662383989c81cc6d90fea834152390 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 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
 	[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 0000000000000000000000000000000000000000..8e55c3a2eab82e404ba3299600a3f69377206e48
--- /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 e9d0c769f5da2e576891953d27f8f6d18c477714..cc1917bf952ad2e24872141eb04d7869ccd416ee 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 @@ static struct irq_chip s3c2412_irq_cfsdi = {
 	.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 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
 		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 8988dac388a9cf83e3182f4aac1a0d19c3431f29..d4ffb2d98076d25674491d2af7b286c3f737eeb6 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 @@ static void s3c2412_cpu_suspend(void)
 	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 @@ static struct sleep_save s3c2412_sleep[] = {
 	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 265cd3f567a3fe164bbe9027cd2856120e725dd9..abf1599c9f97f277b009fd6c64ed6e14629bba46 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -168,6 +168,8 @@ void __init s3c2412_init_clocks(int xtal)
 
 	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 0000000000000000000000000000000000000000..db32cac4199a79a23f7aed3ce0ae210c7fafa8bd
--- /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 79e2ea4adaf36defb9b1f863c1a0444146d2a9e0..184d804934c9b3d8c4d185a95b5c28208323083a 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -111,14 +111,9 @@ static struct clk s3c2440_clk_ac97 = {
 
 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 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
 		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 5b9e830ac4d30a337529ad5e3609e786932f5954..2d030d439fe9ab8048a26438f4091566d6550f49 100644
--- a/arch/arm/mach-s3c2442/clock.c
+++ b/arch/arm/mach-s3c2442/clock.c
@@ -115,14 +115,9 @@ static struct clk s3c2442_clk_cam_upll = {
 
 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 @@ static int s3c2442_clk_add(struct sys_device *sysdev)
 		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 59703c6fb29bc514a83a5d4135989758ad801db9..06206ceb312ef5e4e0f79f274470ab3a0293003f 100644
--- a/arch/arm/mach-sa1100/ssp.c
+++ b/arch/arm/mach-sa1100/ssp.c
@@ -29,9 +29,8 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id)
 {
 	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 47f8640438e6a9d6ede96c45e7933b864a2037e4..c2677368d6af9568d97616b6d0d6becb1a3a5385 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 @@ static int sa1100_set_rtc(void)
 	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;
@@ -92,6 +76,20 @@ static struct irqaction sa1100_timer_irq = {
 	.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;
@@ -105,6 +103,11 @@ static void __init sa1100_timer_init(void)
 	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
@@ -178,7 +181,6 @@ struct sys_timer sa1100_timer = {
 	.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/mm/Kconfig b/arch/arm/mm/Kconfig
index 7868f4dc1d00a311c4765e74effaf37779e9d476..cb104c2a7329ec9990319f392b35e63668951ecb 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -171,8 +171,8 @@ config CPU_ARM925T
 # 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
@@ -345,8 +345,9 @@ config CPU_XSC3
 # 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
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index a8a7dab757eb4977bfc88201da37dfe85713cdbc..28ad7ab1c0cd9cfc506623ec1dbcc91082bc9c14 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 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
 	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 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
  * 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/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 0360b1f14d11f0c0dc3d3333c8a29b1fc53cf594..45a77df668f12b876bde36f9a95ee1c1c23c38aa 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -212,7 +212,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
 
 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);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index f7b9ccdaacbcff0c0a446488f1436fa10ff236c3..2af5bd5a134420b5aee8b68d0c6d4fe154acf3fb 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -98,9 +98,10 @@ static void omap_mcbsp_dump_reg(u8 id)
 
 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_tx_irq_handler(int irq, void *dev_id)
 
 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 irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
 
 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_tx_dma_callback(int lch, u16 ch_status, void *data)
 
 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 8e5ccaa1f03cb8205cedd294d345065395bc40ec..131d20237dd7b3e8267436d2d4c8632d6862ac4f 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -23,6 +23,7 @@ obj-y				+= clock.o
 
 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 79cda0faec8644d0d17fcf54da0cd9852adcae55..99a44746f8f27f89fb4943197a1d6b55b1a259c8 100644
--- a/arch/arm/plat-s3c24xx/clock.c
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -172,6 +172,15 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	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 @@ EXPORT_SYMBOL(clk_set_parent);
 
 /* 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_xtal = {
 struct clk clk_mpll = {
 	.name		= "mpll",
 	.id		= -1,
+	.set_rate	= clk_default_setrate,
 };
 
 struct clk clk_upll = {
@@ -239,6 +255,7 @@ struct clk clk_f = {
 	.rate		= 0,
 	.parent		= &clk_mpll,
 	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
 };
 
 struct clk clk_h = {
@@ -247,6 +264,7 @@ struct clk clk_h = {
 	.rate		= 0,
 	.parent		= NULL,
 	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
 };
 
 struct clk clk_p = {
@@ -255,6 +273,7 @@ struct clk clk_p = {
 	.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 aae1b9cbaf44b77a0e9f4ea7e9f37c04cd1a1191..ac9ff1666fccf729ba3f2b85b38c21e4e2ed5626 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -525,7 +525,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
 		}
 	} 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 @@ int s3c2410_dma_request(unsigned int channel,
 
 	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 @@ int s3c2410_dma_devconfig(int channel,
 
 	chan->source = source;
 	chan->dev_addr = devaddr;
+	chan->hw_cfg = hwcfg;
 
 	switch (source) {
 	case S3C2410_DMASRC_HW:
@@ -1184,7 +1186,7 @@ int s3c2410_dma_devconfig(int channel,
 		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 @@ int s3c2410_dma_devconfig(int channel,
 		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 @@ int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
 
 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 @@ EXPORT_SYMBOL(s3c2410_dma_getposition);
 
 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_suspend(struct sys_device *dev, pm_message_t state)
 
 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 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
 
  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 ec3a09c4d18189b486b900c6b62cfc9d3fea5d87..ee99dcc7f0bd2793524da7f90980264967f3ffcc 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -122,6 +122,19 @@ void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
 
 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 @@ int s3c2410_gpio_getirq(unsigned int pin)
 }
 
 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 8fbc88470261b70772b32b03cdb5ed89c0582cbb..d486f5112569bcd66721b892b128f49ddf016126 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -187,7 +187,7 @@ struct irq_chip s3c_irq_level_chip = {
 	.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 4fdb3117744fe1f543f1ee78aa3f7df9fb81b237..bf5581a9aeea3121dd4a3cce6c8c78de5718e087 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -83,38 +83,39 @@ static struct sleep_save core_save[] = {
 	SAVE_ITEM(S3C2410_REFRESH),
 };
 
-static struct sleep_save gpio_save[] = {
-	SAVE_ITEM(S3C2410_GPACON),
-	SAVE_ITEM(S3C2410_GPADAT),
-
-	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 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,
+	},
+};
 
+static struct sleep_save misc_save[] = {
 	SAVE_ITEM(S3C2410_DCLKCON),
 };
 
@@ -486,6 +487,184 @@ static void s3c2410_pm_configure_extint(void)
 	}
 }
 
+/* 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 @@ static int s3c2410_pm_enter(suspend_state_t state)
 
 	/* 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 @@ static int s3c2410_pm_enter(suspend_state_t state)
 	/* 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 0000000000000000000000000000000000000000..faf3e0f9f4e23b9647850038e6312c38b530a4f6
--- /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 0a9a5e7f62e530de62cce704b4e6a62e431c1366..7ed58c0c24c200ec7093d17d5c4528695b07f9cf 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 @@ stork_egg		ARCH_STORK_EGG		STORK_EGG		248
 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 @@ a9200ec			MACH_A9200EC		A9200EC			645
 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 @@ fred_jack		MACH_FRED_JACK		FRED_JACK		939
 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 @@ aidx270			MACH_AIDX270		AIDX270			1134
 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 @@ osstbox			MACH_OSSTBOX		OSSTBOX			1203
 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 @@ xp179			MACH_XP179		XP179			1290
 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 @@ db88f5281		MACH_DB88F5281		DB88F5281		1358
 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 791d0238c68f133d48664663c4812074737b0247..c85860bad585ecfd10d4a316408f8080f7748667 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -265,7 +265,11 @@ struct vfp_double {
  * 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 0ac022f800a13578d97db2a6236f2cc16e86ef03..353f9e5c7919196134e4323c86cb028c0b12eac4 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -99,12 +99,12 @@ vfp_support_entry:
 	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 @@ no_old_VFP_process:
 	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 @@ check_for_exception:
 
 
 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 @@ look_for_VFP_exceptions:
 
 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 @@ process_exception:
 	@   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 @@ vfp_save_state:
 	@ 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 @@ vfp_get_double:
 	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 @@ vfp_put_double:
 	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 7f343a4beca0542151e1a57f1f2c3612159daa14..15b95b5ab97ea6e149efce7bf316a896b2b014c4 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 b4e210df92f2a37084c9dff73ae07b24ce73f725..32455c633f1c389039d455e10f990399c7c16e28 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -125,13 +125,13 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
 	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 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_
 	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 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs)
 /*
  * 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 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
 	 * 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 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
 	 */
 	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 @@ static int __init vfp_init(void)
 {
 	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 @@ static int __init vfp_init(void)
 	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/drivers/net/Kconfig b/drivers/net/Kconfig
index 9af05a2f4af3c433064b245b2aa383d761d99d4e..a6728661c4167ffa065503e2bebcd594b6748b2e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -212,7 +212,7 @@ config MII
 
 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/serial/21285.c b/drivers/serial/21285.c
index facb6785561906dc0b738ed5ca35cbe55946f064..6a48dfa1efe8552fcaa8453d0800a2d58437c764 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -277,6 +277,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
 	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/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index f81d08d6538b6d34ce9d112a18de3dec909d096f..77a3759d6fc7552c83f01139cff84d46f6f85b2c 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -308,7 +308,7 @@ config USB_S3C2410_DEBUG
 
 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/video/Kconfig b/drivers/video/Kconfig
index 5b3dbcfcda48e6794f71a32d130002229b08c794..758435f8a6f8cb32f4e7413ad0eeafa7d4b74239 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -889,7 +889,7 @@ config FB_S1D13XXX
 
 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 7c30cc8df71eb057b313a841f3c120ad75ae05dd..f8e711147501079011887cc86f65365b04b1cf46 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/include/asm-arm/arch-at91/at91_lcdc.h b/include/asm-arm/arch-at91/at91_lcdc.h
deleted file mode 100644
index ab040a40d37b47b01e46ca201d8ac56d0f44495a..0000000000000000000000000000000000000000
--- 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 33ff5b6798ee4b46a60881efad670ac8b2645e7f..52cd8e5dabc996823368b60797e4a43d6764ec1d 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 bae1103fbbb29e0f1e0b0b5020da0246b213319b..39a32633b275a3913a1d971ef74e19d64028ba07 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 ca9a90733456be5fba159820216bc4fd21f04187..f9f2e3cd95c5766caed7ccb2772c930b8885ac61 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 0000000000000000000000000000000000000000..73e1fcf4a0aa059b4c0fe69e375076f75d44a14c
--- /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 0000000000000000000000000000000000000000..a641686b6c3d3b492a4df2905d5bbc3ebc7cde51
--- /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 aacb1e9764220d484be05a0db74a3251d0ad1f76..a8e9fec6c7352ad5ff7441d3f0aa315df42ae689 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 6fc6e4be624e56ca951f216da1141e02972f273d..72f6e668e4143b5245fb7976677b6b53ae7f3448 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 b15f11b7c08de9d8db8406449ae33d38cf248375..84224174e6a1eb8c10af27dbf2f6dbdea3a41674 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 79054965baa636c41582d928a29def0c63286477..55b07bd5316ccf446f6eb902776f53068e0222f6 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 @@ struct at91_eth_data {
 };
 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_i2c(struct i2c_board_info *devices, int nr_de
 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 @@ struct atmel_uart_data {
 };
 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 @@ struct atmel_ac97_data {
 };
 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 080cbb401a874efd1e7e2e6b056e4f2ddd73287a..7145166826a25e1e46c161fba682d2e8474c4b19 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 @@ static inline unsigned long at91_arch_identify(void)
 #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 cc1d850a0788012574c2c44310245789a8b1fbb5..1005eee6219b410da4f384b5879c40e011abb50e 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 8f1cdd38a96986fe31f9ce47a34fac0a236ca053..2c826d8247a3f8471b5ede7a7c7fd31def3d07b2 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 a310698fb4da9eb04e32b3772dd1f52a75732a8e..f1933b0fa43f2badf4d5e00c04f0d26bcd43ed8c 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 1ee14a14cba05f9191435f39ad0b27d972dd0723..9b1864bbd9a87bf12a1d7bed1d703f35b1e81442 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 @@ extern void gpio_line_set(int line, int value);
 #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 @@ extern void gpio_line_set(int line, int value);
 #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 @@ extern void gpio_line_set(int line, int value);
 #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 2a8c63638c5e824cd30aa2a612d185263ba28f05..53d4a68bfc88af8fb40b6ff061117a18583b2b44 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 eeeea90cd5a96f1b08a12acc6b1d00d68a588c4f..9c5d2357aff3ac4689ae36747022f76cb2d6081a 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -61,13 +61,13 @@ __ixp4xx_ioremap(unsigned long addr, size_t size, unsigned int mtype)
 	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 @@ __ixp4xx_writesw(volatile void __iomem *bus_addr, const u16 *vaddr, int count)
 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 @@ __ixp4xx_readsw(const volatile void __iomem *bus_addr, u16 *vaddr, u32 count)
 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 @@ __ixp4xx_ioread32(const void __iomem *addr)
 		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_iowrite32(u32 value, void __iomem *addr)
 		__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 57fcf9fc82e40cfadfe7e9d4994d1dba45b6b6a8..6b95d77aea190e89c233f604461bf945cddc5dfa 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 0000000000000000000000000000000000000000..763051f8ba146147de8ccb9f0a56d732cc729caf
--- /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 0000000000000000000000000000000000000000..393d5272e50618f63175c90f72d0a5e061a14482
--- /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 0000000000000000000000000000000000000000..e4b565b27b35b51b480fbaab0953e92f5bfefd08
--- /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 0000000000000000000000000000000000000000..ee24aece4cb0689a5ec30aec04a311ac17ca8678
--- /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 0000000000000000000000000000000000000000..89af2b70182f43053cf9d5491440f26c020a5776
--- /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 0000000000000000000000000000000000000000..4645ae26b62a2491e1e985ee01af10180b3b8ce5
--- /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 0000000000000000000000000000000000000000..565430cfaa7e8be779469d609a4c90a7c485b2c8
--- /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 0000000000000000000000000000000000000000..b5ce0e9ac86d5274fd7c917126b4f1ab81171290
--- /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 0000000000000000000000000000000000000000..b8955cc26fecbc7e05c49524c1dcaa167b9baa4a
--- /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 0000000000000000000000000000000000000000..7c5544bdd0c7e1ac1143ac617adea9806a887878
--- /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 0000000000000000000000000000000000000000..154b23fb35996f7d0c1d62f89979b5890200394f
--- /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 0000000000000000000000000000000000000000..e91ed786ffec7b3d102230fb3b5074e6110149b9
--- /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 0000000000000000000000000000000000000000..60f8d910e8259d4637e5a9356158240022f9a981
--- /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-s3c2410/debug-macro.S b/include/asm-arm/arch-s3c2410/debug-macro.S
index 9c8cd9abb82ba6bac45b3609be47f949d4f3148f..89076c322726c50566858967b0ea4ea7dfb3452c 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 c6e8d8f64938e4e3aa0af3fb6119ec47ae8202ee..4f291d9b7d938a04c66c6ac8033a8fc9ffd7801c 100644
--- a/include/asm-arm/arch-s3c2410/dma.h
+++ b/include/asm-arm/arch-s3c2410/dma.h
@@ -214,6 +214,7 @@ struct s3c2410_dma_chan {
 	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 6dadf58ff9847842c0644787f23a7e687f91d5d4..29592c3ebf22887079c85012b0bb468c7b234a57 100644
--- a/include/asm-arm/arch-s3c2410/hardware.h
+++ b/include/asm-arm/arch-s3c2410/hardware.h
@@ -50,6 +50,17 @@ extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
 
 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 int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
 
 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 @@ extern int s3c2440_set_dsc(unsigned int pin, unsigned int value);
 
 #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 996f65488d2d01dc2f8c85d6879ce088e1b74ea8..d858b3eb55477785a38e58ef2ea0491741826ed4 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 e39656b7a08625188ac3b190b5fdce002e7b721b..dba9df9d8713bcc2cedf4dde5ff48dacbd86431a 100644
--- a/include/asm-arm/arch-s3c2410/regs-clock.h
+++ b/include/asm-arm/arch-s3c2410/regs-clock.h
@@ -138,6 +138,8 @@ s3c2410_get_pll(unsigned int pllval, unsigned int baseclk)
 #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 c0748511edbc848c7e16faa97b8bfa491025c6f7..1235df70f34edbb465cfef1dcdbedea47431002d 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 b693158b2d3c28fae653ed989a60568c9aec3af2..0ad75d716ded62c0fde3227df1ec0df4f8e66657 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 e4d82341f7badd15ff6fddc18c2824e0993f01da..312ff93b63c6da560dcf21967cda4f1488b76eca 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 f79987be55e8a66833b50ee82fc0b127d6ee9226..13d13b7cfe98165473a74b02fd8d0e868452c2b7 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 63891786dfa03aa867ca804e13e2b86ea9490b29..14de4e596f87b170661faad4cabe21deeb7019aa 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_idle(void)
 static void
 arch_reset(char mode)
 {
+	struct clk *wdtclk;
+
 	if (mode == 's') {
 		cpu_reset(0);
 	}
@@ -70,19 +75,28 @@ arch_reset(char mode)
 
 	__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/fpstate.h b/include/asm-arm/fpstate.h
index f31cda5a55eeb04d7031c227ec7b1071c77338fd..392eb53323238d16a6b9e80a8363960b06c1103e 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 @@ struct vfp_hard_struct {
 	 */
 	__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 0000000000000000000000000000000000000000..4e7bd32288ae6196a2fa5082173d5510cacd0b7a
--- /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 2c59406435e56f1cc244c9258a60bc38c075cb14..c78efe316fc80ad351ed2f8e9bd07350ec133adc 100644
--- a/include/asm-arm/plat-s3c24xx/dma.h
+++ b/include/asm-arm/plat-s3c24xx/dma.h
@@ -32,6 +32,7 @@ struct s3c24xx_dma_map {
 	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 @@ struct s3c24xx_dma_selection {
 
 	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 8af6d9579b31c975bd86ca6e2e6c1c2ed62ab4f9..45746a9953433cdb81d3ff4e65eaf65f46299992 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 0000000000000000000000000000000000000000..25d4058bcfedf8f30e472a2a62c167eba5db10fd
--- /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 4a499a138256e797207bf3c9c36e7d0bd50c3123..ea565b007d0496e9c59d6b70e7185c672c8317c2 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/traps.h b/include/asm-arm/traps.h
index d4f34dc83eb0a20c12c29b7da063f7eb127cd763..f1541afcf85c200c457fb48fc93d5c88d250902d 100644
--- a/include/asm-arm/traps.h
+++ b/include/asm-arm/traps.h
@@ -15,4 +15,13 @@ struct undef_hook {
 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 bd6be9d7f7729a467a509c956505b9d6c6f1bc08..5f9a2cb3d452fb4d1e42a1d43dc95439286f5e8c 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 27fe028b4e72bbd05ff2ec64054e61e1e86a72c9..cccb3892e73c0c24a097f264f0dfd24dc7186771 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 0dc20261c1ea2d8a02ef094f28afb59b6550d7cf..44d0bfa1f4095b7e531b653d43a9a7f6d6a27cb2 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/sound/oss/waveartist.c b/sound/oss/waveartist.c
index b48c72923a13dfb30c35669213112a31baa4ffc2..88490418f9325fea8424e00e1ff54ee811e87230 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -835,7 +835,7 @@ static struct audio_driver waveartist_audio_driver = {
 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);