Merge branch 'devel-stable' into devel

Conflicts:
	arch/arm/kernel/entry-armv.S
	arch/arm/kernel/setup.c
	arch/arm/mm/init.c
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index eb0fae1..771d48d 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -33,7 +33,13 @@
 
 fffe0000	fffeffff	XScale cache flush area.  This is used
 				in proc-xscale.S to flush the whole data
-				cache.  Free for other usage on non-XScale.
+				cache. (XScale does not have TCM.)
+
+fffe8000	fffeffff	DTCM mapping area for platforms with
+				DTCM mounted inside the CPU.
+
+fffe0000	fffe7fff	ITCM mapping area for platforms with
+				ITCM mounted inside the CPU.
 
 fff00000	fffdffff	Fixmap mapping region.  Addresses provided
 				by fix_to_virt() will be located here.
diff --git a/Documentation/arm/tcm.txt b/Documentation/arm/tcm.txt
index 77fd937..7c15871 100644
--- a/Documentation/arm/tcm.txt
+++ b/Documentation/arm/tcm.txt
@@ -19,8 +19,8 @@
 system control coprocessor. Documentation from ARM can be found
 at http://infocenter.arm.com, search for "TCM Status Register"
 to see documents for all CPUs. Reading this register you can
-determine if ITCM (bit 0) and/or DTCM (bit 16) is present in the
-machine.
+determine if ITCM (bits 1-0) and/or DTCM (bit 17-16) is present
+in the machine.
 
 There is further a TCM region register (search for "TCM Region
 Registers" at the ARM site) that can report and modify the location
@@ -35,7 +35,15 @@
 the MMU, but notice that the TCM if often used in situations where
 the MMU is turned off. To avoid confusion the current Linux
 implementation will map the TCM 1 to 1 from physical to virtual
-memory in the location specified by the machine.
+memory in the location specified by the kernel. Currently Linux
+will map ITCM to 0xfffe0000 and on, and DTCM to 0xfffe8000 and
+on, supporting a maximum of 32KiB of ITCM and 32KiB of DTCM.
+
+Newer versions of the region registers also support dividing these
+TCMs in two separate banks, so for example an 8KiB ITCM is divided
+into two 4KiB banks with its own control registers. The idea is to
+be able to lock and hide one of the banks for use by the secure
+world (TrustZone).
 
 TCM is used for a few things:
 
@@ -65,18 +73,18 @@
   memory. Such a heap is great for things like saving
   device state when shutting off device power domains.
 
-A machine that has TCM memory shall select HAVE_TCM in
-arch/arm/Kconfig for itself, and then the
-rest of the functionality will depend on the physical
-location and size of ITCM and DTCM to be defined in
-mach/memory.h for the machine. Code that needs to use
-TCM shall #include <asm/tcm.h> If the TCM is not located
-at the place given in memory.h it will be moved using
-the TCM Region registers.
+A machine that has TCM memory shall select HAVE_TCM from
+arch/arm/Kconfig for itself. Code that needs to use TCM shall
+#include <asm/tcm.h>
 
 Functions to go into itcm can be tagged like this:
 int __tcmfunc foo(int bar);
 
+Since these are marked to become long_calls and you may want
+to have functions called locally inside the TCM without
+wasting space, there is also the __tcmlocalfunc prefix that
+will make the call relative.
+
 Variables to go into dtcm can be tagged like this:
 int __tcmdata foo;
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4e829c6..e39caa8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -10,6 +10,7 @@
 	default y
 	select HAVE_AOUT
 	select HAVE_IDE
+	select HAVE_MEMBLOCK
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select GENERIC_ATOMIC64 if (!CPU_32v6K)
@@ -24,6 +25,7 @@
 	select HAVE_KERNEL_LZMA
 	select HAVE_PERF_EVENTS
 	select PERF_USE_VMALLOC
+	select HAVE_REGS_AND_STACK_ACCESS_API
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
 	  licensed by ARM Ltd and targeted at embedded applications and
@@ -55,7 +57,7 @@
 config GENERIC_CLOCKEVENTS_BROADCAST
 	bool
 	depends on GENERIC_CLOCKEVENTS
-	default y if SMP && !LOCAL_TIMERS
+	default y if SMP
 
 config HAVE_TCM
 	bool
@@ -440,21 +442,6 @@
 	help
 	  Support for Intel's IXP4XX (XScale) family of processors.
 
-config ARCH_L7200
-	bool "LinkUp-L7200"
-	select CPU_ARM720T
-	select FIQ
-	select ARCH_USES_GETTIMEOFFSET
-	help
-	  Say Y here if you intend to run this kernel on a LinkUp Systems
-	  L7200 Software Development Board which uses an ARM720T processor.
-	  Information on this board can be obtained at:
-
-	  <http://www.linkupsys.com/>
-
-	  If you have any questions or comments about the Linux kernel port
-	  to this board, send e-mail to <sjhill@cotw.com>.
-
 config ARCH_DOVE
 	bool "Marvell Dove"
 	select PCI
@@ -734,7 +721,6 @@
 config ARCH_LH7A40X
 	bool "Sharp LH7A40X"
 	select CPU_ARM922T
-	select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM
 	select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
 	select ARCH_USES_GETTIMEOFFSET
 	help
@@ -1048,11 +1034,6 @@
 
 source "arch/arm/common/Kconfig"
 
-config FORCE_MAX_ZONEORDER
-	int
-	depends on SA1111
-	default "9"
-
 menu "Bus support"
 
 config ARM_AMBA
@@ -1189,9 +1170,10 @@
 config LOCAL_TIMERS
 	bool "Use local timer interrupts"
 	depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
-		REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500)
+		REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
+		ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
 	default y
-	select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500)
+	select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_OMAP4 || ARCH_U8500)
 	help
 	  Enable support for local timers on SMP platforms, rather then the
 	  legacy IPI broadcast method.  Local timers allows the system
@@ -1202,10 +1184,10 @@
 
 config HZ
 	int
-	default 128 if ARCH_L7200
 	default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PV210
 	default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
 	default AT91_TIMER_HZ if ARCH_AT91
+	default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE
 	default 100
 
 config THUMB2_KERNEL
@@ -1258,10 +1240,6 @@
 config ARCH_HAS_HOLES_MEMORYMODEL
 	bool
 
-# Discontigmem is deprecated
-config ARCH_DISCONTIGMEM_ENABLE
-	bool
-
 config ARCH_SPARSEMEM_ENABLE
 	bool
 
@@ -1269,13 +1247,7 @@
 	def_bool ARCH_SPARSEMEM_ENABLE
 
 config ARCH_SELECT_MEMORY_MODEL
-	def_bool ARCH_DISCONTIGMEM_ENABLE && ARCH_SPARSEMEM_ENABLE
-
-config NODES_SHIFT
-	int
-	default "4" if ARCH_LH7A40X
-	default "2"
-	depends on NEED_MULTIPLE_NODES
+	def_bool ARCH_SPARSEMEM_ENABLE
 
 config HIGHMEM
 	bool "High Memory Support (EXPERIMENTAL)"
@@ -1307,8 +1279,33 @@
 	  Enable hardware performance counter support for perf events. If
 	  disabled, perf events will use software events only.
 
+config SPARSE_IRQ
+	def_bool n
+	help
+	  This enables support for sparse irqs. This is useful in general
+	  as most CPUs have a fairly sparse array of IRQ vectors, which
+	  the irq_desc then maps directly on to. Systems with a high
+	  number of off-chip IRQs will want to treat this as
+	  experimental until they have been independently verified.
+
 source "mm/Kconfig"
 
+config FORCE_MAX_ZONEORDER
+	int "Maximum zone order" if ARCH_SHMOBILE
+	range 11 64 if ARCH_SHMOBILE
+	default "9" if SA1111
+	default "11"
+	help
+	  The kernel memory allocator divides physically contiguous memory
+	  blocks into "zones", where each zone is a power of two number of
+	  pages.  This option selects the largest power of two that the kernel
+	  keeps in the memory allocator.  If you need to allocate very large
+	  blocks of physically contiguous memory, then you may need to
+	  increase this value.
+
+	  This config option is actually maximum order plus one. For example,
+	  a value of 11 means that the largest free memory block is 2^10 pages.
+
 config LEDS
 	bool "Timer and CPU usage LEDs"
 	depends on ARCH_CDB89712 || ARCH_EBSA110 || \
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 21ceada..63d998e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -143,7 +143,6 @@
 machine-$(CONFIG_ARCH_IXP4XX)		:= ixp4xx
 machine-$(CONFIG_ARCH_KIRKWOOD)		:= kirkwood
 machine-$(CONFIG_ARCH_KS8695)		:= ks8695
-machine-$(CONFIG_ARCH_L7200)		:= l7200
 machine-$(CONFIG_ARCH_LH7A40X)		:= lh7a40x
 machine-$(CONFIG_ARCH_LOKI) 		:= loki
 machine-$(CONFIG_ARCH_LPC32XX)		:= lpc32xx
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index cc8380b..c2225fe 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -20,10 +20,6 @@
 OBJS		+= head-shark.o ofw-shark.o
 endif
 
-ifeq ($(CONFIG_ARCH_L7200),y)
-OBJS		+= head-l7200.o
-endif
-
 ifeq ($(CONFIG_ARCH_P720T),y)
 # Borrow this code from SA1100
 OBJS		+= head-sa1100.o
diff --git a/arch/arm/boot/compressed/head-l7200.S b/arch/arm/boot/compressed/head-l7200.S
deleted file mode 100644
index d0e3b20..0000000
--- a/arch/arm/boot/compressed/head-l7200.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/* 
- * linux/arch/arm/boot/compressed/head-l7200.S
- * 
- * Copyright (C) 2000 Steve Hill <sjhill@cotw.com>
- * 
- * Some code borrowed from Nicolas Pitre's 'head-sa1100.S' file. This
- * is merged with head.S by the linker.
- */
-
-#include <asm/mach-types.h>
-
-#ifndef CONFIG_ARCH_L7200
-#error What am I doing here...
-#endif
-
-		.section        ".start", "ax"
-
-__L7200_start:
-		mov	r0, #0x00100000		@ FLASH address of initrd
-		mov	r2, #0xf1000000		@ RAM address of initrd
-		add	r3, r2, #0x00700000	@ Size of initrd 
-1:
-		ldmia   r0!, {r4, r5, r6, r7}
-		stmia   r2!, {r4, r5, r6, r7}
-		cmp	r2, r3
-		ble	1b
-
-		mov	r8, #0			@ Zero it out
-		mov	r7, #MACH_TYPE_L7200	@ Set architecture ID
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 337741f..7dfa9a8 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -108,6 +108,51 @@
 	spin_unlock(&irq_controller_lock);
 }
 
+static int gic_set_type(unsigned int irq, unsigned int type)
+{
+	void __iomem *base = gic_dist_base(irq);
+	unsigned int gicirq = gic_irq(irq);
+	u32 enablemask = 1 << (gicirq % 32);
+	u32 enableoff = (gicirq / 32) * 4;
+	u32 confmask = 0x2 << ((gicirq % 16) * 2);
+	u32 confoff = (gicirq / 16) * 4;
+	bool enabled = false;
+	u32 val;
+
+	/* Interrupt configuration for SGIs can't be changed */
+	if (gicirq < 16)
+		return -EINVAL;
+
+	if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
+		return -EINVAL;
+
+	spin_lock(&irq_controller_lock);
+
+	val = readl(base + GIC_DIST_CONFIG + confoff);
+	if (type == IRQ_TYPE_LEVEL_HIGH)
+		val &= ~confmask;
+	else if (type == IRQ_TYPE_EDGE_RISING)
+		val |= confmask;
+
+	/*
+	 * As recommended by the spec, disable the interrupt before changing
+	 * the configuration
+	 */
+	if (readl(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
+		writel(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
+		enabled = true;
+	}
+
+	writel(val, base + GIC_DIST_CONFIG + confoff);
+
+	if (enabled)
+		writel(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
+
+	spin_unlock(&irq_controller_lock);
+
+	return 0;
+}
+
 #ifdef CONFIG_SMP
 static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
 {
@@ -161,6 +206,7 @@
 	.ack		= gic_ack_irq,
 	.mask		= gic_mask_irq,
 	.unmask		= gic_unmask_irq,
+	.set_type	= gic_set_type,
 #ifdef CONFIG_SMP
 	.set_affinity	= gic_set_cpu,
 #endif
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 6f80665..ac2fd44 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -185,13 +185,10 @@
 	},
 };
 
-void __init sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes)
+void __init sa1111_adjust_zones(unsigned long *size, unsigned long *holes)
 {
 	unsigned int sz = SZ_1M >> PAGE_SHIFT;
 
-	if (node != 0)
-		sz = 0;
-
 	size[1] = size[0] - sz;
 	size[0] = sz;
 }
diff --git a/arch/arm/configs/lusl7200_defconfig b/arch/arm/configs/lusl7200_defconfig
deleted file mode 100644
index 816fc42..0000000
--- a/arch/arm/configs/lusl7200_defconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-# CONFIG_HOTPLUG is not set
-CONFIG_MODULES=y
-CONFIG_ARCH_L7200=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x00010000
-CONFIG_ZBOOT_ROM_BSS=0xf03e0000
-CONFIG_ZBOOT_ROM=y
-CONFIG_CMDLINE="console=tty0 console=ttyLU1,115200 root=/dev/ram initrd=0xf1000000,0x005dac7b mem=32M"
-CONFIG_BINFMT_AOUT=y
-CONFIG_BLK_DEV_RAM=y
-# CONFIG_INPUT is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_EXT2_FS=y
-CONFIG_DEBUG_USER=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h
index f7bd52b..c1062c3 100644
--- a/arch/arm/include/asm/hwcap.h
+++ b/arch/arm/include/asm/hwcap.h
@@ -19,6 +19,7 @@
 #define HWCAP_NEON	4096
 #define HWCAP_VFPv3	8192
 #define HWCAP_VFPv3D16	16384
+#define HWCAP_TLS	32768
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 /*
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index 237282f..2721a58 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -7,6 +7,8 @@
 #define irq_canonicalize(i)	(i)
 #endif
 
+#define NR_IRQS_LEGACY	16
+
 /*
  * Use this value to indicate lack of interrupt
  * capability
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
index df15a0d..8ec9ef5 100644
--- a/arch/arm/include/asm/kexec.h
+++ b/arch/arm/include/asm/kexec.h
@@ -19,10 +19,26 @@
 
 #ifndef __ASSEMBLY__
 
-struct kimage;
-/* Provide a dummy definition to avoid build failures. */
+/**
+ * crash_setup_regs() - save registers for the panic kernel
+ * @newregs: registers are saved here
+ * @oldregs: registers to be saved (may be %NULL)
+ *
+ * Function copies machine registers from @oldregs to @newregs. If @oldregs is
+ * %NULL then current registers are stored there.
+ */
 static inline void crash_setup_regs(struct pt_regs *newregs,
-                                        struct pt_regs *oldregs) { }
+				    struct pt_regs *oldregs)
+{
+	if (oldregs) {
+		memcpy(newregs, oldregs, sizeof(*newregs));
+	} else {
+		__asm__ __volatile__ ("stmia %0, {r0 - r15}"
+				      : : "r" (&newregs->ARM_r0));
+		__asm__ __volatile__ ("mrs %0, cpsr"
+				      : "=r" (newregs->ARM_cpsr));
+	}
+}
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index c59842d..8a0dd18 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -20,6 +20,7 @@
 	 * by assembler code in head.S, head-common.S
 	 */
 	unsigned int		nr;		/* architecture number	*/
+	unsigned int		nr_irqs;	/* number of IRQs */
 	unsigned int		phys_io;	/* start of physical io	*/
 	unsigned int		io_pg_offst;	/* byte offset for io 
 						 * page tabe entry	*/
@@ -37,6 +38,7 @@
 	void			(*fixup)(struct machine_desc *,
 					 struct tag *, char **,
 					 struct meminfo *);
+	void			(*reserve)(void);/* reserve mem blocks	*/
 	void			(*map_io)(void);/* IO mapping function	*/
 	void			(*init_irq)(void);
 	struct sys_timer	*timer;		/* system tick timer	*/
diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h
index 8920b2d6..ce3eee9f 100644
--- a/arch/arm/include/asm/mach/irq.h
+++ b/arch/arm/include/asm/mach/irq.h
@@ -17,6 +17,7 @@
 /*
  * This is internal.  Do not use it.
  */
+extern unsigned int arch_nr_irqs;
 extern void (*init_arch_irq)(void);
 extern void init_FIQ(void);
 extern int show_fiq_list(struct seq_file *, void *);
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index 742c2aaeb..d2fedb5 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -27,6 +27,8 @@
 #define MT_MEMORY		9
 #define MT_ROM			10
 #define MT_MEMORY_NONCACHED	11
+#define MT_MEMORY_DTCM		12
+#define MT_MEMORY_ITCM		13
 
 #ifdef CONFIG_MMU
 extern void iotable_init(struct map_desc *, int);
diff --git a/arch/arm/include/asm/memblock.h b/arch/arm/include/asm/memblock.h
new file mode 100644
index 0000000..fdbc43b
--- /dev/null
+++ b/arch/arm/include/asm/memblock.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_ARM_MEMBLOCK_H
+#define _ASM_ARM_MEMBLOCK_H
+
+#ifdef CONFIG_MMU
+extern phys_addr_t lowmem_end_addr;
+#define MEMBLOCK_REAL_LIMIT	lowmem_end_addr
+#else
+#define MEMBLOCK_REAL_LIMIT	0
+#endif
+
+struct meminfo;
+struct machine_desc;
+
+extern void arm_memblock_init(struct meminfo *, struct machine_desc *);
+
+#endif
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 4312ee5..23c2e8e 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -124,6 +124,15 @@
 #endif /* !CONFIG_MMU */
 
 /*
+ * We fix the TCM memories max 32 KiB ITCM resp DTCM at these
+ * locations
+ */
+#ifdef CONFIG_HAVE_TCM
+#define ITCM_OFFSET	UL(0xfffe0000)
+#define DTCM_OFFSET	UL(0xfffe8000)
+#endif
+
+/*
  * Physical vs virtual RAM address space conversion.  These are
  * private definitions which should NOT be used outside memory.h
  * files.  Use virt_to_phys/phys_to_virt/__pa/__va instead.
@@ -158,7 +167,7 @@
 #endif
 
 #ifndef arch_adjust_zones
-#define arch_adjust_zones(node,size,holes) do { } while (0)
+#define arch_adjust_zones(size,holes) do { } while (0)
 #elif !defined(CONFIG_ZONE_DMA)
 #error "custom arch_adjust_zones() requires CONFIG_ZONE_DMA"
 #endif
@@ -234,76 +243,11 @@
  *  virt_to_page(k)	convert a _valid_ virtual address to struct page *
  *  virt_addr_valid(k)	indicates whether a virtual address is valid
  */
-#ifndef CONFIG_DISCONTIGMEM
-
 #define ARCH_PFN_OFFSET		PHYS_PFN_OFFSET
 
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 #define virt_addr_valid(kaddr)	((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
 
-#define PHYS_TO_NID(addr)	(0)
-
-#else /* CONFIG_DISCONTIGMEM */
-
-/*
- * This is more complex.  We have a set of mem_map arrays spread
- * around in memory.
- */
-#include <linux/numa.h>
-
-#define arch_pfn_to_nid(pfn)	PFN_TO_NID(pfn)
-#define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT)
-
-#define virt_to_page(kaddr)					\
-	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
-
-#define virt_addr_valid(kaddr)	(KVADDR_TO_NID(kaddr) < MAX_NUMNODES)
-
-/*
- * Common discontigmem stuff.
- *  PHYS_TO_NID is used by the ARM kernel/setup.c
- */
-#define PHYS_TO_NID(addr)	PFN_TO_NID((addr) >> PAGE_SHIFT)
-
-/*
- * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
- * and returns the mem_map of that node.
- */
-#define ADDR_TO_MAPBASE(kaddr)	NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
-
-/*
- * Given a page frame number, find the owning node of the memory
- * and returns the mem_map of that node.
- */
-#define PFN_TO_MAPBASE(pfn)	NODE_MEM_MAP(PFN_TO_NID(pfn))
-
-#ifdef NODE_MEM_SIZE_BITS
-#define NODE_MEM_SIZE_MASK	((1 << NODE_MEM_SIZE_BITS) - 1)
-
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-#define KVADDR_TO_NID(addr) \
-	(((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MEM_SIZE_BITS)
-
-/*
- * Given a page frame number, convert it to a node id.
- */
-#define PFN_TO_NID(pfn) \
-	(((pfn) - PHYS_PFN_OFFSET) >> (NODE_MEM_SIZE_BITS - PAGE_SHIFT))
-
-/*
- * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
- * and returns the index corresponding to the appropriate page in the
- * node's mem_map.
- */
-#define LOCAL_MAP_NR(addr) \
-	(((unsigned long)(addr) & NODE_MEM_SIZE_MASK) >> PAGE_SHIFT)
-
-#endif /* NODE_MEM_SIZE_BITS */
-
-#endif /* !CONFIG_DISCONTIGMEM */
-
 /*
  * Optional coherency support.  Currently used only by selected
  * Intel XSC3-based systems.
diff --git a/arch/arm/include/asm/mmzone.h b/arch/arm/include/asm/mmzone.h
deleted file mode 100644
index ae63a4f..0000000
--- a/arch/arm/include/asm/mmzone.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  arch/arm/include/asm/mmzone.h
- *
- *  1999-12-29	Nicolas Pitre		Created
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_MMZONE_H
-#define __ASM_MMZONE_H
-
-/*
- * Currently defined in arch/arm/mm/discontig.c
- */
-extern pg_data_t discontig_node_data[];
-
-/*
- * Return a pointer to the node data for node n.
- */
-#define NODE_DATA(nid)		(&discontig_node_data[nid])
-
-/*
- * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
- */
-#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
-
-#include <mach/memory.h>
-
-#endif
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 9dcb11e..c974be8 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -184,6 +184,42 @@
 #define predicate(x)		((x) & 0xf0000000)
 #define PREDICATE_ALWAYS	0xe0000000
 
+/*
+ * kprobe-based event tracer support
+ */
+#include <linux/stddef.h>
+#include <linux/types.h>
+#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0))
+
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
+extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+					       unsigned int n);
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs:	   pt_regs from which register value is gotten
+ * @offset:    offset number of the register.
+ *
+ * regs_get_register returns the value of a register whose offset from @regs.
+ * The @offset is the offset of the register in struct pt_regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+					      unsigned int offset)
+{
+	if (unlikely(offset > MAX_REG_OFFSET))
+		return 0;
+	return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/* Valid only for Kernel mode traps. */
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+	return regs->ARM_sp;
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index f392fb4..f1e5a9b 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -201,8 +201,7 @@
 struct membank {
 	unsigned long start;
 	unsigned long size;
-	unsigned short node;
-	unsigned short highmem;
+	unsigned int highmem;
 };
 
 struct meminfo {
@@ -212,9 +211,8 @@
 
 extern struct meminfo meminfo;
 
-#define for_each_nodebank(iter,mi,no)			\
-	for (iter = 0; iter < (mi)->nr_banks; iter++)	\
-		if ((mi)->bank[iter].node == no)
+#define for_each_bank(iter,mi)				\
+	for (iter = 0; iter < (mi)->nr_banks; iter++)
 
 #define bank_pfn_start(bank)	__phys_to_pfn((bank)->start)
 #define bank_pfn_end(bank)	__phys_to_pfn((bank)->start + (bank)->size)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 5f4f480..8ba1ccf 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -83,7 +83,7 @@
 
 void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
 				       struct pt_regs *),
-		     int sig, const char *name);
+		     int sig, int code, const char *name);
 
 #define xchg(ptr,x) \
 	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
new file mode 100644
index 0000000..e71d6ff
--- /dev/null
+++ b/arch/arm/include/asm/tls.h
@@ -0,0 +1,46 @@
+#ifndef __ASMARM_TLS_H
+#define __ASMARM_TLS_H
+
+#ifdef __ASSEMBLY__
+	.macro set_tls_none, tp, tmp1, tmp2
+	.endm
+
+	.macro set_tls_v6k, tp, tmp1, tmp2
+	mcr	p15, 0, \tp, c13, c0, 3		@ set TLS register
+	.endm
+
+	.macro set_tls_v6, tp, tmp1, tmp2
+	ldr	\tmp1, =elf_hwcap
+	ldr	\tmp1, [\tmp1, #0]
+	mov	\tmp2, #0xffff0fff
+	tst	\tmp1, #HWCAP_TLS		@ hardware TLS available?
+	mcrne	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
+	streq	\tp, [\tmp2, #-15]		@ set TLS value at 0xffff0ff0
+	.endm
+
+	.macro set_tls_software, tp, tmp1, tmp2
+	mov	\tmp1, #0xffff0fff
+	str	\tp, [\tmp1, #-15]		@ set TLS value at 0xffff0ff0
+	.endm
+#endif
+
+#ifdef CONFIG_TLS_REG_EMUL
+#define tls_emu		1
+#define has_tls_reg		1
+#define set_tls		set_tls_none
+#elif __LINUX_ARM_ARCH__ >= 7 ||					\
+	(__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
+#define tls_emu		0
+#define has_tls_reg		1
+#define set_tls		set_tls_v6k
+#elif __LINUX_ARM_ARCH__ == 6
+#define tls_emu		0
+#define has_tls_reg		(elf_hwcap & HWCAP_TLS)
+#define set_tls		set_tls_v6
+#else
+#define tls_emu		0
+#define has_tls_reg		0
+#define set_tls		set_tls_software
+#endif
+
+#endif	/* __ASMARM_TLS_H */
diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h
index 422f3cc..3d5fc41 100644
--- a/arch/arm/include/asm/vfpmacros.h
+++ b/arch/arm/include/asm/vfpmacros.h
@@ -3,6 +3,8 @@
  *
  * Assembler-only file containing VFP macros and register definitions.
  */
+#include <asm/hwcap.h>
+
 #include "vfp.h"
 
 @ Macros to allow building with old toolkits (with no VFP support)
@@ -22,12 +24,20 @@
 	LDC	p11, cr0, [\base],#32*4		    @ FLDMIAD \base!, {d0-d15}
 #endif
 #ifdef CONFIG_VFPv3
+#if __LINUX_ARM_ARCH__ <= 6
+	ldr	\tmp, =elf_hwcap		    @ may not have MVFR regs
+	ldr	\tmp, [\tmp, #0]
+	tst	\tmp, #HWCAP_VFPv3D16
+	ldceq	p11, cr0, [\base],#32*4		    @ FLDMIAD \base!, {d16-d31}
+	addne	\base, \base, #32*4		    @ step over unused register space
+#else
 	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
+#endif
 	.endm
 
 	@ write all the working registers out of the VFP
@@ -38,10 +48,18 @@
 	STC	p11, cr0, [\base],#32*4		    @ FSTMIAD \base!, {d0-d15}
 #endif
 #ifdef CONFIG_VFPv3
+#if __LINUX_ARM_ARCH__ <= 6
+	ldr	\tmp, =elf_hwcap		    @ may not have MVFR regs
+	ldr	\tmp, [\tmp, #0]
+	tst	\tmp, #HWCAP_VFPv3D16
+	stceq	p11, cr0, [\base],#32*4		    @ FSTMIAD \base!, {d16-d31}
+	addne	\base, \base, #32*4		    @ step over unused register space
+#else
 	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
+#endif
 	.endm
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 021f72d..980b78e 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -41,6 +41,7 @@
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_ARM_UNWIND)	+= unwind.o
 obj-$(CONFIG_HAVE_TCM)		+= tcm.o
+obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 
 obj-$(CONFIG_CRUNCH)		+= crunch.o crunch-bits.o
 AFLAGS_crunch-bits.o		:= -Wa,-mcpu=ep9312
diff --git a/arch/arm/kernel/crash_dump.c b/arch/arm/kernel/crash_dump.c
new file mode 100644
index 0000000..cd3b853
--- /dev/null
+++ b/arch/arm/kernel/crash_dump.c
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/kernel/crash_dump.c
+ *
+ * Copyright (C) 2010 Nokia Corporation.
+ * Author: Mika Westerberg
+ *
+ * This code is taken from arch/x86/kernel/crash_dump_64.c
+ *   Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *   Copyright (C) IBM Corporation, 2004. All rights reserved
+ *
+ * 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/errno.h>
+#include <linux/crash_dump.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+/* stores the physical address of elf header of crash image */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
+/**
+ * copy_oldmem_page() - copy one page from old kernel memory
+ * @pfn: page frame number to be copied
+ * @buf: buffer where the copied page is placed
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page
+ * @userbuf: if set, @buf is int he user address space
+ *
+ * This function copies one page from old kernel memory into buffer pointed by
+ * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes
+ * copied or negative error in case of failure.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+			 size_t csize, unsigned long offset,
+			 int userbuf)
+{
+	void *vaddr;
+
+	if (!csize)
+		return 0;
+
+	vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+	if (!vaddr)
+		return -ENOMEM;
+
+	if (userbuf) {
+		if (copy_to_user(buf, vaddr + offset, csize)) {
+			iounmap(vaddr);
+			return -EFAULT;
+		}
+	} else {
+		memcpy(buf, vaddr + offset, csize);
+	}
+
+	iounmap(vaddr);
+	return csize;
+}
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 9ef9a82..bb8e93a7 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -22,6 +22,7 @@
 #include <asm/thread_notify.h>
 #include <asm/unwind.h>
 #include <asm/unistd.h>
+#include <asm/tls.h>
 
 #include "entry-header.S"
 
@@ -735,12 +736,7 @@
 #ifdef CONFIG_MMU
 	ldr	r6, [r2, #TI_CPU_DOMAIN]
 #endif
-#if defined(CONFIG_HAS_TLS_REG)
-	mcr	p15, 0, r3, c13, c0, 3		@ set TLS register
-#elif !defined(CONFIG_TLS_REG_EMUL)
-	mov	r4, #0xffff0fff
-	str	r3, [r4, #-15]			@ TLS val at 0xffff0ff0
-#endif
+	set_tls	r3, r4, r5
 #if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
 	ldr	r7, [r2, #TI_TASK]
 	ldr	r8, =__stack_chk_guard
@@ -1013,17 +1009,12 @@
  */
 
 __kuser_get_tls:				@ 0xffff0fe0
-
-#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
-	ldr	r0, [pc, #(16 - 8)]		@ TLS stored at 0xffff0ff0
-#else
-	mrc	p15, 0, r0, c13, c0, 3		@ read TLS register
-#endif
+	ldr	r0, [pc, #(16 - 8)]	@ read TLS, set in kuser_get_tls_init
 	usr_ret	lr
-
-	.rep	5
-	.word	0			@ pad up to __kuser_helper_version
-	.endr
+	mrc	p15, 0, r0, c13, c0, 3	@ 0xffff0fe8 hardware TLS code
+	.rep	4
+	.word	0			@ 0xffff0ff0 software TLS value, then
+	.endr				@ pad up to __kuser_helper_version
 
 /*
  * Reference declaration:
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 3b3d2c8..c0d5c3b 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -47,12 +47,14 @@
 #define irq_finish(irq) do { } while (0)
 #endif
 
+unsigned int arch_nr_irqs;
 void (*init_arch_irq)(void) __initdata = NULL;
 unsigned long irq_err_count;
 
 int show_interrupts(struct seq_file *p, void *v)
 {
 	int i = *(loff_t *) v, cpu;
+	struct irq_desc *desc;
 	struct irqaction * action;
 	unsigned long flags;
 
@@ -67,24 +69,25 @@
 		seq_putc(p, '\n');
 	}
 
-	if (i < NR_IRQS) {
-		raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
-		action = irq_desc[i].action;
+	if (i < nr_irqs) {
+		desc = irq_to_desc(i);
+		raw_spin_lock_irqsave(&desc->lock, flags);
+		action = desc->action;
 		if (!action)
 			goto unlock;
 
 		seq_printf(p, "%3d: ", i);
 		for_each_present_cpu(cpu)
 			seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
-		seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
+		seq_printf(p, " %10s", desc->chip->name ? : "-");
 		seq_printf(p, "  %s", action->name);
 		for (action = action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 
 		seq_putc(p, '\n');
 unlock:
-		raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-	} else if (i == NR_IRQS) {
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
+	} else if (i == nr_irqs) {
 #ifdef CONFIG_FIQ
 		show_fiq_list(p, v);
 #endif
@@ -112,7 +115,7 @@
 	 * Some hardware gives randomly wrong interrupts.  Rather
 	 * than crashing, do something sensible.
 	 */
-	if (unlikely(irq >= NR_IRQS)) {
+	if (unlikely(irq >= nr_irqs)) {
 		if (printk_ratelimit())
 			printk(KERN_WARNING "Bad IRQ%u\n", irq);
 		ack_bad_irq(irq);
@@ -132,12 +135,12 @@
 	struct irq_desc *desc;
 	unsigned long flags;
 
-	if (irq >= NR_IRQS) {
+	if (irq >= nr_irqs) {
 		printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
 		return;
 	}
 
-	desc = irq_desc + irq;
+	desc = irq_to_desc(irq);
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
 	if (iflags & IRQF_VALID)
@@ -151,14 +154,25 @@
 
 void __init init_IRQ(void)
 {
+	struct irq_desc *desc;
 	int irq;
 
-	for (irq = 0; irq < NR_IRQS; irq++)
-		irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE;
+	for (irq = 0; irq < nr_irqs; irq++) {
+		desc = irq_to_desc_alloc_node(irq, 0);
+		desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
+	}
 
 	init_arch_irq();
 }
 
+#ifdef CONFIG_SPARSE_IRQ
+int __init arch_probe_nr_irqs(void)
+{
+	nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS;
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_HOTPLUG_CPU
 
 static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
@@ -178,10 +192,9 @@
 void migrate_irqs(void)
 {
 	unsigned int i, cpu = smp_processor_id();
+	struct irq_desc *desc;
 
-	for (i = 0; i < NR_IRQS; i++) {
-		struct irq_desc *desc = irq_desc + i;
-
+	for_each_irq_desc(i, desc) {
 		if (desc->node == cpu) {
 			unsigned int newcpu = cpumask_any_and(desc->affinity,
 							      cpu_online_mask);
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 598ca61..1fc74cb 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -37,12 +37,12 @@
 {
 }
 
-void machine_shutdown(void)
-{
-}
-
 void machine_crash_shutdown(struct pt_regs *regs)
 {
+	local_irq_disable();
+	crash_save_cpu(regs, smp_processor_id());
+
+	printk(KERN_INFO "Loading crashdump kernel...\n");
 }
 
 void machine_kexec(struct kimage *image)
@@ -74,7 +74,11 @@
 			   (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
 	printk(KERN_INFO "Bye!\n");
 
-	cpu_proc_fin();
+	local_irq_disable();
+	local_fiq_disable();
 	setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
+	flush_cache_all();
+	cpu_proc_fin();
+	flush_cache_all();
 	cpu_reset(reboot_code_buffer_phys);
 }
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 43557a1..401e38b 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -30,6 +30,7 @@
 #include <linux/uaccess.h>
 #include <linux/random.h>
 
+#include <asm/cacheflush.h>
 #include <asm/leds.h>
 #include <asm/processor.h>
 #include <asm/system.h>
@@ -91,10 +92,9 @@
 
 void arm_machine_restart(char mode, const char *cmd)
 {
-	/*
-	 * Clean and disable cache, and turn off interrupts
-	 */
-	cpu_proc_fin();
+	/* Disable interrupts first */
+	local_irq_disable();
+	local_fiq_disable();
 
 	/*
 	 * Tell the mm system that we are going to reboot -
@@ -103,6 +103,15 @@
 	 */
 	setup_mm_for_reboot(mode);
 
+	/* Clean and invalidate caches */
+	flush_cache_all();
+
+	/* Turn off caching */
+	cpu_proc_fin();
+
+	/* Push out any further dirty data, and ensure cache is empty */
+	flush_cache_all();
+
 	/*
 	 * Now call the architecture specific reboot code.
 	 */
@@ -196,19 +205,29 @@
 
 __setup("reboot=", reboot_setup);
 
-void machine_halt(void)
+void machine_shutdown(void)
 {
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
 }
 
+void machine_halt(void)
+{
+	machine_shutdown();
+	while (1);
+}
 
 void machine_power_off(void)
 {
+	machine_shutdown();
 	if (pm_power_off)
 		pm_power_off();
 }
 
 void machine_restart(char *cmd)
 {
+	machine_shutdown();
 	arm_pm_restart(reboot_mode, cmd);
 }
 
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 3f562a7..f99d489 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -52,6 +52,102 @@
 #define BREAKINST_THUMB	0xde01
 #endif
 
+struct pt_regs_offset {
+	const char *name;
+	int offset;
+};
+
+#define REG_OFFSET_NAME(r) \
+	{.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+static const struct pt_regs_offset regoffset_table[] = {
+	REG_OFFSET_NAME(r0),
+	REG_OFFSET_NAME(r1),
+	REG_OFFSET_NAME(r2),
+	REG_OFFSET_NAME(r3),
+	REG_OFFSET_NAME(r4),
+	REG_OFFSET_NAME(r5),
+	REG_OFFSET_NAME(r6),
+	REG_OFFSET_NAME(r7),
+	REG_OFFSET_NAME(r8),
+	REG_OFFSET_NAME(r9),
+	REG_OFFSET_NAME(r10),
+	REG_OFFSET_NAME(fp),
+	REG_OFFSET_NAME(ip),
+	REG_OFFSET_NAME(sp),
+	REG_OFFSET_NAME(lr),
+	REG_OFFSET_NAME(pc),
+	REG_OFFSET_NAME(cpsr),
+	REG_OFFSET_NAME(ORIG_r0),
+	REG_OFFSET_END,
+};
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name:	the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (!strcmp(roff->name, name))
+			return roff->offset;
+	return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset:	the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (roff->offset == offset)
+			return roff->name;
+	return NULL;
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs:      pt_regs which contains kernel stack pointer.
+ * @addr:      address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
+{
+	return ((addr & ~(THREAD_SIZE - 1))  ==
+		(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs:	pt_regs which contains kernel stack pointer.
+ * @n:		stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
+{
+	unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+	addr += n;
+	if (regs_within_kernel_stack(regs, (unsigned long)addr))
+		return *addr;
+	else
+		return 0;
+}
+
 /*
  * this routine will get a word off of the processes privileged stack.
  * the offset is how far from the base addr as stored in the THREAD.
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index 61930eb0..fd26f8d 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -10,6 +10,12 @@
 	ldr	r0,kexec_indirection_page
 	ldr	r1,kexec_start_address
 
+	/*
+	 * If there is no indirection page (we are doing crashdumps)
+	 * skip any relocation.
+	 */
+	cmp	r0, #0
+	beq	2f
 
 0:	/* top, read another word for the indirection page */
 	ldr	r3, [r0],#4
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index cbc6ddb..d5231ae 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -19,12 +19,15 @@
 #include <linux/seq_file.h>
 #include <linux/screen_info.h>
 #include <linux/init.h>
+#include <linux/kexec.h>
+#include <linux/crash_dump.h>
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
 #include <linux/smp.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/memblock.h>
 
 #include <asm/unified.h>
 #include <asm/cpu.h>
@@ -271,6 +274,21 @@
 extern struct proc_info_list *lookup_processor_type(unsigned int);
 extern struct machine_desc *lookup_machine_type(unsigned int);
 
+static void __init feat_v6_fixup(void)
+{
+	int id = read_cpuid_id();
+
+	if ((id & 0xff0f0000) != 0x41070000)
+		return;
+
+	/*
+	 * HWCAP_TLS is available only on 1136 r1p0 and later,
+	 * see also kuser_get_tls_init.
+	 */
+	if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0))
+		elf_hwcap &= ~HWCAP_TLS;
+}
+
 static void __init setup_processor(void)
 {
 	struct proc_info_list *list;
@@ -313,6 +331,8 @@
 	elf_hwcap &= ~HWCAP_THUMB;
 #endif
 
+	feat_v6_fixup();
+
 	cacheid_init();
 	cpu_proc_init();
 }
@@ -404,13 +424,12 @@
 	size -= start & ~PAGE_MASK;
 	bank->start = PAGE_ALIGN(start);
 	bank->size  = size & PAGE_MASK;
-	bank->node  = PHYS_TO_NID(start);
 
 	/*
 	 * Check whether this memory region has non-zero size or
 	 * invalid node number.
 	 */
-	if (bank->size == 0 || bank->node >= MAX_NUMNODES)
+	if (bank->size == 0)
 		return -EINVAL;
 
 	meminfo.nr_banks++;
@@ -665,6 +684,79 @@
 }
 arch_initcall(customize_machine);
 
+#ifdef CONFIG_KEXEC
+static inline unsigned long long get_total_mem(void)
+{
+	unsigned long total;
+
+	total = max_low_pfn - min_low_pfn;
+	return total << PAGE_SHIFT;
+}
+
+/**
+ * reserve_crashkernel() - reserves memory are for crash kernel
+ *
+ * This function reserves memory area given in "crashkernel=" kernel command
+ * line parameter. The memory reserved is used by a dump capture kernel when
+ * primary kernel is crashing.
+ */
+static void __init reserve_crashkernel(void)
+{
+	unsigned long long crash_size, crash_base;
+	unsigned long long total_mem;
+	int ret;
+
+	total_mem = get_total_mem();
+	ret = parse_crashkernel(boot_command_line, total_mem,
+				&crash_size, &crash_base);
+	if (ret)
+		return;
+
+	ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE);
+	if (ret < 0) {
+		printk(KERN_WARNING "crashkernel reservation failed - "
+		       "memory is in use (0x%lx)\n", (unsigned long)crash_base);
+		return;
+	}
+
+	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+	       "for crashkernel (System RAM: %ldMB)\n",
+	       (unsigned long)(crash_size >> 20),
+	       (unsigned long)(crash_base >> 20),
+	       (unsigned long)(total_mem >> 20));
+
+	crashk_res.start = crash_base;
+	crashk_res.end = crash_base + crash_size - 1;
+	insert_resource(&iomem_resource, &crashk_res);
+}
+#else
+static inline void reserve_crashkernel(void) {}
+#endif /* CONFIG_KEXEC */
+
+/*
+ * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
+ * is_kdump_kernel() to determine if we are booting after a panic. Hence
+ * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
+ */
+
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * elfcorehdr= specifies the location of elf core header stored by the crashed
+ * kernel. This option will be passed by kexec loader to the capture kernel.
+ */
+static int __init setup_elfcorehdr(char *arg)
+{
+	char *end;
+
+	if (!arg)
+		return -EINVAL;
+
+	elfcorehdr_addr = memparse(arg, &end);
+	return end > arg ? 0 : -EINVAL;
+}
+early_param("elfcorehdr", setup_elfcorehdr);
+#endif /* CONFIG_CRASH_DUMP */
+
 static void __init squash_mem_tags(struct tag *tag)
 {
 	for (; tag->hdr.size; tag = tag_next(tag))
@@ -727,12 +819,15 @@
 
 	parse_early_param();
 
+	arm_memblock_init(&meminfo, mdesc);
+
 	paging_init(mdesc);
 	request_standard_resources(&meminfo, mdesc);
 
 #ifdef CONFIG_SMP
 	smp_init_cpus();
 #endif
+	reserve_crashkernel();
 
 	cpu_init();
 	tcm_init();
@@ -740,6 +835,7 @@
 	/*
 	 * Set up various architecture-specific pointers
 	 */
+	arch_nr_irqs = mdesc->nr_irqs;
 	init_arch_irq = mdesc->init_irq;
 	system_timer = mdesc->timer;
 	init_machine = mdesc->init_machine;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index b8c3d0f..40dc74f 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -429,7 +429,11 @@
 {
 	send_ipi_message(mask, IPI_TIMER);
 }
+#else
+#define smp_timer_broadcast	NULL
+#endif
 
+#ifndef CONFIG_LOCAL_TIMERS
 static void broadcast_timer_set_mode(enum clock_event_mode mode,
 	struct clock_event_device *evt)
 {
@@ -444,7 +448,6 @@
 	evt->rating	= 400;
 	evt->mult	= 1;
 	evt->set_mode	= broadcast_timer_set_mode;
-	evt->broadcast	= smp_timer_broadcast;
 
 	clockevents_register_device(evt);
 }
@@ -456,6 +459,7 @@
 	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
 
 	evt->cpumask = cpumask_of(cpu);
+	evt->broadcast = smp_timer_broadcast;
 
 	local_timer_setup(evt);
 }
@@ -467,10 +471,13 @@
  */
 static void ipi_cpu_stop(unsigned int cpu)
 {
-	spin_lock(&stop_lock);
-	printk(KERN_CRIT "CPU%u: stopping\n", cpu);
-	dump_stack();
-	spin_unlock(&stop_lock);
+	if (system_state == SYSTEM_BOOTING ||
+	    system_state == SYSTEM_RUNNING) {
+		spin_lock(&stop_lock);
+		printk(KERN_CRIT "CPU%u: stopping\n", cpu);
+		dump_stack();
+		spin_unlock(&stop_lock);
+	}
 
 	set_cpu_online(cpu, false);
 
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 7c5f0c0..35882fb 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -132,7 +132,8 @@
 	twd_calibrate_rate();
 
 	clk->name = "local_timer";
-	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
+			CLOCK_EVT_FEAT_C3STOP;
 	clk->rating = 350;
 	clk->set_mode = twd_set_mode;
 	clk->set_next_event = twd_set_next_event;
diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c
index e503038..26685c2 100644
--- a/arch/arm/kernel/tcm.c
+++ b/arch/arm/kernel/tcm.c
@@ -13,38 +13,35 @@
 #include <linux/ioport.h>
 #include <linux/genalloc.h>
 #include <linux/string.h> /* memcpy */
-#include <asm/page.h> /* PAGE_SHIFT */
 #include <asm/cputype.h>
 #include <asm/mach/map.h>
 #include <mach/memory.h>
 #include "tcm.h"
 
-/* Scream and warn about misuse */
-#if !defined(ITCM_OFFSET) || !defined(ITCM_END) || \
-    !defined(DTCM_OFFSET) || !defined(DTCM_END)
-#error "TCM support selected but offsets not defined!"
-#endif
-
 static struct gen_pool *tcm_pool;
 
 /* TCM section definitions from the linker */
 extern char __itcm_start, __sitcm_text, __eitcm_text;
 extern char __dtcm_start, __sdtcm_data, __edtcm_data;
 
+/* These will be increased as we run */
+u32 dtcm_end = DTCM_OFFSET;
+u32 itcm_end = ITCM_OFFSET;
+
 /*
  * TCM memory resources
  */
 static struct resource dtcm_res = {
 	.name = "DTCM RAM",
 	.start = DTCM_OFFSET,
-	.end = DTCM_END,
+	.end = DTCM_OFFSET,
 	.flags = IORESOURCE_MEM
 };
 
 static struct resource itcm_res = {
 	.name = "ITCM RAM",
 	.start = ITCM_OFFSET,
-	.end = ITCM_END,
+	.end = ITCM_OFFSET,
 	.flags = IORESOURCE_MEM
 };
 
@@ -52,8 +49,8 @@
 	{
 		.virtual	= DTCM_OFFSET,
 		.pfn		= __phys_to_pfn(DTCM_OFFSET),
-		.length		= (DTCM_END - DTCM_OFFSET + 1),
-		.type		= MT_UNCACHED
+		.length		= 0,
+		.type		= MT_MEMORY_DTCM
 	}
 };
 
@@ -61,8 +58,8 @@
 	{
 		.virtual	= ITCM_OFFSET,
 		.pfn		= __phys_to_pfn(ITCM_OFFSET),
-		.length		= (ITCM_END - ITCM_OFFSET + 1),
-		.type		= MT_UNCACHED
+		.length		= 0,
+		.type		= MT_MEMORY_ITCM
 	}
 };
 
@@ -93,14 +90,24 @@
 }
 EXPORT_SYMBOL(tcm_free);
 
-
-static void __init setup_tcm_bank(u8 type, u32 offset, u32 expected_size)
+static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks,
+				  u32 *offset)
 {
 	const int tcm_sizes[16] = { 0, -1, -1, 4, 8, 16, 32, 64, 128,
 				    256, 512, 1024, -1, -1, -1, -1 };
 	u32 tcm_region;
 	int tcm_size;
 
+	/*
+	 * If there are more than one TCM bank of this type,
+	 * select the TCM bank to operate on in the TCM selection
+	 * register.
+	 */
+	if (banks > 1)
+		asm("mcr	p15, 0, %0, c9, c2, 0"
+		    : /* No output operands */
+		    : "r" (bank));
+
 	/* Read the special TCM region register c9, 0 */
 	if (!type)
 		asm("mrc	p15, 0, %0, c9, c1, 0"
@@ -111,26 +118,24 @@
 
 	tcm_size = tcm_sizes[(tcm_region >> 2) & 0x0f];
 	if (tcm_size < 0) {
-		pr_err("CPU: %sTCM of unknown size!\n",
-			type ? "I" : "D");
+		pr_err("CPU: %sTCM%d of unknown size\n",
+		       type ? "I" : "D", bank);
+		return -EINVAL;
+	} else if (tcm_size > 32) {
+		pr_err("CPU: %sTCM%d larger than 32k found\n",
+		       type ? "I" : "D", bank);
+		return -EINVAL;
 	} else {
-		pr_info("CPU: found %sTCM %dk @ %08x, %senabled\n",
+		pr_info("CPU: found %sTCM%d %dk @ %08x, %senabled\n",
 			type ? "I" : "D",
+			bank,
 			tcm_size,
 			(tcm_region & 0xfffff000U),
 			(tcm_region & 1) ? "" : "not ");
 	}
 
-	if (tcm_size != expected_size) {
-		pr_crit("CPU: %sTCM was detected %dk but expected %dk!\n",
-		       type ? "I" : "D",
-		       tcm_size,
-		       expected_size);
-		/* Adjust to the expected size? what can we do... */
-	}
-
 	/* Force move the TCM bank to where we want it, enable */
-	tcm_region = offset | (tcm_region & 0x00000ffeU) | 1;
+	tcm_region = *offset | (tcm_region & 0x00000ffeU) | 1;
 
 	if (!type)
 		asm("mcr	p15, 0, %0, c9, c1, 0"
@@ -141,10 +146,15 @@
 		    : /* No output operands */
 		    : "r" (tcm_region));
 
-	pr_debug("CPU: moved %sTCM %dk to %08x, enabled\n",
-		 type ? "I" : "D",
-		 tcm_size,
-		 (tcm_region & 0xfffff000U));
+	/* Increase offset */
+	*offset += (tcm_size << 10);
+
+	pr_info("CPU: moved %sTCM%d %dk to %08x, enabled\n",
+		type ? "I" : "D",
+		bank,
+		tcm_size,
+		(tcm_region & 0xfffff000U));
+	return 0;
 }
 
 /*
@@ -153,34 +163,52 @@
 void __init tcm_init(void)
 {
 	u32 tcm_status = read_cpuid_tcmstatus();
+	u8 dtcm_banks = (tcm_status >> 16) & 0x03;
+	u8 itcm_banks = (tcm_status & 0x03);
 	char *start;
 	char *end;
 	char *ram;
+	int ret;
+	int i;
 
 	/* Setup DTCM if present */
-	if (tcm_status & (1 << 16)) {
-		setup_tcm_bank(0, DTCM_OFFSET,
-			       (DTCM_END - DTCM_OFFSET + 1) >> 10);
+	if (dtcm_banks > 0) {
+		for (i = 0; i < dtcm_banks; i++) {
+			ret = setup_tcm_bank(0, i, dtcm_banks, &dtcm_end);
+			if (ret)
+				return;
+		}
+		dtcm_res.end = dtcm_end - 1;
 		request_resource(&iomem_resource, &dtcm_res);
+		dtcm_iomap[0].length = dtcm_end - DTCM_OFFSET;
 		iotable_init(dtcm_iomap, 1);
 		/* Copy data from RAM to DTCM */
 		start = &__sdtcm_data;
 		end   = &__edtcm_data;
 		ram   = &__dtcm_start;
+		/* This means you compiled more code than fits into DTCM */
+		BUG_ON((end - start) > (dtcm_end - DTCM_OFFSET));
 		memcpy(start, ram, (end-start));
 		pr_debug("CPU DTCM: copied data from %p - %p\n", start, end);
 	}
 
 	/* Setup ITCM if present */
-	if (tcm_status & 1) {
-		setup_tcm_bank(1, ITCM_OFFSET,
-			       (ITCM_END - ITCM_OFFSET + 1) >> 10);
+	if (itcm_banks > 0) {
+		for (i = 0; i < itcm_banks; i++) {
+			ret = setup_tcm_bank(1, i, itcm_banks, &itcm_end);
+			if (ret)
+				return;
+		}
+		itcm_res.end = itcm_end - 1;
 		request_resource(&iomem_resource, &itcm_res);
+		itcm_iomap[0].length = itcm_end - ITCM_OFFSET;
 		iotable_init(itcm_iomap, 1);
 		/* Copy code from RAM to ITCM */
 		start = &__sitcm_text;
 		end   = &__eitcm_text;
 		ram   = &__itcm_start;
+		/* This means you compiled more code than fits into ITCM */
+		BUG_ON((end - start) > (itcm_end - ITCM_OFFSET));
 		memcpy(start, ram, (end-start));
 		pr_debug("CPU ITCM: copied code from %p - %p\n", start, end);
 	}
@@ -208,10 +236,10 @@
 	pr_debug("Setting up TCM memory pool\n");
 
 	/* Add the rest of DTCM to the TCM pool */
-	if (tcm_status & (1 << 16)) {
-		if (dtcm_pool_start < DTCM_END) {
+	if (tcm_status & (0x03 << 16)) {
+		if (dtcm_pool_start < dtcm_end) {
 			ret = gen_pool_add(tcm_pool, dtcm_pool_start,
-					   DTCM_END - dtcm_pool_start + 1, -1);
+					   dtcm_end - dtcm_pool_start, -1);
 			if (ret) {
 				pr_err("CPU DTCM: could not add DTCM " \
 				       "remainder to pool!\n");
@@ -219,16 +247,16 @@
 			}
 			pr_debug("CPU DTCM: Added %08x bytes @ %08x to " \
 				 "the TCM memory pool\n",
-				 DTCM_END - dtcm_pool_start + 1,
+				 dtcm_end - dtcm_pool_start,
 				 dtcm_pool_start);
 		}
 	}
 
 	/* Add the rest of ITCM to the TCM pool */
-	if (tcm_status & 1) {
-		if (itcm_pool_start < ITCM_END) {
+	if (tcm_status & 0x03) {
+		if (itcm_pool_start < itcm_end) {
 			ret = gen_pool_add(tcm_pool, itcm_pool_start,
-					   ITCM_END - itcm_pool_start + 1, -1);
+					   itcm_end - itcm_pool_start, -1);
 			if (ret) {
 				pr_err("CPU ITCM: could not add ITCM " \
 				       "remainder to pool!\n");
@@ -236,7 +264,7 @@
 			}
 			pr_debug("CPU ITCM: Added %08x bytes @ %08x to " \
 				 "the TCM memory pool\n",
-				 ITCM_END - itcm_pool_start + 1,
+				 itcm_end - itcm_pool_start,
 				 itcm_pool_start);
 		}
 	}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 1621e53..cda78d5 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -30,6 +30,7 @@
 #include <asm/unistd.h>
 #include <asm/traps.h>
 #include <asm/unwind.h>
+#include <asm/tls.h>
 
 #include "ptrace.h"
 #include "signal.h"
@@ -518,17 +519,20 @@
 
 	case NR(set_tls):
 		thread->tp_value = regs->ARM_r0;
-#if defined(CONFIG_HAS_TLS_REG)
-		asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
-#elif !defined(CONFIG_TLS_REG_EMUL)
-		/*
-		 * User space must never try to access this directly.
-		 * Expect your app to break eventually if you do so.
-		 * The user helper at 0xffff0fe0 must be used instead.
-		 * (see entry-armv.S for details)
-		 */
-		*((unsigned int *)0xffff0ff0) = regs->ARM_r0;
-#endif
+		if (tls_emu)
+			return 0;
+		if (has_tls_reg) {
+			asm ("mcr p15, 0, %0, c13, c0, 3"
+				: : "r" (regs->ARM_r0));
+		} else {
+			/*
+			 * User space must never try to access this directly.
+			 * Expect your app to break eventually if you do so.
+			 * The user helper at 0xffff0fe0 must be used instead.
+			 * (see entry-armv.S for details)
+			 */
+			*((unsigned int *)0xffff0ff0) = regs->ARM_r0;
+		}
 		return 0;
 
 #ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
@@ -743,6 +747,16 @@
 	return;
 }
 
+static void __init kuser_get_tls_init(unsigned long vectors)
+{
+	/*
+	 * vectors + 0xfe0 = __kuser_get_tls
+	 * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
+	 */
+	if (tls_emu || has_tls_reg)
+		memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4);
+}
+
 void __init early_trap_init(void)
 {
 	unsigned long vectors = CONFIG_VECTORS_BASE;
@@ -761,6 +775,11 @@
 	memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
 
 	/*
+	 * Do processor specific fixups for the kuser helpers
+	 */
+	kuser_get_tls_init(vectors);
+
+	/*
 	 * Copy signal return handlers into the vector page, and
 	 * set sigreturn to be a pointer to these.
 	 */
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 030ba72..59ff42d 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -41,7 +41,6 @@
 endif
 
 lib-$(CONFIG_ARCH_RPC)		+= ecard.o io-acorn.o floppydma.o
-lib-$(CONFIG_ARCH_L7200)	+= io-acorn.o
 lib-$(CONFIG_ARCH_SHARK)	+= io-shark.o
 
 $(obj)/csumpartialcopy.o:	$(obj)/csumpartialcopygeneric.S
diff --git a/arch/arm/mach-aaec2000/include/mach/memory.h b/arch/arm/mach-aaec2000/include/mach/memory.h
index c008225..4f93c56 100644
--- a/arch/arm/mach-aaec2000/include/mach/memory.h
+++ b/arch/arm/mach-aaec2000/include/mach/memory.h
@@ -14,14 +14,4 @@
 
 #define PHYS_OFFSET	UL(0xf0000000)
 
-/*
- * The nodes are the followings:
- *
- *   node 0: 0xf000.0000 - 0xf3ff.ffff
- *   node 1: 0xf400.0000 - 0xf7ff.ffff
- *   node 2: 0xf800.0000 - 0xfbff.ffff
- *   node 3: 0xfc00.0000 - 0xffff.ffff
- */
-#define NODE_MEM_SIZE_BITS	26
-
 #endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 841eaf8..939bccd 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -366,6 +366,17 @@
 
 endif
 
+if (ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
+comment "AT91SAM9260/AT91SAM9G20 boards"
+
+config MACH_SNAPPER_9260
+        bool "Bluewater Systems Snapper 9260/9G20 module"
+        help
+          Select this if you are using the Bluewater Systems Snapper 9260 or
+          Snapper 9G20 modules.
+          <http://www.bluewatersys.com/>
+endif
+
 # ----------------------------------------------------------
 
 if ARCH_AT91SAM9G45
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index c1f821e..ca2ac00 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -66,6 +66,9 @@
 obj-$(CONFIG_MACH_STAMP9G20)	+= board-stamp9g20.o
 obj-$(CONFIG_MACH_PORTUXG20)	+= board-stamp9g20.o
 
+# AT91SAM9260/AT91SAM9G20 board-specific support
+obj-$(CONFIG_MACH_SNAPPER_9260)	+= board-snapper9260.o
+
 # AT91SAM9G45 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
 
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 85166b7..753c0d3 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -20,6 +20,7 @@
 #include <mach/at91_pmc.h>
 #include <mach/at91_rstc.h>
 #include <mach/at91_shdwc.h>
+#include <mach/cpu.h>
 
 #include "generic.h"
 #include "clock.h"
@@ -176,6 +177,13 @@
 	.type		= CLK_TYPE_PERIPHERAL,
 };
 
+/* Video decoder clock - Only for sam9m10/sam9m11 */
+static struct clk vdec_clk = {
+	.name		= "vdec_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_VDEC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+
 /* One additional fake clock for ohci */
 static struct clk ohci_clk = {
 	.name		= "ohci_clk",
@@ -239,6 +247,9 @@
 	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 		clk_register(periph_clocks[i]);
 
+	if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11())
+		clk_register(&vdec_clk);
+
 	clk_register(&pck0);
 	clk_register(&pck1);
 }
diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
index a4102d7..c49f5c0 100644
--- a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
@@ -26,6 +26,9 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/at73c213.h>
 #include <linux/clk.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/consumer.h>
 
 #include <mach/hardware.h>
 #include <asm/setup.h>
@@ -235,6 +238,46 @@
 	}
 };
 
+#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
+static struct regulator_consumer_supply ek_audio_consumer_supplies[] = {
+	REGULATOR_SUPPLY("AVDD", "0-001b"),
+	REGULATOR_SUPPLY("HPVDD", "0-001b"),
+	REGULATOR_SUPPLY("DBVDD", "0-001b"),
+	REGULATOR_SUPPLY("DCVDD", "0-001b"),
+};
+
+static struct regulator_init_data ek_avdd_reg_init_data = {
+	.constraints	= {
+		.name	= "3V3",
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.consumer_supplies = ek_audio_consumer_supplies,
+	.num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies),
+};
+
+static struct fixed_voltage_config ek_vdd_pdata = {
+	.supply_name	= "board-3V3",
+	.microvolts	= 3300000,
+	.gpio		= -EINVAL,
+	.enabled_at_boot = 0,
+	.init_data	= &ek_avdd_reg_init_data,
+};
+static struct platform_device ek_voltage_regulator = {
+	.name		= "reg-fixed-voltage",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &ek_vdd_pdata,
+	},
+};
+static void __init ek_add_regulators(void)
+{
+	platform_device_register(&ek_voltage_regulator);
+}
+#else
+static void __init ek_add_regulators(void) {}
+#endif
+
 static struct i2c_board_info __initdata ek_i2c_devices[] = {
 	{
 		I2C_BOARD_INFO("24c512", 0x50),
@@ -256,6 +299,8 @@
 	ek_add_device_nand();
 	/* Ethernet */
 	at91_add_device_eth(&ek_macb_data);
+	/* Regulators */
+	ek_add_regulators();
 	/* MMC */
 #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
 	at91_add_device_mci(0, &ek_mmc_data);
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index c11fd47..6ea9808 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -27,6 +27,9 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/clk.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/consumer.h>
 
 #include <mach/hardware.h>
 #include <asm/setup.h>
@@ -269,6 +272,46 @@
 static void __init ek_add_device_buttons(void) {}
 #endif
 
+#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
+static struct regulator_consumer_supply ek_audio_consumer_supplies[] = {
+	REGULATOR_SUPPLY("AVDD", "0-001b"),
+	REGULATOR_SUPPLY("HPVDD", "0-001b"),
+	REGULATOR_SUPPLY("DBVDD", "0-001b"),
+	REGULATOR_SUPPLY("DCVDD", "0-001b"),
+};
+
+static struct regulator_init_data ek_avdd_reg_init_data = {
+	.constraints	= {
+		.name	= "3V3",
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.consumer_supplies = ek_audio_consumer_supplies,
+	.num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies),
+};
+
+static struct fixed_voltage_config ek_vdd_pdata = {
+	.supply_name	= "board-3V3",
+	.microvolts	= 3300000,
+	.gpio		= -EINVAL,
+	.enabled_at_boot = 0,
+	.init_data	= &ek_avdd_reg_init_data,
+};
+static struct platform_device ek_voltage_regulator = {
+	.name		= "reg-fixed-voltage",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &ek_vdd_pdata,
+	},
+};
+static void __init ek_add_regulators(void)
+{
+	platform_device_register(&ek_voltage_regulator);
+}
+#else
+static void __init ek_add_regulators(void) {}
+#endif
+
 
 static struct i2c_board_info __initdata ek_i2c_devices[] = {
         {
@@ -294,6 +337,8 @@
 	ek_add_device_nand();
 	/* Ethernet */
 	at91_add_device_eth(&ek_macb_data);
+	/* Regulators */
+	ek_add_regulators();
 	/* MMC */
 	at91_add_device_mmc(0, &ek_mmc_data);
 	/* I2C */
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c
new file mode 100644
index 0000000..2c08ae4
--- /dev/null
+++ b/arch/arm/mach-at91/board-snapper9260.c
@@ -0,0 +1,189 @@
+/*
+ * linux/arch/arm/mach-at91/board-snapper9260.c
+ *
+ *  Copyright (C) 2010 Bluewater System Ltd
+ *
+ * Author: Andre Renaud <andre@bluewatersys.com>
+ * Author: Ryan Mallon  <ryan@bluewatersys.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c/pca953x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+#define SNAPPER9260_IO_EXP_GPIO(x)	(NR_BUILTIN_GPIO + (x))
+
+static void __init snapper9260_map_io(void)
+{
+	at91sam9260_initialize(18432000);
+
+	/* Debug on ttyS0 */
+	at91_register_uart(0, 0, 0);
+	at91_set_serial_console(0);
+
+	at91_register_uart(AT91SAM9260_ID_US0, 1,
+			   ATMEL_UART_CTS | ATMEL_UART_RTS);
+	at91_register_uart(AT91SAM9260_ID_US1, 2,
+			   ATMEL_UART_CTS | ATMEL_UART_RTS);
+	at91_register_uart(AT91SAM9260_ID_US2, 3, 0);
+}
+
+static void __init snapper9260_init_irq(void)
+{
+	at91sam9260_init_interrupts(NULL);
+}
+
+static struct at91_usbh_data __initdata snapper9260_usbh_data = {
+	.ports		= 2,
+};
+
+static struct at91_udc_data __initdata snapper9260_udc_data = {
+	.vbus_pin		= SNAPPER9260_IO_EXP_GPIO(5),
+	.vbus_active_low	= 1,
+	.vbus_polled		= 1,
+};
+
+static struct at91_eth_data snapper9260_macb_data = {
+	.is_rmii	= 1,
+};
+
+static struct mtd_partition __initdata snapper9260_nand_partitions[] = {
+	{
+		.name	= "Preboot",
+		.offset	= 0,
+		.size	= SZ_128K,
+	},
+	{
+		.name	= "Bootloader",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= SZ_256K,
+	},
+	{
+		.name	= "Environment",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= SZ_128K,
+	},
+	{
+		.name	= "Kernel",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= SZ_4M,
+	},
+	{
+		.name	= "Filesystem",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct mtd_partition * __init
+snapper9260_nand_partition_info(int size, int *num_partitions)
+{
+	*num_partitions = ARRAY_SIZE(snapper9260_nand_partitions);
+	return snapper9260_nand_partitions;
+}
+
+static struct atmel_nand_data __initdata snapper9260_nand_data = {
+	.ale		= 21,
+	.cle		= 22,
+	.rdy_pin	= AT91_PIN_PC13,
+	.partition_info	= snapper9260_nand_partition_info,
+	.bus_width_16	= 0,
+};
+
+static struct sam9_smc_config __initdata snapper9260_nand_smc_config = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 0,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 0,
+
+	.ncs_read_pulse		= 5,
+	.nrd_pulse		= 2,
+	.ncs_write_pulse	= 5,
+	.nwe_pulse		= 2,
+
+	.read_cycle		= 7,
+	.write_cycle		= 7,
+
+	.mode			= (AT91_SMC_READMODE | AT91_SMC_WRITEMODE |
+				   AT91_SMC_EXNWMODE_DISABLE),
+	.tdf_cycles		= 1,
+};
+
+static struct pca953x_platform_data snapper9260_io_expander_data = {
+	.gpio_base		= SNAPPER9260_IO_EXP_GPIO(0),
+};
+
+static struct i2c_board_info __initdata snapper9260_i2c_devices[] = {
+	{
+		/* IO expander */
+		I2C_BOARD_INFO("max7312", 0x28),
+		.platform_data = &snapper9260_io_expander_data,
+	},
+	{
+		/* Audio codec */
+		I2C_BOARD_INFO("tlv320aic23", 0x1a),
+	},
+	{
+		/* RTC */
+		I2C_BOARD_INFO("isl1208", 0x6f),
+	},
+};
+
+static void __init snapper9260_add_device_nand(void)
+{
+	at91_set_A_periph(AT91_PIN_PC14, 0);
+	sam9_smc_configure(3, &snapper9260_nand_smc_config);
+	at91_add_device_nand(&snapper9260_nand_data);
+}
+
+static void __init snapper9260_board_init(void)
+{
+	at91_add_device_i2c(snapper9260_i2c_devices,
+			    ARRAY_SIZE(snapper9260_i2c_devices));
+	at91_add_device_serial();
+	at91_add_device_usbh(&snapper9260_usbh_data);
+	at91_add_device_udc(&snapper9260_udc_data);
+	at91_add_device_eth(&snapper9260_macb_data);
+	at91_add_device_ssc(AT91SAM9260_ID_SSC, (ATMEL_SSC_TF | ATMEL_SSC_TK |
+						 ATMEL_SSC_TD | ATMEL_SSC_RD));
+	snapper9260_add_device_nand();
+}
+
+MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module")
+	.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		= snapper9260_map_io,
+	.init_irq	= snapper9260_init_irq,
+	.init_machine	= snapper9260_board_init,
+MACHINE_END
+
+
diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h
index d8c1ede..9c6af97 100644
--- a/arch/arm/mach-at91/include/mach/at91cap9.h
+++ b/arch/arm/mach-at91/include/mach/at91cap9.h
@@ -84,7 +84,7 @@
  */
 #define AT91_ECC	(0xffffe200 - AT91_BASE_SYS)
 #define AT91_BCRAMC	(0xffffe400 - AT91_BASE_SYS)
-#define AT91_DDRSDRC	(0xffffe600 - AT91_BASE_SYS)
+#define AT91_DDRSDRC0	(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)
diff --git a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
index 1499b1c..976f4a6 100644
--- a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
+++ b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
@@ -15,7 +15,7 @@
 #ifndef AT91CAP9_DDRSDR_H
 #define AT91CAP9_DDRSDR_H
 
-#define AT91_DDRSDRC_MR		(AT91_DDRSDRC + 0x00)	/* Mode Register */
+#define AT91_DDRSDRC_MR		0x00	/* Mode Register */
 #define		AT91_DDRSDRC_MODE	(0xf << 0)		/* Command Mode */
 #define			AT91_DDRSDRC_MODE_NORMAL		0
 #define			AT91_DDRSDRC_MODE_NOP		1
@@ -25,10 +25,10 @@
 #define			AT91_DDRSDRC_MODE_EXT_LMR	5
 #define			AT91_DDRSDRC_MODE_DEEP		6
 
-#define AT91_DDRSDRC_RTR	(AT91_DDRSDRC + 0x04)	/* Refresh Timer Register */
+#define AT91_DDRSDRC_RTR	0x04	/* Refresh Timer Register */
 #define		AT91_DDRSDRC_COUNT	(0xfff << 0)		/* Refresh Timer Counter */
 
-#define AT91_DDRSDRC_CR		(AT91_DDRSDRC + 0x08)	/* Configuration Register */
+#define AT91_DDRSDRC_CR		0x08	/* Configuration Register */
 #define		AT91_DDRSDRC_NC		(3 << 0)		/* Number of Column Bits */
 #define			AT91_DDRSDRC_NC_SDR8	(0 << 0)
 #define			AT91_DDRSDRC_NC_SDR9	(1 << 0)
@@ -49,7 +49,7 @@
 #define		AT91_DDRSDRC_DLL	(1 << 7)		/* Reset DLL */
 #define		AT91_DDRSDRC_DICDS	(1 << 8)		/* Output impedance control */
 
-#define AT91_DDRSDRC_T0PR	(AT91_DDRSDRC + 0x0C)	/* Timing 0 Register */
+#define AT91_DDRSDRC_T0PR	0x0C	/* Timing 0 Register */
 #define		AT91_DDRSDRC_TRAS	(0xf <<  0)		/* Active to Precharge delay */
 #define		AT91_DDRSDRC_TRCD	(0xf <<  4)		/* Row to Column delay */
 #define		AT91_DDRSDRC_TWR	(0xf <<  8)		/* Write recovery delay */
@@ -59,13 +59,13 @@
 #define		AT91_DDRSDRC_TWTR	(1   << 24)		/* Internal Write to Read delay */
 #define		AT91_DDRSDRC_TMRD	(0xf << 28)		/* Load mode to active/refresh delay */
 
-#define AT91_DDRSDRC_T1PR	(AT91_DDRSDRC + 0x10)	/* Timing 1 Register */
+#define AT91_DDRSDRC_T1PR	0x10	/* Timing 1 Register */
 #define		AT91_DDRSDRC_TRFC	(0x1f << 0)		/* Row Cycle Delay */
 #define		AT91_DDRSDRC_TXSNR	(0xff << 8)		/* Exit self-refresh to non-read */
 #define		AT91_DDRSDRC_TXSRD	(0xff << 16)		/* Exit self-refresh to read */
 #define		AT91_DDRSDRC_TXP	(0xf  << 24)		/* Exit power-down delay */
 
-#define AT91_DDRSDRC_LPR	(AT91_DDRSDRC + 0x18)	/* Low Power Register */
+#define AT91_DDRSDRC_LPR	0x18	/* Low Power Register */
 #define		AT91_DDRSDRC_LPCB		(3 << 0)	/* Low-power Configurations */
 #define			AT91_DDRSDRC_LPCB_DISABLE		0
 #define			AT91_DDRSDRC_LPCB_SELF_REFRESH		1
@@ -80,14 +80,14 @@
 #define			AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES	(1 << 12)
 #define			AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES	(2 << 12)
 
-#define AT91_DDRSDRC_MDR	(AT91_DDRSDRC + 0x1C)	/* Memory Device Register */
+#define AT91_DDRSDRC_MDR	0x1C	/* Memory Device Register */
 #define		AT91_DDRSDRC_MD		(3 << 0)		/* Memory Device Type */
 #define			AT91_DDRSDRC_MD_SDR		0
 #define			AT91_DDRSDRC_MD_LOW_POWER_SDR	1
 #define			AT91_DDRSDRC_MD_DDR		2
 #define			AT91_DDRSDRC_MD_LOW_POWER_DDR	3
 
-#define AT91_DDRSDRC_DLLR	(AT91_DDRSDRC + 0x20)	/* DLL Information Register */
+#define AT91_DDRSDRC_DLLR	0x20	/* DLL Information Register */
 #define		AT91_DDRSDRC_MDINC	(1 << 0)		/* Master Delay increment */
 #define		AT91_DDRSDRC_MDDEC	(1 << 1)		/* Master Delay decrement */
 #define		AT91_DDRSDRC_MDOVF	(1 << 2)		/* Master Delay Overflow */
@@ -98,5 +98,11 @@
 #define		AT91_DDRSDRC_SDVAL	(0xff << 16)		/* Slave Delay value */
 #define		AT91_DDRSDRC_SDCVAL	(0xff << 24)		/* Slave Delay Correction value */
 
+/* Register access macros */
+#define at91_ramc_read(num, reg) \
+	at91_sys_read(AT91_DDRSDRC##num + reg)
+#define at91_ramc_write(num, reg, value) \
+	at91_sys_write(AT91_DDRSDRC##num + reg, value)
+
 
 #endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h
index 43c396b..4e79036 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9260.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9260.h
@@ -84,7 +84,7 @@
  * System Peripherals (offset from AT91_BASE_SYS)
  */
 #define AT91_ECC	(0xffffe800 - AT91_BASE_SYS)
-#define AT91_SDRAMC	(0xffffea00 - AT91_BASE_SYS)
+#define AT91_SDRAMC0	(0xffffea00 - AT91_BASE_SYS)
 #define AT91_SMC	(0xffffec00 - AT91_BASE_SYS)
 #define AT91_MATRIX	(0xffffee00 - AT91_BASE_SYS)
 #define AT91_CCFG	(0xffffef10 - AT91_BASE_SYS)
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h
index 87de8be..2b56185 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9261.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9261.h
@@ -68,7 +68,7 @@
 /*
  * System Peripherals (offset from AT91_BASE_SYS)
  */
-#define AT91_SDRAMC	(0xffffea00 - AT91_BASE_SYS)
+#define AT91_SDRAMC0	(0xffffea00 - AT91_BASE_SYS)
 #define AT91_SMC	(0xffffec00 - AT91_BASE_SYS)
 #define AT91_MATRIX	(0xffffee00 - AT91_BASE_SYS)
 #define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
new file mode 100644
index 0000000..d27b15b
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
@@ -0,0 +1,130 @@
+/*
+ * Header file for the Atmel DDR/SDR SDRAM Controller
+ *
+ * Copyright (C) 2010 Atmel Corporation
+ *	Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef AT91SAM9_DDRSDR_H
+#define AT91SAM9_DDRSDR_H
+
+#define AT91_DDRSDRC_MR		0x00	/* Mode Register */
+#define		AT91_DDRSDRC_MODE	(0x7 << 0)		/* Command Mode */
+#define			AT91_DDRSDRC_MODE_NORMAL	0
+#define			AT91_DDRSDRC_MODE_NOP		1
+#define			AT91_DDRSDRC_MODE_PRECHARGE	2
+#define			AT91_DDRSDRC_MODE_LMR		3
+#define			AT91_DDRSDRC_MODE_REFRESH	4
+#define			AT91_DDRSDRC_MODE_EXT_LMR	5
+#define			AT91_DDRSDRC_MODE_DEEP		6
+
+#define AT91_DDRSDRC_RTR	0x04	/* Refresh Timer Register */
+#define		AT91_DDRSDRC_COUNT	(0xfff << 0)		/* Refresh Timer Counter */
+
+#define AT91_DDRSDRC_CR		0x08	/* Configuration Register */
+#define		AT91_DDRSDRC_NC		(3 << 0)		/* Number of Column Bits */
+#define			AT91_DDRSDRC_NC_SDR8	(0 << 0)
+#define			AT91_DDRSDRC_NC_SDR9	(1 << 0)
+#define			AT91_DDRSDRC_NC_SDR10	(2 << 0)
+#define			AT91_DDRSDRC_NC_SDR11	(3 << 0)
+#define			AT91_DDRSDRC_NC_DDR9	(0 << 0)
+#define			AT91_DDRSDRC_NC_DDR10	(1 << 0)
+#define			AT91_DDRSDRC_NC_DDR11	(2 << 0)
+#define			AT91_DDRSDRC_NC_DDR12	(3 << 0)
+#define		AT91_DDRSDRC_NR		(3 << 2)		/* Number of Row Bits */
+#define			AT91_DDRSDRC_NR_11	(0 << 2)
+#define			AT91_DDRSDRC_NR_12	(1 << 2)
+#define			AT91_DDRSDRC_NR_13	(2 << 2)
+#define			AT91_DDRSDRC_NR_14	(3 << 2)
+#define		AT91_DDRSDRC_CAS	(7 << 4)		/* CAS Latency */
+#define			AT91_DDRSDRC_CAS_2	(2 << 4)
+#define			AT91_DDRSDRC_CAS_3	(3 << 4)
+#define			AT91_DDRSDRC_CAS_25	(6 << 4)
+#define		AT91_DDRSDRC_RST_DLL	(1 << 7)		/* Reset DLL */
+#define		AT91_DDRSDRC_DICDS	(1 << 8)		/* Output impedance control */
+#define		AT91_DDRSDRC_DIS_DLL	(1 << 9)		/* Disable DLL */
+#define		AT91_DDRSDRC_OCD	(1 << 12)		/* Off-Chip Driver */
+#define		AT91_DDRSDRC_DQMS	(1 << 16)		/* Mask Data is Shared */
+#define		AT91_DDRSDRC_ACTBST	(1 << 18)		/* Active Bank X to Burst Stop Read Access Bank Y */
+
+#define AT91_DDRSDRC_T0PR	0x0C	/* Timing 0 Register */
+#define		AT91_DDRSDRC_TRAS	(0xf <<  0)		/* Active to Precharge delay */
+#define		AT91_DDRSDRC_TRCD	(0xf <<  4)		/* Row to Column delay */
+#define		AT91_DDRSDRC_TWR	(0xf <<  8)		/* Write recovery delay */
+#define		AT91_DDRSDRC_TRC	(0xf << 12)		/* Row cycle delay */
+#define		AT91_DDRSDRC_TRP	(0xf << 16)		/* Row precharge delay */
+#define		AT91_DDRSDRC_TRRD	(0xf << 20)		/* Active BankA to BankB */
+#define		AT91_DDRSDRC_TWTR	(0x7 << 24)		/* Internal Write to Read delay */
+#define		AT91_DDRSDRC_RED_WRRD	(0x1 << 27)		/* Reduce Write to Read Delay */
+#define		AT91_DDRSDRC_TMRD	(0xf << 28)		/* Load mode to active/refresh delay */
+
+#define AT91_DDRSDRC_T1PR	0x10	/* Timing 1 Register */
+#define		AT91_DDRSDRC_TRFC	(0x1f << 0)		/* Row Cycle Delay */
+#define		AT91_DDRSDRC_TXSNR	(0xff << 8)		/* Exit self-refresh to non-read */
+#define		AT91_DDRSDRC_TXSRD	(0xff << 16)		/* Exit self-refresh to read */
+#define		AT91_DDRSDRC_TXP	(0xf  << 24)		/* Exit power-down delay */
+
+#define AT91_DDRSDRC_T2PR	0x14	/* Timing 2 Register */
+#define		AT91_DDRSDRC_TXARD	(0xf  << 0)		/* Exit active power down delay to read command in mode "Fast Exit" */
+#define		AT91_DDRSDRC_TXARDS	(0xf  << 4)		/* Exit active power down delay to read command in mode "Slow Exit" */
+#define		AT91_DDRSDRC_TRPA	(0xf  << 8)		/* Row Precharge All delay */
+#define		AT91_DDRSDRC_TRTP	(0x7  << 12)		/* Read to Precharge delay */
+
+#define AT91_DDRSDRC_LPR	0x1C	/* Low Power Register */
+#define		AT91_DDRSDRC_LPCB	(3 << 0)		/* Low-power Configurations */
+#define			AT91_DDRSDRC_LPCB_DISABLE		0
+#define			AT91_DDRSDRC_LPCB_SELF_REFRESH		1
+#define			AT91_DDRSDRC_LPCB_POWER_DOWN		2
+#define			AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN	3
+#define		AT91_DDRSDRC_CLKFR	(1 << 2)	/* Clock Frozen */
+#define		AT91_DDRSDRC_PASR	(7 << 4)	/* Partial Array Self Refresh */
+#define		AT91_DDRSDRC_TCSR	(3 << 8)	/* Temperature Compensated Self Refresh */
+#define		AT91_DDRSDRC_DS		(3 << 10)	/* Drive Strength */
+#define		AT91_DDRSDRC_TIMEOUT	(3 << 12)	/* Time to define when Low Power Mode is enabled */
+#define			AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES	(0 << 12)
+#define			AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES	(1 << 12)
+#define			AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES	(2 << 12)
+#define		AT91_DDRSDRC_APDE	(1 << 16)	 /* Active power down exit time */
+#define		AT91_DDRSDRC_UPD_MR	(3 << 20)	 /* Update load mode register and extended mode register */
+
+#define AT91_DDRSDRC_MDR	0x20	/* Memory Device Register */
+#define		AT91_DDRSDRC_MD		(3 << 0)		/* Memory Device Type */
+#define			AT91_DDRSDRC_MD_SDR		0
+#define			AT91_DDRSDRC_MD_LOW_POWER_SDR	1
+#define			AT91_DDRSDRC_MD_LOW_POWER_DDR	3
+#define			AT91_DDRSDRC_MD_DDR2		6
+#define		AT91_DDRSDRC_DBW	(1 << 4)		/* Data Bus Width */
+#define			AT91_DDRSDRC_DBW_32BITS		(0 <<  4)
+#define			AT91_DDRSDRC_DBW_16BITS		(1 <<  4)
+
+#define AT91_DDRSDRC_DLL	0x24	/* DLL Information Register */
+#define		AT91_DDRSDRC_MDINC	(1 << 0)		/* Master Delay increment */
+#define		AT91_DDRSDRC_MDDEC	(1 << 1)		/* Master Delay decrement */
+#define		AT91_DDRSDRC_MDOVF	(1 << 2)		/* Master Delay Overflow */
+#define		AT91_DDRSDRC_MDVAL	(0xff <<  8)		/* Master Delay value */
+
+#define AT91_DDRSDRC_HS		0x2C	/* High Speed Register */
+#define		AT91_DDRSDRC_DIS_ATCP_RD	(1 << 2)	/* Anticip read access is disabled */
+
+#define AT91_DDRSDRC_DELAY(n)	(0x30 + (0x4 * (n)))	/* Delay I/O Register n */
+
+#define AT91_DDRSDRC_WPMR	0xE4	/* Write Protect Mode Register */
+#define		AT91_DDRSDRC_WP		(1 << 0)		/* Write protect enable */
+#define		AT91_DDRSDRC_WPKEY	(0xffffff << 8)		/* Write protect key */
+#define		AT91_DDRSDRC_KEY	(0x444452 << 8)		/* Write protect key = "DDR" */
+
+#define AT91_DDRSDRC_WPSR	0xE8	/* Write Protect Status Register */
+#define		AT91_DDRSDRC_WPVS	(1 << 0)		/* Write protect violation status */
+#define		AT91_DDRSDRC_WPVSRC	(0xffff << 8)		/* Write protect violation source */
+
+/* Register access macros */
+#define at91_ramc_read(num, reg) \
+	at91_sys_read(AT91_DDRSDRC##num + reg)
+#define at91_ramc_write(num, reg, value) \
+	at91_sys_write(AT91_DDRSDRC##num + reg, value)
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
index b726038..100f5a5 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
@@ -17,7 +17,7 @@
 #define AT91SAM9_SDRAMC_H
 
 /* SDRAM Controller (SDRAMC) registers */
-#define AT91_SDRAMC_MR		(AT91_SDRAMC + 0x00)	/* SDRAM Controller Mode Register */
+#define AT91_SDRAMC_MR		0x00	/* SDRAM Controller Mode Register */
 #define		AT91_SDRAMC_MODE	(0xf << 0)		/* Command Mode */
 #define			AT91_SDRAMC_MODE_NORMAL		0
 #define			AT91_SDRAMC_MODE_NOP		1
@@ -27,10 +27,10 @@
 #define			AT91_SDRAMC_MODE_EXT_LMR	5
 #define			AT91_SDRAMC_MODE_DEEP		6
 
-#define AT91_SDRAMC_TR		(AT91_SDRAMC + 0x04)	/* SDRAM Controller Refresh Timer Register */
+#define AT91_SDRAMC_TR		0x04	/* SDRAM Controller Refresh Timer Register */
 #define		AT91_SDRAMC_COUNT	(0xfff << 0)		/* Refresh Timer Counter */
 
-#define AT91_SDRAMC_CR		(AT91_SDRAMC + 0x08)	/* SDRAM Controller Configuration Register */
+#define AT91_SDRAMC_CR		0x08	/* SDRAM Controller Configuration Register */
 #define		AT91_SDRAMC_NC		(3 << 0)		/* Number of Column Bits */
 #define			AT91_SDRAMC_NC_8	(0 << 0)
 #define			AT91_SDRAMC_NC_9	(1 << 0)
@@ -57,7 +57,7 @@
 #define		AT91_SDRAMC_TRAS	(0xf << 24)		/* Active to Precharge Delay */
 #define		AT91_SDRAMC_TXSR	(0xf << 28)		/* Exit Self Refresh to Active Delay */
 
-#define AT91_SDRAMC_LPR		(AT91_SDRAMC + 0x10)	/* SDRAM Controller Low Power Register */
+#define AT91_SDRAMC_LPR		0x10	/* SDRAM Controller Low Power Register */
 #define		AT91_SDRAMC_LPCB		(3 << 0)	/* Low-power Configurations */
 #define			AT91_SDRAMC_LPCB_DISABLE		0
 #define			AT91_SDRAMC_LPCB_SELF_REFRESH		1
@@ -71,16 +71,21 @@
 #define			AT91_SDRAMC_TIMEOUT_64_CLK_CYCLES	(1 << 12)
 #define			AT91_SDRAMC_TIMEOUT_128_CLK_CYCLES	(2 << 12)
 
-#define AT91_SDRAMC_IER		(AT91_SDRAMC + 0x14)	/* SDRAM Controller Interrupt Enable Register */
-#define AT91_SDRAMC_IDR		(AT91_SDRAMC + 0x18)	/* SDRAM Controller Interrupt Disable Register */
-#define AT91_SDRAMC_IMR		(AT91_SDRAMC + 0x1C)	/* SDRAM Controller Interrupt Mask Register */
-#define AT91_SDRAMC_ISR		(AT91_SDRAMC + 0x20)	/* SDRAM Controller Interrupt Status Register */
+#define AT91_SDRAMC_IER		0x14	/* SDRAM Controller Interrupt Enable Register */
+#define AT91_SDRAMC_IDR		0x18	/* SDRAM Controller Interrupt Disable Register */
+#define AT91_SDRAMC_IMR		0x1C	/* SDRAM Controller Interrupt Mask Register */
+#define AT91_SDRAMC_ISR		0x20	/* SDRAM Controller Interrupt Status Register */
 #define		AT91_SDRAMC_RES		(1 << 0)		/* Refresh Error Status */
 
-#define AT91_SDRAMC_MDR		(AT91_SDRAMC + 0x24)	/* SDRAM Memory Device Register */
+#define AT91_SDRAMC_MDR		0x24	/* SDRAM Memory Device Register */
 #define		AT91_SDRAMC_MD		(3 << 0)		/* Memory Device Type */
 #define			AT91_SDRAMC_MD_SDRAM		0
 #define			AT91_SDRAMC_MD_LOW_POWER_SDRAM	1
 
+/* Register access macros */
+#define at91_ramc_read(num, reg) \
+	at91_sys_read(AT91_SDRAMC##num + reg)
+#define at91_ramc_write(num, reg, value) \
+	at91_sys_write(AT91_SDRAMC##num + reg, value)
 
 #endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h
index fc2de6c..87ba851 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9rl.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h
@@ -74,7 +74,7 @@
  */
 #define AT91_DMA	(0xffffe600 - AT91_BASE_SYS)
 #define AT91_ECC	(0xffffe800 - AT91_BASE_SYS)
-#define AT91_SDRAMC	(0xffffea00 - AT91_BASE_SYS)
+#define AT91_SDRAMC0	(0xffffea00 - AT91_BASE_SYS)
 #define AT91_SMC	(0xffffec00 - AT91_BASE_SYS)
 #define AT91_MATRIX	(0xffffee00 - AT91_BASE_SYS)
 #define AT91_CCFG	(0xffffef10 - AT91_BASE_SYS)
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index df2ed84..58528aa 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -44,6 +44,8 @@
  /* USB Device */
 struct at91_udc_data {
 	u8	vbus_pin;		/* high == host powering us */
+	u8	vbus_active_low;	/* vbus polarity */
+	u8	vbus_polled;		/* Use polling, not interrupt */
 	u8	pullup_pin;		/* active == D+ pulled up */
 	u8	pullup_active_low;	/* true == pullup_pin is active low */
 };
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 833659d..3bef931 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -52,6 +52,7 @@
 
 #define ARCH_EXID_AT91SAM9M11	0x00000001
 #define ARCH_EXID_AT91SAM9M10	0x00000002
+#define ARCH_EXID_AT91SAM9G46	0x00000003
 #define ARCH_EXID_AT91SAM9G45	0x00000004
 
 static inline unsigned long at91_exid_identify(void)
@@ -128,9 +129,18 @@
 #ifdef CONFIG_ARCH_AT91SAM9G45
 #define cpu_is_at91sam9g45()	(at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
 #define cpu_is_at91sam9g45es()	(at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES)
+#define cpu_is_at91sam9m10()    (cpu_is_at91sam9g45() && \
+                                (at91_exid_identify() == ARCH_EXID_AT91SAM9M10))
+#define cpu_is_at91sam9m46()    (cpu_is_at91sam9g45() && \
+                                (at91_exid_identify() == ARCH_EXID_AT91SAM9G46))
+#define cpu_is_at91sam9m11()    (cpu_is_at91sam9g45() && \
+                                (at91_exid_identify() == ARCH_EXID_AT91SAM9M11))
 #else
 #define cpu_is_at91sam9g45()	(0)
 #define cpu_is_at91sam9g45es()	(0)
+#define cpu_is_at91sam9m10()	(0)
+#define cpu_is_at91sam9g46()	(0)
+#define cpu_is_at91sam9m11()	(0)
 #endif
 
 #ifdef CONFIG_ARCH_AT91CAP9
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
index 04c91e3..bfdd8ab 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -19,6 +19,7 @@
 #define PIN_BASE		NR_AIC_IRQS
 
 #define MAX_GPIO_BANKS		5
+#define NR_BUILTIN_GPIO		(PIN_BASE + (MAX_GPIO_BANKS * 32))
 
 /* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
 
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 08322c4..8c87d0c 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -30,14 +30,50 @@
 {
 	u32 saved_lpr, lpr;
 
-	saved_lpr = at91_sys_read(AT91_DDRSDRC_LPR);
+	saved_lpr = at91_ramc_read(0, AT91_DDRSDRC_LPR);
 
 	lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
-	at91_sys_write(AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
+	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
 	return saved_lpr;
 }
 
-#define sdram_selfrefresh_disable(saved_lpr)	at91_sys_write(AT91_DDRSDRC_LPR, saved_lpr)
+#define sdram_selfrefresh_disable(saved_lpr)	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr)
+
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#include <mach/at91sam9_ddrsdr.h>
+
+/* We manage both DDRAM/SDRAM controllers, we need more than one value to
+ * remember.
+ */
+static u32 saved_lpr1;
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+	/* Those tow values allow us to delay self-refresh activation
+	 * to the maximum. */
+	u32 lpr0, lpr1;
+	u32 saved_lpr0;
+
+	saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
+	lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
+	lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
+
+	saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
+	lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
+	lpr0 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
+
+	/* self-refresh mode now */
+	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
+	at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
+
+	return saved_lpr0;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr0)	\
+	do { \
+		at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \
+		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \
+	} while (0)
 
 #else
 #include <mach/at91sam9_sdramc.h>
@@ -47,7 +83,6 @@
  * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
  * handle those cases both here and in the Suspend-To-RAM support.
  */
-#define	AT91_SDRAMC	AT91_SDRAMC0
 #warning Assuming EB1 SDRAM controller is *NOT* used
 #endif
 
@@ -55,13 +90,13 @@
 {
 	u32 saved_lpr, lpr;
 
-	saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
+	saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR);
 
 	lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
-	at91_sys_write(AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
+	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
 	return saved_lpr;
 }
 
-#define sdram_selfrefresh_disable(saved_lpr)	at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
+#define sdram_selfrefresh_disable(saved_lpr)	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr)
 
 #endif
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index 9c5b48e..b6b00a1 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -16,10 +16,12 @@
 #include <mach/hardware.h>
 #include <mach/at91_pmc.h>
 
-#ifdef CONFIG_ARCH_AT91RM9200
+#if defined(CONFIG_ARCH_AT91RM9200)
 #include <mach/at91rm9200_mc.h>
 #elif defined(CONFIG_ARCH_AT91CAP9)
 #include <mach/at91cap9_ddrsdr.h>
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#include <mach/at91sam9_ddrsdr.h>
 #else
 #include <mach/at91sam9_sdramc.h>
 #endif
@@ -30,7 +32,6 @@
  * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
  * handle those cases both here and in the Suspend-To-RAM support.
  */
-#define AT91_SDRAMC	AT91_SDRAMC0
 #warning Assuming EB1 SDRAM controller is *NOT* used
 #endif
 
@@ -113,12 +114,14 @@
 	/*
 	 * Register usage:
 	 *  R1 = Base address of AT91_PMC
-	 *  R2 = Base address of AT91_SDRAMC (or AT91_SYS on AT91RM9200)
+	 *  R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
 	 *  R3 = temporary register
 	 *  R4 = temporary register
+	 *  R5 = Base address of second RAM Controller or 0 if not present
 	 */
 	ldr	r1, .at91_va_base_pmc
 	ldr	r2, .at91_va_base_sdramc
+	ldr	r5, .at91_va_base_ramc1
 
 	/* Drain write buffer */
 	mcr	p15, 0, r0, c7, c10, 4
@@ -127,20 +130,33 @@
 	/* Put SDRAM in self-refresh mode */
 	mov	r3, #1
 	str	r3, [r2, #AT91_SDRAMC_SRR]
-#elif defined(CONFIG_ARCH_AT91CAP9)
-	/* Enable SDRAM self-refresh mode */
-	ldr	r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
-	str	r3, .saved_sam9_lpr
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+	|| defined(CONFIG_ARCH_AT91SAM9G45)
 
-	mov	r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
-	str	r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
+	/* prepare for DDRAM self-refresh mode */
+	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
+	str	r3, .saved_sam9_lpr
+	bic	r3, #AT91_DDRSDRC_LPCB
+	orr	r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+
+	/* figure out if we use the second ram controller */
+	cmp	r5, #0
+	ldrne	r4, [r5, #AT91_DDRSDRC_LPR]
+	strne	r4, .saved_sam9_lpr1
+	bicne	r4, #AT91_DDRSDRC_LPCB
+	orrne	r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+
+	/* Enable DDRAM self-refresh mode */
+	str	r3, [r2, #AT91_DDRSDRC_LPR]
+	strne	r4, [r5, #AT91_DDRSDRC_LPR]
 #else
 	/* Enable SDRAM self-refresh mode */
-	ldr	r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
+	ldr	r3, [r2, #AT91_SDRAMC_LPR]
 	str	r3, .saved_sam9_lpr
 
-	mov	r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
-	str	r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
+	bic	r3, #AT91_SDRAMC_LPCB
+	orr	r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
+	str	r3, [r2, #AT91_SDRAMC_LPR]
 #endif
 
 	/* Save Master clock setting */
@@ -247,14 +263,21 @@
 
 #ifdef CONFIG_ARCH_AT91RM9200
 	/* Do nothing - self-refresh is automatically disabled. */
-#elif defined(CONFIG_ARCH_AT91CAP9)
-	/* Restore LPR on AT91CAP9 */
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+	|| defined(CONFIG_ARCH_AT91SAM9G45)
+	/* Restore LPR on AT91 with DDRAM */
 	ldr	r3, .saved_sam9_lpr
-	str	r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
+	str	r3, [r2, #AT91_DDRSDRC_LPR]
+
+	/* if we use the second ram controller */
+	cmp	r5, #0
+	ldrne	r4, .saved_sam9_lpr1
+	strne	r4, [r5, #AT91_DDRSDRC_LPR]
+
 #else
-	/* Restore LPR on AT91SAM9 */
+	/* Restore LPR on AT91 with SDRAM */
 	ldr	r3, .saved_sam9_lpr
-	str	r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
+	str	r3, [r2, #AT91_SDRAMC_LPR]
 #endif
 
 	/* Restore registers, and return */
@@ -273,18 +296,29 @@
 .saved_sam9_lpr:
 	.word 0
 
+.saved_sam9_lpr1:
+	.word 0
+
 .at91_va_base_pmc:
 	.word AT91_VA_BASE_SYS + AT91_PMC
 
 #ifdef CONFIG_ARCH_AT91RM9200
 .at91_va_base_sdramc:
 	.word AT91_VA_BASE_SYS
-#elif defined(CONFIG_ARCH_AT91CAP9)
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+	|| defined(CONFIG_ARCH_AT91SAM9G45)
 .at91_va_base_sdramc:
-	.word AT91_VA_BASE_SYS + AT91_DDRSDRC
+	.word AT91_VA_BASE_SYS + AT91_DDRSDRC0
 #else
 .at91_va_base_sdramc:
-	.word AT91_VA_BASE_SYS + AT91_SDRAMC
+	.word AT91_VA_BASE_SYS + AT91_SDRAMC0
+#endif
+
+.at91_va_base_ramc1:
+#if defined(CONFIG_ARCH_AT91SAM9G45)
+	.word AT91_VA_BASE_SYS + AT91_DDRSDRC1
+#else
+	.word 0
 #endif
 
 ENTRY(at91_slow_clock_sz)
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
index 72e405d..d3f959e 100644
--- a/arch/arm/mach-bcmring/core.c
+++ b/arch/arm/mach-bcmring/core.c
@@ -91,14 +91,23 @@
 	.parent = &pll1_clk,
 };
 
+static struct clk dummy_apb_pclk = {
+	.name = "BUSCLK",
+	.type = CLK_TYPE_PRIMARY,
+	.mode = CLK_MODE_XTAL,
+};
+
 static struct clk_lookup lookups[] = {
-	{			/* UART0 */
-	 .dev_id = "uarta",
-	 .clk = &uart_clk,
-	 }, {			/* UART1 */
-	     .dev_id = "uartb",
-	     .clk = &uart_clk,
-	     }
+	{			/* Bus clock */
+		.con_id = "apb_pclk",
+		.clk = &dummy_apb_pclk,
+	}, {			/* UART0 */
+		.dev_id = "uarta",
+		.clk = &uart_clk,
+	}, {			/* UART1 */
+		.dev_id = "uartb",
+		.clk = &uart_clk,
+	}
 };
 
 static struct amba_device *amba_devs[] __initdata = {
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index dbaae5f..eb34bd12 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -30,7 +30,6 @@
 config ARCH_EDB7211
 	bool "EDB7211"
 	select ISA
-	select ARCH_DISCONTIGMEM_ENABLE
 	select ARCH_SPARSEMEM_ENABLE
 	select ARCH_SELECT_MEMORY_MODEL
 	help
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c
index 09fb57e..3c3bf45 100644
--- a/arch/arm/mach-clps711x/clep7312.c
+++ b/arch/arm/mach-clps711x/clep7312.c
@@ -32,7 +32,6 @@
 	mi->nr_banks=1;
 	mi->bank[0].start = 0xc0000000;
 	mi->bank[0].size = 0x01000000;
-	mi->bank[0].node = 0;
 }
 
 
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index dc81cc6..4a7a232 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/memblock.h>
 #include <linux/types.h>
 #include <linux/string.h>
 
@@ -29,6 +30,12 @@
 
 extern void edb7211_map_io(void);
 
+/* Reserve screen memory region at the start of main system memory. */
+static void __init edb7211_reserve(void)
+{
+	memblock_reserve(PHYS_OFFSET, 0x00020000);
+}
+
 static void __init
 fixup_edb7211(struct machine_desc *desc, struct tag *tags,
 	      char **cmdline, struct meminfo *mi)
@@ -43,10 +50,8 @@
 	 */
 	mi->bank[0].start = 0xc0000000;
 	mi->bank[0].size = 8*1024*1024;
-	mi->bank[0].node = 0;
 	mi->bank[1].start = 0xc1000000;
 	mi->bank[1].size = 8*1024*1024;
-	mi->bank[1].node = 1;
 	mi->nr_banks = 2;
 }
 
@@ -57,6 +62,7 @@
 	.boot_params	= 0xc0020100,	/* 0xc0000000 - 0xc001ffff can be video RAM */
 	.fixup		= fixup_edb7211,
 	.map_io		= edb7211_map_io,
+	.reserve	= edb7211_reserve,
 	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c
index 7430e40..a696099 100644
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -39,7 +39,6 @@
 		{
 			.start	= 0xC0000000,
 			.size	= 0x01000000,
-			.node	= 0
 		},
 	},
 };
diff --git a/arch/arm/mach-clps711x/include/mach/memory.h b/arch/arm/mach-clps711x/include/mach/memory.h
index f70d52b..f45c8e8 100644
--- a/arch/arm/mach-clps711x/include/mach/memory.h
+++ b/arch/arm/mach-clps711x/include/mach/memory.h
@@ -20,7 +20,6 @@
 #ifndef __ASM_ARCH_MEMORY_H
 #define __ASM_ARCH_MEMORY_H
 
-
 /*
  * Physical DRAM offset.
  */
@@ -72,7 +71,6 @@
  * 	node 2:  0xd0000000 - 0xd7ffffff
  * 	node 3:  0xd8000000 - 0xdfffffff
  */
-#define NODE_MEM_SIZE_BITS	24
 #define SECTION_SIZE_BITS	24
 #define MAX_PHYSMEM_BITS	32
 
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 2ec3095..b280efb 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -25,6 +25,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/tps6507x.h>
 #include <linux/mfd/tps6507x.h>
 #include <linux/input/tps6507x-ts.h>
 
@@ -469,6 +470,11 @@
 	},
 };
 
+/* We take advantage of the fact that both defdcdc{2,3} are tied high */
+static struct tps6507x_reg_platform_data tps6507x_platform_data = {
+	.defdcdc_default = true,
+};
+
 struct regulator_init_data tps65070_regulator_data[] = {
 	/* dcdc1 */
 	{
@@ -494,6 +500,7 @@
 		},
 		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc2_consumers),
 		.consumer_supplies = tps65070_dcdc2_consumers,
+		.driver_data = &tps6507x_platform_data,
 	},
 
 	/* dcdc3 */
@@ -507,6 +514,7 @@
 		},
 		.num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc3_consumers),
 		.consumer_supplies = tps65070_dcdc3_consumers,
+		.driver_data = &tps6507x_platform_data,
 	},
 
 	/* ldo1 */
diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h
index a91edfb..22eb97c 100644
--- a/arch/arm/mach-davinci/include/mach/memory.h
+++ b/arch/arm/mach-davinci/include/mach/memory.h
@@ -48,19 +48,16 @@
  * below 128M
  */
 static inline void
-__arch_adjust_zones(int node, unsigned long *size, unsigned long *holes)
+__arch_adjust_zones(unsigned long *size, unsigned long *holes)
 {
 	unsigned int sz = (128<<20) >> PAGE_SHIFT;
 
-	if (node != 0)
-		sz = 0;
-
 	size[1] = size[0] - sz;
 	size[0] = sz;
 }
 
-#define arch_adjust_zones(node, zone_size, holes) \
-        if ((meminfo.bank[0].size >> 20) > 128) __arch_adjust_zones(node, zone_size, holes)
+#define arch_adjust_zones(zone_size, holes) \
+        if ((meminfo.bank[0].size >> 20) > 128) __arch_adjust_zones(zone_size, holes)
 
 #define ISA_DMA_THRESHOLD	(PHYS_OFFSET + (128<<20) - 1)
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + (128<<20))
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index 3a1a855..f744f67 100644
--- a/arch/arm/mach-ep93xx/adssphere.c
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -13,7 +13,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
 
 #include <mach/hardware.h>
 
@@ -21,26 +20,6 @@
 #include <asm/mach/arch.h>
 
 
-static struct physmap_flash_data adssphere_flash_data = {
-	.width		= 4,
-};
-
-static struct resource adssphere_flash_resource = {
-	.start		= EP93XX_CS6_PHYS_BASE,
-	.end		= EP93XX_CS6_PHYS_BASE + SZ_32M - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device adssphere_flash = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &adssphere_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &adssphere_flash_resource,
-};
-
 static struct ep93xx_eth_data __initdata adssphere_eth_data = {
 	.phy_id		= 1,
 };
@@ -48,8 +27,7 @@
 static void __init adssphere_init_machine(void)
 {
 	ep93xx_init_devices();
-	platform_device_register(&adssphere_flash);
-
+	ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
 	ep93xx_register_eth(&adssphere_eth_data, 1);
 }
 
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index e29bdef..7f303976 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -185,7 +185,7 @@
 	INIT_CK(NULL,			"pll1",		&clk_pll1),
 	INIT_CK(NULL,			"fclk",		&clk_f),
 	INIT_CK(NULL,			"hclk",		&clk_h),
-	INIT_CK(NULL,			"pclk",		&clk_p),
+	INIT_CK(NULL,			"apb_pclk",	&clk_p),
 	INIT_CK(NULL,			"pll2",		&clk_pll2),
 	INIT_CK("ep93xx-ohci",		NULL,		&clk_usb_host),
 	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 9092677..8e37a04 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -29,6 +29,7 @@
 #include <linux/termios.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
+#include <linux/mtd/physmap.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <linux/spi/spi.h>
@@ -215,8 +216,8 @@
 	spin_lock_irqsave(&syscon_swlock, flags);
 
 	val = __raw_readl(EP93XX_SYSCON_DEVCFG);
-	val |= set_bits;
 	val &= ~clear_bits;
+	val |= set_bits;
 	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
 	__raw_writel(val, EP93XX_SYSCON_DEVCFG);
 
@@ -348,6 +349,43 @@
 
 
 /*************************************************************************
+ * EP93xx physmap'ed flash
+ *************************************************************************/
+static struct physmap_flash_data ep93xx_flash_data;
+
+static struct resource ep93xx_flash_resource = {
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device ep93xx_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &ep93xx_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &ep93xx_flash_resource,
+};
+
+/**
+ * ep93xx_register_flash() - Register the external flash device.
+ * @width:	bank width in octets
+ * @start:	resource start address
+ * @size:	resource size
+ */
+void __init ep93xx_register_flash(unsigned int width,
+				  resource_size_t start, resource_size_t size)
+{
+	ep93xx_flash_data.width		= width;
+
+	ep93xx_flash_resource.start	= start;
+	ep93xx_flash_resource.end	= start + size - 1;
+
+	platform_device_register(&ep93xx_flash);
+}
+
+
+/*************************************************************************
  * EP93xx ethernet peripheral handling
  *************************************************************************/
 static struct ep93xx_eth_data ep93xx_eth_data;
@@ -620,6 +658,11 @@
 	.resource		= ep93xx_fb_resource,
 };
 
+static struct platform_device ep93xx_bl_device = {
+	.name		= "ep93xx-bl",
+	.id		= -1,
+};
+
 /**
  * ep93xx_register_fb - Register the framebuffer platform device.
  * @data:	platform specific framebuffer configuration (__initdata)
@@ -628,6 +671,7 @@
 {
 	ep93xxfb_data = *data;
 	platform_device_register(&ep93xx_fb_device);
+	platform_device_register(&ep93xx_bl_device);
 }
 
 
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 3884182..c2ce903 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -27,7 +27,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
@@ -38,39 +37,13 @@
 #include <asm/mach/arch.h>
 
 
-static struct physmap_flash_data edb93xx_flash_data;
-
-static struct resource edb93xx_flash_resource = {
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device edb93xx_flash = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &edb93xx_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &edb93xx_flash_resource,
-};
-
-static void __init __edb93xx_register_flash(unsigned int width,
-			resource_size_t start, resource_size_t size)
-{
-	edb93xx_flash_data.width	= width;
-	edb93xx_flash_resource.start	= start;
-	edb93xx_flash_resource.end	= start + size - 1;
-
-	platform_device_register(&edb93xx_flash);
-}
-
 static void __init edb93xx_register_flash(void)
 {
 	if (machine_is_edb9307() || machine_is_edb9312() ||
 	    machine_is_edb9315()) {
-		__edb93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
+		ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
 	} else {
-		__edb93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
+		ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
 	}
 }
 
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index a809618..d97168c 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -13,7 +13,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
 
 #include <mach/hardware.h>
 
@@ -21,26 +20,6 @@
 #include <asm/mach/arch.h>
 
 
-static struct physmap_flash_data gesbc9312_flash_data = {
-	.width		= 4,
-};
-
-static struct resource gesbc9312_flash_resource = {
-	.start		= EP93XX_CS6_PHYS_BASE,
-	.end		= EP93XX_CS6_PHYS_BASE + SZ_8M - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device gesbc9312_flash = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &gesbc9312_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &gesbc9312_flash_resource,
-};
-
 static struct ep93xx_eth_data __initdata gesbc9312_eth_data = {
 	.phy_id		= 1,
 };
@@ -48,8 +27,7 @@
 static void __init gesbc9312_init_machine(void)
 {
 	ep93xx_init_devices();
-	platform_device_register(&gesbc9312_flash);
-
+	ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_8M);
 	ep93xx_register_eth(&gesbc9312_eth_data, 0);
 }
 
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 9a4413d..a6c0917 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -43,6 +43,9 @@
 
 unsigned int ep93xx_chip_revision(void);
 
+void ep93xx_register_flash(unsigned int width,
+			   resource_size_t start, resource_size_t size);
+
 void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
 void ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
 			 struct i2c_board_info *devices, int num);
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index 1cc911b..2ba7763 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -14,7 +14,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
@@ -31,31 +30,6 @@
  * Micro9-Lite uses a separate MTD map driver for flash support
  * Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1
  *************************************************************************/
-static struct physmap_flash_data micro9_flash_data;
-
-static struct resource micro9_flash_resource = {
-	.start		= EP93XX_CS1_PHYS_BASE,
-	.end		= EP93XX_CS1_PHYS_BASE + SZ_64M - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device micro9_flash = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &micro9_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &micro9_flash_resource,
-};
-
-static void __init __micro9_register_flash(unsigned int width)
-{
-	micro9_flash_data.width = width;
-
-	platform_device_register(&micro9_flash);
-}
-
 static unsigned int __init micro9_detect_bootwidth(void)
 {
 	u32 v;
@@ -70,10 +44,17 @@
 
 static void __init micro9_register_flash(void)
 {
+	unsigned int width;
+
 	if (machine_is_micro9())
-		__micro9_register_flash(4);
+		width = 4;
 	else if (machine_is_micro9m() || machine_is_micro9s())
-		__micro9_register_flash(micro9_detect_bootwidth());
+		width = micro9_detect_bootwidth();
+	else
+		width = 0;
+
+	if (width)
+		ep93xx_register_flash(width, EP93XX_CS1_PHYS_BASE, SZ_64M);
 }
 
 
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index 388aec9..5dded58 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -18,7 +18,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
@@ -29,26 +28,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-static struct physmap_flash_data simone_flash_data = {
-	.width		= 2,
-};
-
-static struct resource simone_flash_resource = {
-	.start		= EP93XX_CS6_PHYS_BASE,
-	.end		= EP93XX_CS6_PHYS_BASE + SZ_8M - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device simone_flash = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.num_resources	= 1,
-	.resource	= &simone_flash_resource,
-	.dev = {
-		.platform_data	= &simone_flash_data,
-	},
-};
-
 static struct ep93xx_eth_data __initdata simone_eth_data = {
 	.phy_id		= 1,
 };
@@ -77,8 +56,7 @@
 static void __init simone_init_machine(void)
 {
 	ep93xx_init_devices();
-
-	platform_device_register(&simone_flash);
+	ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_8M);
 	ep93xx_register_eth(&simone_eth_data, 1);
 	ep93xx_register_fb(&simone_fb_info);
 	ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index ae7319e..93aeab8 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -17,7 +17,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/m48t86.h>
-#include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 
@@ -173,31 +172,13 @@
 };
 
 
-/*************************************************************************
- * NOR flash (TS-7200 only)
- *************************************************************************/
-static struct physmap_flash_data ts72xx_nor_data = {
-	.width		= 2,
-};
-
-static struct resource ts72xx_nor_resource = {
-	.start		= EP93XX_CS6_PHYS_BASE,
-	.end		= EP93XX_CS6_PHYS_BASE + SZ_16M - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device ts72xx_nor_flash = {
-	.name			= "physmap-flash",
-	.id			= 0,
-	.dev.platform_data	= &ts72xx_nor_data,
-	.resource		= &ts72xx_nor_resource,
-	.num_resources		= 1,
-};
-
 static void __init ts72xx_register_flash(void)
 {
+	/*
+	 * TS7200 has NOR flash all other TS72xx board have NAND flash.
+	 */
 	if (board_is_ts7200()) {
-		platform_device_register(&ts72xx_nor_flash);
+		ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
 	} else {
 		resource_size_t start;
 
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
new file mode 100644
index 0000000..5f96e15
--- /dev/null
+++ b/arch/arm/mach-integrator/common.h
@@ -0,0 +1 @@
+void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index b02cfc0..8f4fb6d 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/memblock.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/termios.h>
@@ -30,6 +31,7 @@
 #include <asm/system.h>
 #include <asm/leds.h>
 #include <asm/mach/time.h>
+#include <asm/pgtable.h>
 
 static struct amba_pl010_data integrator_uart_data;
 
@@ -119,8 +121,13 @@
 	.rate	= 14745600,
 };
 
+static struct clk dummy_apb_pclk;
+
 static struct clk_lookup lookups[] = {
-	{	/* UART0 */
+	{	/* Bus clock */
+		.con_id		= "apb_pclk",
+		.clk		= &dummy_apb_pclk,
+	}, {	/* UART0 */
 		.dev_id		= "mb:16",
 		.clk		= &uartclk,
 	}, {	/* UART1 */
@@ -215,3 +222,13 @@
 }
 
 EXPORT_SYMBOL(cm_control);
+
+/*
+ * We need to stop things allocating the low memory; ideally we need a
+ * better implementation of GFP_DMA which does not assume that DMA-able
+ * memory starts at zero.
+ */
+void __init integrator_reserve(void)
+{
+	memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+}
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 227cf4d..6ab5a03 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -48,6 +48,8 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
+#include "common.h"
+
 /* 
  * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
  * is the (PA >> 12).
@@ -502,6 +504,7 @@
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= ap_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= ap_init_irq,
 	.timer		= &ap_timer,
 	.init_machine	= ap_init,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index cde57b2..05db40e 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -43,6 +43,8 @@
 
 #include <plat/timer-sp.h>
 
+#include "common.h"
+
 #define INTCP_PA_FLASH_BASE		0x24000000
 #define INTCP_FLASH_SIZE		SZ_32M
 
@@ -601,6 +603,7 @@
 	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
 	.boot_params	= 0x00000100,
 	.map_io		= intcp_map_io,
+	.reserve	= integrator_reserve,
 	.init_irq	= intcp_init_irq,
 	.timer		= &cp_timer,
 	.init_machine	= intcp_init,
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 9cef059..6467d99 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -505,10 +505,10 @@
 	/*
 	 * Hook in our fault handler for PCI errors
 	 */
-	hook_fault_code(4, v3_pci_fault, SIGBUS, "external abort on linefetch");
-	hook_fault_code(6, v3_pci_fault, SIGBUS, "external abort on linefetch");
-	hook_fault_code(8, v3_pci_fault, SIGBUS, "external abort on non-linefetch");
-	hook_fault_code(10, v3_pci_fault, SIGBUS, "external abort on non-linefetch");
+	hook_fault_code(4, v3_pci_fault, SIGBUS, 0, "external abort on linefetch");
+	hook_fault_code(6, v3_pci_fault, SIGBUS, 0, "external abort on linefetch");
+	hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
+	hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
 
 	spin_lock_irqsave(&v3_lock, flags);
 
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
index 25b1da9..7415e43 100644
--- a/arch/arm/mach-iop13xx/include/mach/memory.h
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -69,6 +69,4 @@
 #endif /* CONFIG_ARCH_IOP13XX */
 #endif /* !ASSEMBLY */
 
-#define PFN_TO_NID(addr)	(0)
-
 #endif
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 6d5a908..773ea0c 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -987,7 +987,7 @@
 		iop13xx_atux_setup();
 	}
 
-	hook_fault_code(16+6, iop13xx_pci_abort, SIGBUS,
+	hook_fault_code(16+6, iop13xx_pci_abort, SIGBUS, 0,
 			"imprecise external abort");
 }
 
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 90771ca..f797c5f 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -209,7 +209,7 @@
 			"the needed workaround has not been configured in");
 #endif
 
-	hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS,
+	hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, 0,
 				"PCI config cycle to non-existent device");
 }
 
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
index 4b0e598..563819a 100644
--- a/arch/arm/mach-ixp23xx/pci.c
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -229,7 +229,7 @@
 {
 	ixp23xx_pci_common_init();
 
-	hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS,
+	hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, 0,
 			"PCI config cycle to non-existent device");
 
 	*IXP23XX_PCI_ADDR_EXT = 0x0000e000;
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index e3181534..61cd4d6 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -348,7 +348,7 @@
  * This is really ugly and we need a better way of specifying
  * DMA-capable regions of memory.
  */
-void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size,
+void __init ixp4xx_adjust_zones(unsigned long *zone_size,
 	unsigned long *zhole_size)
 {
 	unsigned int sz = SZ_64M >> PAGE_SHIFT;
@@ -356,7 +356,7 @@
 	/*
 	 * Only adjust if > 64M on current system
 	 */
-	if (node || (zone_size[0] <= sz))
+	if (zone_size[0] <= sz)
 		return;
 
 	zone_size[1] = zone_size[0] - sz;
@@ -382,7 +382,8 @@
 
 
 	/* hook in our fault handler for PCI errors */
-	hook_fault_code(16+6, abort_handler, SIGBUS, "imprecise external abort");
+	hook_fault_code(16+6, abort_handler, SIGBUS, 0,
+			"imprecise external abort");
 
 	pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
 
diff --git a/arch/arm/mach-ixp4xx/include/mach/memory.h b/arch/arm/mach-ixp4xx/include/mach/memory.h
index 98f5e5e..0136eaa 100644
--- a/arch/arm/mach-ixp4xx/include/mach/memory.h
+++ b/arch/arm/mach-ixp4xx/include/mach/memory.h
@@ -16,10 +16,10 @@
 
 #if !defined(__ASSEMBLY__) && defined(CONFIG_PCI)
 
-void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes);
+void ixp4xx_adjust_zones(unsigned long *size, unsigned long *holes);
 
-#define arch_adjust_zones(node, size, holes) \
-	ixp4xx_adjust_zones(node, size, holes)
+#define arch_adjust_zones(size, holes) \
+	ixp4xx_adjust_zones(size, holes)
 
 #define ISA_DMA_THRESHOLD (SZ_64M - 1)
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_64M)
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
index 7849966..5fcd082 100644
--- a/arch/arm/mach-ks8695/pci.c
+++ b/arch/arm/mach-ks8695/pci.c
@@ -268,8 +268,8 @@
 	__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");
+	hook_fault_code(8, ks8695_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
+	hook_fault_code(10, ks8695_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
 }
 
 static void ks8695_show_pciregs(void)
diff --git a/arch/arm/mach-l7200/Makefile b/arch/arm/mach-l7200/Makefile
deleted file mode 100644
index 4bd8ebd..0000000
--- a/arch/arm/mach-l7200/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-obj-y			:= core.o
-obj-m			:=
-obj-n			:=
-obj-			:=
-
diff --git a/arch/arm/mach-l7200/Makefile.boot b/arch/arm/mach-l7200/Makefile.boot
deleted file mode 100644
index 6c72ecb..0000000
--- a/arch/arm/mach-l7200/Makefile.boot
+++ /dev/null
@@ -1,2 +0,0 @@
-   zreladdr-y	:= 0xf0008000
-
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
deleted file mode 100644
index 50d2324..0000000
--- a/arch/arm/mach-l7200/core.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- *  linux/arch/arm/mm/mm-lusl7200.c
- *
- *  Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- *  Extra MM routines for L7200 architecture
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/device.h>
-
-#include <asm/types.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <asm/page.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-/*
- * IRQ base register
- */
-#define	IRQ_BASE	(IO_BASE_2 + 0x1000)
-
-/* 
- * Normal IRQ registers
- */
-#define IRQ_STATUS	(*(volatile unsigned long *) (IRQ_BASE + 0x000))
-#define IRQ_RAWSTATUS	(*(volatile unsigned long *) (IRQ_BASE + 0x004))
-#define IRQ_ENABLE	(*(volatile unsigned long *) (IRQ_BASE + 0x008))
-#define IRQ_ENABLECLEAR	(*(volatile unsigned long *) (IRQ_BASE + 0x00c))
-#define IRQ_SOFT	(*(volatile unsigned long *) (IRQ_BASE + 0x010))
-#define IRQ_SOURCESEL	(*(volatile unsigned long *) (IRQ_BASE + 0x018))
-
-/* 
- * Fast IRQ registers
- */
-#define FIQ_STATUS	(*(volatile unsigned long *) (IRQ_BASE + 0x100))
-#define FIQ_RAWSTATUS	(*(volatile unsigned long *) (IRQ_BASE + 0x104))
-#define FIQ_ENABLE	(*(volatile unsigned long *) (IRQ_BASE + 0x108))
-#define FIQ_ENABLECLEAR	(*(volatile unsigned long *) (IRQ_BASE + 0x10c))
-#define FIQ_SOFT	(*(volatile unsigned long *) (IRQ_BASE + 0x110))
-#define FIQ_SOURCESEL	(*(volatile unsigned long *) (IRQ_BASE + 0x118))
-
-static void l7200_mask_irq(unsigned int irq)
-{
-	IRQ_ENABLECLEAR = 1 << irq;
-}
-
-static void l7200_unmask_irq(unsigned int irq)
-{
-	IRQ_ENABLE = 1 << irq;
-}
-
-static struct irq_chip l7200_irq_chip = {
-	.ack		= l7200_mask_irq,
-	.mask		= l7200_mask_irq,
-	.unmask		= l7200_unmask_irq
-};
- 
-static void __init l7200_init_irq(void)
-{
-	int irq;
-
-	IRQ_ENABLECLEAR = 0xffffffff;	/* clear all interrupt enables */
-	FIQ_ENABLECLEAR = 0xffffffff;	/* clear all fast interrupt enables */
-
-	for (irq = 0; irq < NR_IRQS; irq++) {
-		set_irq_chip(irq, &l7200_irq_chip);
-		set_irq_flags(irq, IRQF_VALID);
-		set_irq_handler(irq, handle_level_irq);
-	}
-
-	init_FIQ();
-}
-
-static struct map_desc l7200_io_desc[] __initdata = {
-	{ IO_BASE,	IO_START,	IO_SIZE,	MT_DEVICE },
-	{ IO_BASE_2,	IO_START_2,	IO_SIZE_2,	MT_DEVICE },
-	{ AUX_BASE,     AUX_START,      AUX_SIZE,       MT_DEVICE },
-	{ FLASH1_BASE,  FLASH1_START,   FLASH1_SIZE,    MT_DEVICE },
-	{ FLASH2_BASE,  FLASH2_START,   FLASH2_SIZE,    MT_DEVICE }
-};
-
-static void __init l7200_map_io(void)
-{
-	iotable_init(l7200_io_desc, ARRAY_SIZE(l7200_io_desc));
-}
-
-MACHINE_START(L7200, "LinkUp Systems L7200")
-	/* Maintainer: Steve Hill / Scott McConnell */
-	.phys_io	= 0x80040000,
-	.io_pg_offst	= ((0xd0000000) >> 18) & 0xfffc,
-	.map_io		= l7200_map_io,
-	.init_irq	= l7200_init_irq,
-MACHINE_END
-
diff --git a/arch/arm/mach-l7200/include/mach/aux_reg.h b/arch/arm/mach-l7200/include/mach/aux_reg.h
deleted file mode 100644
index 4671558..0000000
--- a/arch/arm/mach-l7200/include/mach/aux_reg.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/aux_reg.h
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- *   08-02-2000	SJH	Created file
- */
-#ifndef _ASM_ARCH_AUXREG_H
-#define _ASM_ARCH_AUXREG_H
-
-#include <mach/hardware.h>
-
-#define l7200aux_reg	*((volatile unsigned int *) (AUX_BASE))
-
-/*
- * Auxillary register values
- */
-#define AUX_CLEAR		0x00000000
-#define AUX_DIAG_LED_ON		0x00000002
-#define AUX_RTS_UART1		0x00000004
-#define AUX_DTR_UART1		0x00000008
-#define AUX_KBD_COLUMN_12_HIGH	0x00000010
-#define AUX_KBD_COLUMN_12_OFF	0x00000020
-#define AUX_KBD_COLUMN_13_HIGH	0x00000040
-#define AUX_KBD_COLUMN_13_OFF	0x00000080
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/debug-macro.S b/arch/arm/mach-l7200/include/mach/debug-macro.S
deleted file mode 100644
index b69ed34..0000000
--- a/arch/arm/mach-l7200/include/mach/debug-macro.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* arch/arm/mach-l7200/include/mach/debug-macro.S
- *
- * Debugging macro include header
- *
- *  Copyright (C) 1994-1999 Russell King
- *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * 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.
- *
-*/
-
-		.equ	io_virt, IO_BASE
-		.equ	io_phys, IO_START
-
-		.macro	addruart, rx, tmp
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #io_phys		@ physical base address
-		movne	\rx, #io_virt		@ virtual address
-		add	\rx, \rx, #0x00044000	@ UART1
-@		add	\rx, \rx, #0x00045000	@ UART2
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #0x0]	@ UARTDR
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
-		bne	1001b
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
-		bne	1001b
-		.endm
diff --git a/arch/arm/mach-l7200/include/mach/entry-macro.S b/arch/arm/mach-l7200/include/mach/entry-macro.S
deleted file mode 100644
index 1726d91..0000000
--- a/arch/arm/mach-l7200/include/mach/entry-macro.S
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for L7200-based platforms
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <mach/hardware.h>
-
-		.equ	irq_base_addr,	IO_BASE_2
-
-		.macro  disable_fiq
-		.endm
-
-		.macro  get_irqnr_preamble, base, tmp
-		.endm
-
-		.macro  arch_ret_to_user, tmp1, tmp2
-		.endm
-
-		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov     \irqstat, #irq_base_addr		@ Virt addr IRQ regs
-		add	\irqstat, \irqstat, #0x00001000		@ Status reg
-		ldr     \irqstat, [\irqstat, #0]		@ get interrupts
-		mov     \irqnr, #0
-1001:		tst     \irqstat, #1
-		addeq   \irqnr, \irqnr, #1
-		moveq   \irqstat, \irqstat, lsr #1
-		tsteq   \irqnr, #32
-		beq     1001b
-		teq     \irqnr, #32
-		.endm
-
diff --git a/arch/arm/mach-l7200/include/mach/gp_timers.h b/arch/arm/mach-l7200/include/mach/gp_timers.h
deleted file mode 100644
index 2b7086a..0000000
--- a/arch/arm/mach-l7200/include/mach/gp_timers.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/gp_timers.h
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- *   07-28-2000	SJH	Created file
- *   08-02-2000	SJH	Used structure for registers
- */
-#ifndef _ASM_ARCH_GPTIMERS_H
-#define _ASM_ARCH_GPTIMERS_H
-
-#include <mach/hardware.h>
-
-/*
- * Layout of L7200 general purpose timer registers
- */
-struct GPT_Regs {
-	unsigned int TIMERLOAD;
-	unsigned int TIMERVALUE;
-	unsigned int TIMERCONTROL;
-	unsigned int TIMERCLEAR;
-};
-
-#define GPT_BASE		(IO_BASE_2 + 0x3000)
-#define l7200_timer1_regs	((volatile struct GPT_Regs *) (GPT_BASE))
-#define l7200_timer2_regs	((volatile struct GPT_Regs *) (GPT_BASE + 0x20))
-
-/*
- * General register values
- */
-#define	GPT_PRESCALE_1		0x00000000
-#define	GPT_PRESCALE_16		0x00000004
-#define	GPT_PRESCALE_256	0x00000008
-#define GPT_MODE_FREERUN	0x00000000
-#define GPT_MODE_PERIODIC	0x00000040
-#define GPT_ENABLE		0x00000080
-#define GPT_BZTOG		0x00000100
-#define GPT_BZMOD		0x00000200
-#define GPT_LOAD_MASK 		0x0000ffff
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/gpio.h b/arch/arm/mach-l7200/include/mach/gpio.h
deleted file mode 100644
index c7b0a5d..0000000
--- a/arch/arm/mach-l7200/include/mach/gpio.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************/
-/*
- *      arch/arm/mach-l7200/include/mach/gpio.h
- *
- *      Registers and  helper functions for the L7200 Link-Up Systems
- *      GPIO.
- *
- *      (C) Copyright 2000, S A McConnell  (samcconn@cotw.com)
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-/****************************************************************************/
-
-#define GPIO_OFF   0x00005000  /* Offset from IO_START to the GPIO reg's. */
-
-/* IO_START and IO_BASE are defined in hardware.h */
-
-#define GPIO_START (IO_START_2 + GPIO_OFF) /* Physical addr of the GPIO reg. */
-#define GPIO_BASE  (IO_BASE_2  + GPIO_OFF) /* Virtual addr of the GPIO reg. */
-
-/* Offsets from the start of the GPIO for all the registers. */
-#define PADR_OFF     0x000
-#define PADDR_OFF    0x004
-#define PASBSR_OFF   0x008
-#define PAEENR_OFF   0x00c
-#define PAESNR_OFF   0x010
-#define PAESTR_OFF   0x014
-#define PAIMR_OFF    0x018
-#define PAINT_OFF    0x01c
-
-#define PBDR_OFF     0x020
-#define PBDDR_OFF    0x024
-#define PBSBSR_OFF   0x028
-#define PBIMR_OFF    0x038
-#define PBINT_OFF    0x03c
-
-#define PCDR_OFF     0x040
-#define PCDDR_OFF    0x044
-#define PCSBSR_OFF   0x048
-#define PCIMR_OFF    0x058
-#define PCINT_OFF    0x05c
-
-#define PDDR_OFF     0x060
-#define PDDDR_OFF    0x064
-#define PDSBSR_OFF   0x068
-#define PDEENR_OFF   0x06c
-#define PDESNR_OFF   0x070
-#define PDESTR_OFF   0x074
-#define PDIMR_OFF    0x078
-#define PDINT_OFF    0x07c
-
-#define PEDR_OFF     0x080
-#define PEDDR_OFF    0x084
-#define PESBSR_OFF   0x088
-#define PEEENR_OFF   0x08c
-#define PEESNR_OFF   0x090
-#define PEESTR_OFF   0x094
-#define PEIMR_OFF    0x098
-#define PEINT_OFF    0x09c
-
-/* Define the GPIO registers for use by device drivers and the kernel. */
-#define PADR   (*(volatile unsigned long *)(GPIO_BASE+PADR_OFF))
-#define PADDR  (*(volatile unsigned long *)(GPIO_BASE+PADDR_OFF))
-#define PASBSR (*(volatile unsigned long *)(GPIO_BASE+PASBSR_OFF))
-#define PAEENR (*(volatile unsigned long *)(GPIO_BASE+PAEENR_OFF))
-#define PAESNR (*(volatile unsigned long *)(GPIO_BASE+PAESNR_OFF))
-#define PAESTR (*(volatile unsigned long *)(GPIO_BASE+PAESTR_OFF))
-#define PAIMR  (*(volatile unsigned long *)(GPIO_BASE+PAIMR_OFF))
-#define PAINT  (*(volatile unsigned long *)(GPIO_BASE+PAINT_OFF))
-
-#define PBDR   (*(volatile unsigned long *)(GPIO_BASE+PBDR_OFF))
-#define PBDDR  (*(volatile unsigned long *)(GPIO_BASE+PBDDR_OFF))
-#define PBSBSR (*(volatile unsigned long *)(GPIO_BASE+PBSBSR_OFF))
-#define PBIMR  (*(volatile unsigned long *)(GPIO_BASE+PBIMR_OFF))
-#define PBINT  (*(volatile unsigned long *)(GPIO_BASE+PBINT_OFF))
-
-#define PCDR   (*(volatile unsigned long *)(GPIO_BASE+PCDR_OFF))
-#define PCDDR  (*(volatile unsigned long *)(GPIO_BASE+PCDDR_OFF))
-#define PCSBSR (*(volatile unsigned long *)(GPIO_BASE+PCSBSR_OFF))
-#define PCIMR  (*(volatile unsigned long *)(GPIO_BASE+PCIMR_OFF))
-#define PCINT  (*(volatile unsigned long *)(GPIO_BASE+PCINT_OFF))
-
-#define PDDR   (*(volatile unsigned long *)(GPIO_BASE+PDDR_OFF))
-#define PDDDR  (*(volatile unsigned long *)(GPIO_BASE+PDDDR_OFF))
-#define PDSBSR (*(volatile unsigned long *)(GPIO_BASE+PDSBSR_OFF))
-#define PDEENR (*(volatile unsigned long *)(GPIO_BASE+PDEENR_OFF))
-#define PDESNR (*(volatile unsigned long *)(GPIO_BASE+PDESNR_OFF))
-#define PDESTR (*(volatile unsigned long *)(GPIO_BASE+PDESTR_OFF))
-#define PDIMR  (*(volatile unsigned long *)(GPIO_BASE+PDIMR_OFF))
-#define PDINT  (*(volatile unsigned long *)(GPIO_BASE+PDINT_OFF))
-
-#define PEDR   (*(volatile unsigned long *)(GPIO_BASE+PEDR_OFF))
-#define PEDDR  (*(volatile unsigned long *)(GPIO_BASE+PEDDR_OFF))
-#define PESBSR (*(volatile unsigned long *)(GPIO_BASE+PESBSR_OFF))
-#define PEEENR (*(volatile unsigned long *)(GPIO_BASE+PEEENR_OFF))
-#define PEESNR (*(volatile unsigned long *)(GPIO_BASE+PEESNR_OFF))
-#define PEESTR (*(volatile unsigned long *)(GPIO_BASE+PEESTR_OFF))
-#define PEIMR  (*(volatile unsigned long *)(GPIO_BASE+PEIMR_OFF))
-#define PEINT  (*(volatile unsigned long *)(GPIO_BASE+PEINT_OFF))
-
-#define VEE_EN         0x02
-#define BACKLIGHT_EN   0x04
diff --git a/arch/arm/mach-l7200/include/mach/hardware.h b/arch/arm/mach-l7200/include/mach/hardware.h
deleted file mode 100644
index c31909c..0000000
--- a/arch/arm/mach-l7200/include/mach/hardware.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/hardware.h
- *
- * Copyright (C) 2000 Rob Scott (rscott@mtrob.fdns.net)
- *                    Steve Hill (sjhill@cotw.com)
- *
- * This file contains the hardware definitions for the 
- * LinkUp Systems L7200 SOC development board.
- *
- * Changelog:
- *   02-01-2000	 RS	Created L7200 version, derived from rpc code
- *   03-21-2000	SJH	Cleaned up file
- *   04-21-2000	 RS 	Changed mapping of I/O in virtual space
- *   04-25-2000	SJH	Removed unused symbols and such
- *   05-05-2000	SJH	Complete rewrite
- *   07-31-2000	SJH	Added undocumented debug auxillary port to
- *			get at last two columns for keyboard driver
- */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-/* Hardware addresses of major areas.
- *  *_START is the physical address
- *  *_SIZE  is the size of the region
- *  *_BASE  is the virtual address
- */
-#define RAM_START		0xf0000000
-#define RAM_SIZE		0x02000000
-#define RAM_BASE		0xc0000000
-
-#define IO_START		0x80000000      /* I/O */
-#define IO_SIZE			0x01000000
-#define IO_BASE			0xd0000000
-
-#define IO_START_2		0x90000000      /* I/O */
-#define IO_SIZE_2		0x01000000
-#define IO_BASE_2		0xd1000000
-
-#define AUX_START		0x1a000000      /* AUX PORT */
-#define AUX_SIZE 		0x01000000
-#define AUX_BASE		0xd2000000
-
-#define FLASH1_START		0x00000000      /* FLASH BANK 1 */
-#define FLASH1_SIZE 		0x01000000
-#define FLASH1_BASE		0xd3000000
-
-#define FLASH2_START		0x10000000      /* FLASH BANK 2 */
-#define FLASH2_SIZE 		0x01000000
-#define FLASH2_BASE		0xd4000000
-
-#define ISA_START		0x20000000	/* ISA */
-#define ISA_SIZE		0x20000000
-#define ISA_BASE		0xe0000000
-
-#define PCIO_BASE		IO_BASE
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/io.h b/arch/arm/mach-l7200/include/mach/io.h
deleted file mode 100644
index a770a89..0000000
--- a/arch/arm/mach-l7200/include/mach/io.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/io.h
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- *  03-21-2000	SJH	Created from arch/arm/mach-nexuspci/include/mach/io.h
- *  08-31-2000	SJH	Added in IO functions necessary for new drivers
- */
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#define IO_SPACE_LIMIT 0xffffffff
-
-/*
- * There are not real ISA nor PCI buses, so we fake it.
- */
-#define __io(a)		__typesafe_io(a)
-#define __mem_pci(a)	(a)
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/irqs.h b/arch/arm/mach-l7200/include/mach/irqs.h
deleted file mode 100644
index 7edffd7..0000000
--- a/arch/arm/mach-l7200/include/mach/irqs.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/irqs.h
- *
- * Copyright (C) 2000 Rob Scott (rscott@mtrob.fdns.net)
- *                    Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- *   01-02-2000 RS	Create l7200 version
- *   03-28-2000 SJH	Removed unused interrupt
- *   07-28-2000 SJH	Added pseudo-keyboard interrupt
- */
-
-/*
- * NOTE: The second timer (Timer 2) is used as the keyboard
- *       interrupt when the keyboard driver is enabled.
- */
-
-#define NR_IRQS          32
-
-#define IRQ_STWDOG        0   /* Watchdog timer */
-#define IRQ_PROG          1   /* Programmable interrupt */
-#define IRQ_DEBUG_RX      2   /* Comm Rx debug */
-#define IRQ_DEBUG_TX      3   /* Comm Tx debug */
-#define IRQ_GCTC1         4   /* Timer 1 */
-#define IRQ_GCTC2         5   /* Timer 2 / Keyboard */
-#define IRQ_DMA           6   /* DMA controller */
-#define IRQ_CLCD          7   /* Color LCD controller */
-#define IRQ_SM_RX         8   /* Smart card */
-#define IRQ_SM_TX         9   /* Smart cart */
-#define IRQ_SM_RST       10   /* Smart card */
-#define IRQ_SIB          11   /* Serial Interface Bus */
-#define IRQ_MMC          12   /* MultiMediaCard */
-#define IRQ_SSP1         13   /* Synchronous Serial Port 1 */
-#define IRQ_SSP2         14   /* Synchronous Serial Port 1 */
-#define IRQ_SPI          15   /* SPI slave */
-#define IRQ_UART_1       16   /* UART 1 */
-#define IRQ_UART_2       17   /* UART 2 */
-#define IRQ_IRDA         18   /* IRDA */
-#define IRQ_RTC_TICK     19   /* Real Time Clock tick */
-#define IRQ_RTC_ALARM    20   /* Real Time Clock alarm */
-#define IRQ_GPIO         21   /* General Purpose IO */
-#define IRQ_GPIO_DMA     22   /* General Purpose IO, DMA */
-#define IRQ_M2M          23   /* Memory to memory DMA  */
-#define IRQ_RESERVED     24   /* RESERVED, don't use */
-#define IRQ_INTF         25   /* External active low interrupt */
-#define IRQ_INT0         26   /* External active low interrupt */
-#define IRQ_INT1         27   /* External active low interrupt */
-#define IRQ_INT2         28   /* External active low interrupt */
-#define IRQ_UCB1200      29   /* Interrupt generated by UCB1200*/
-#define IRQ_BAT_LO       30   /* Low batery or external power */
-#define IRQ_MEDIA_CHG    31   /* Media change interrupt */
-
-/*
- * This is the offset of the FIQ "IRQ" numbers
- */
-#define FIQ_START	64
diff --git a/arch/arm/mach-l7200/include/mach/memory.h b/arch/arm/mach-l7200/include/mach/memory.h
deleted file mode 100644
index 9fb40ed..0000000
--- a/arch/arm/mach-l7200/include/mach/memory.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/memory.h
- *
- * Copyright (c) 2000 Steve Hill (sjhill@cotw.com)
- * Copyright (c) 2000 Rob Scott (rscott@mtrob.fdns.net)
- *
- * Changelog:
- *  03-13-2000	SJH	Created
- *  04-13-2000  RS      Changed bus macros for new addr
- *  05-03-2000  SJH     Removed bus macros and fixed virt_to_phys macro
- */
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-/*
- * Physical DRAM offset on the L7200 SDB.
- */
-#define PHYS_OFFSET     UL(0xf0000000)
-
-/*
- * Cache flushing area - ROM
- */
-#define FLUSH_BASE_PHYS		0x40000000
-#define FLUSH_BASE		0xdf000000
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/pmpcon.h b/arch/arm/mach-l7200/include/mach/pmpcon.h
deleted file mode 100644
index 3959871..0000000
--- a/arch/arm/mach-l7200/include/mach/pmpcon.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/****************************************************************************/
-/*
- *  arch/arm/mach-l7200/include/mach/pmpcon.h
- *
- *   Registers and  helper functions for the L7200 Link-Up Systems
- *   DC/DC converter register.
- *
- *   (C) Copyright 2000, S A McConnell  (samcconn@cotw.com)
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-/****************************************************************************/
-
-#define PMPCON_OFF 0x00006000  /* Offset from IO_START_2. */
-
-/* IO_START_2 and IO_BASE_2 are defined in hardware.h */
-
-#define PMPCON_START (IO_START_2 + PMPCON_OFF)  /* Physical address of reg. */
-#define PMPCON_BASE  (IO_BASE_2  + PMPCON_OFF)  /* Virtual address of reg. */
-
-
-#define PMPCON (*(volatile unsigned int *)(PMPCON_BASE))
-
-#define PWM2_50CYCLE 0x800
-#define CONTRAST     0x9
-
-#define PWM1H (CONTRAST)
-#define PWM1L (CONTRAST << 4)
-
-#define PMPCON_VALUE  (PWM2_50CYCLE | PWM1L | PWM1H) 
-	
-/* PMPCON = 0x811;   // too light and fuzzy
- * PMPCON = 0x844;   
- * PMPCON = 0x866;   // better color poor depth
- * PMPCON = 0x888;   // Darker but better depth 
- * PMPCON = 0x899;   // Darker even better depth
- * PMPCON = 0x8aa;   // too dark even better depth
- * PMPCON = 0X8cc;   // Way too dark
- */
-
-/* As CONTRAST value increases the greater the depth perception and
- * the darker the colors.
- */
diff --git a/arch/arm/mach-l7200/include/mach/pmu.h b/arch/arm/mach-l7200/include/mach/pmu.h
deleted file mode 100644
index a2da7ae..0000000
--- a/arch/arm/mach-l7200/include/mach/pmu.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************/
-/*
- *  arch/arm/mach-l7200/include/mach/pmu.h
- *
- *   Registers and  helper functions for the L7200 Link-Up Systems
- *   Power Management Unit (PMU).
- *
- *   (C) Copyright 2000, S A McConnell  (samcconn@cotw.com)
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-/****************************************************************************/
-
-#define PMU_OFF   0x00050000  /* Offset from IO_START to the PMU registers. */
-
-/* IO_START and IO_BASE are defined in hardware.h */
-
-#define PMU_START (IO_START + PMU_OFF)  /* Physical addr. of the PMU reg. */
-#define PMU_BASE  (IO_BASE  + PMU_OFF)  /* Virtual addr. of the PMU reg. */
-
-
-/* Define the PMU registers for use by device drivers and the kernel. */
-
-typedef struct {
-     unsigned int CURRENT;  /* Current configuration register */
-     unsigned int NEXT;     /* Next configuration register */
-     unsigned int reserved;
-     unsigned int RUN;      /* Run configuration register */
-     unsigned int COMM;     /* Configuration command register */
-     unsigned int SDRAM;    /* SDRAM configuration bypass register */
-} pmu_interface;
-
-#define PMU ((volatile pmu_interface *)(PMU_BASE))
-
-
-/* Macro's for reading the common register fields. */
-
-#define GET_TRANSOP(reg)  ((reg >> 25) & 0x03) /* Bits 26-25 */
-#define GET_OSCEN(reg)    ((reg >> 16) & 0x01)
-#define GET_OSCMUX(reg)   ((reg >> 15) & 0x01)
-#define GET_PLLMUL(reg)   ((reg >>  9) & 0x3f) /* Bits 14-9 */
-#define GET_PLLEN(reg)    ((reg >>  8) & 0x01)
-#define GET_PLLMUX(reg)   ((reg >>  7) & 0x01)
-#define GET_BCLK_DIV(reg) ((reg >>  3) & 0x03) /* Bits 4-3 */
-#define GET_SDRB_SEL(reg) ((reg >>  2) & 0x01)
-#define GET_SDRF_SEL(reg) ((reg >>  1) & 0x01)
-#define GET_FASTBUS(reg)  (reg & 0x1)
-
-/* CFG_NEXT register */
-
-#define CFG_NEXT_CLOCKRECOVERY ((PMU->NEXT >> 18) & 0x7f)   /* Bits 24-18 */
-#define CFG_NEXT_INTRET        ((PMU->NEXT >> 17) & 0x01)
-#define CFG_NEXT_SDR_STOP      ((PMU->NEXT >>  6) & 0x01)
-#define CFG_NEXT_SYSCLKEN      ((PMU->NEXT >>  5) & 0x01)
-
-/* Useful field values that can be used to construct the
- * CFG_NEXT and CFG_RUN registers.
- */
-
-#define TRANSOP_NOP      0<<25  /* NOCHANGE_NOSTALL */
-#define NOCHANGE_STALL   1<<25
-#define CHANGE_NOSTALL   2<<25
-#define CHANGE_STALL     3<<25
-
-#define INTRET           1<<17
-#define OSCEN            1<<16
-#define OSCMUX           1<<15
-
-/* PLL frequencies */
-
-#define PLLMUL_0         0<<9         /*  3.6864 MHz */
-#define PLLMUL_1         1<<9         /*  ?????? MHz */
-#define PLLMUL_5         5<<9         /*  18.432 MHz */
-#define PLLMUL_10       10<<9         /*  36.864 MHz */
-#define PLLMUL_18       18<<9         /*  ?????? MHz */
-#define PLLMUL_20       20<<9         /*  73.728 MHz */
-#define PLLMUL_32       32<<9         /*  ?????? MHz */
-#define PLLMUL_35       35<<9         /* 129.024 MHz */
-#define PLLMUL_36       36<<9         /*  ?????? MHz */
-#define PLLMUL_39       39<<9         /*  ?????? MHz */
-#define PLLMUL_40       40<<9         /* 147.456 MHz */
-
-/* Clock recovery times */
-
-#define CRCLOCK_1        1<<18
-#define CRCLOCK_2        2<<18
-#define CRCLOCK_4        4<<18
-#define CRCLOCK_8        8<<18
-#define CRCLOCK_16      16<<18
-#define CRCLOCK_32      32<<18
-#define CRCLOCK_63      63<<18
-#define CRCLOCK_127    127<<18
-
-#define PLLEN            1<<8
-#define PLLMUX           1<<7
-#define SDR_STOP         1<<6
-#define SYSCLKEN         1<<5
-
-#define BCLK_DIV_4       2<<3
-#define BCLK_DIV_2       1<<3
-#define BCLK_DIV_1       0<<3
-
-#define SDRB_SEL         1<<2
-#define SDRF_SEL         1<<1
-#define FASTBUS          1<<0
-
-
-/* CFG_SDRAM */
-
-#define SDRREFFQ         1<<0  /* Only if SDRSTOPRQ is not set. */
-#define SDRREFACK        1<<1  /* Read-only */
-#define SDRSTOPRQ        1<<2  /* Only if SDRREFFQ is not set. */
-#define SDRSTOPACK       1<<3  /* Read-only */
-#define PICEN            1<<4  /* Enable Co-procesor */
-#define PICTEST          1<<5
-
-#define GET_SDRREFFQ    ((PMU->SDRAM >> 0) & 0x01)
-#define GET_SDRREFACK   ((PMU->SDRAM >> 1) & 0x01) /* Read-only */
-#define GET_SDRSTOPRQ   ((PMU->SDRAM >> 2) & 0x01)
-#define GET_SDRSTOPACK  ((PMU->SDRAM >> 3) & 0x01) /* Read-only */
-#define GET_PICEN       ((PMU->SDRAM >> 4) & 0x01)
-#define GET_PICTEST     ((PMU->SDRAM >> 5) & 0x01)
diff --git a/arch/arm/mach-l7200/include/mach/serial.h b/arch/arm/mach-l7200/include/mach/serial.h
deleted file mode 100644
index adc05e5..0000000
--- a/arch/arm/mach-l7200/include/mach/serial.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/serial.h
- *
- * Copyright (c) 2000 Rob Scott (rscott@mtrob.fdns.net)
- *                    Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- *  03-20-2000  SJH     Created
- *  03-26-2000  SJH     Added flags for serial ports
- *  03-27-2000  SJH     Corrected BASE_BAUD value
- *  04-14-2000  RS      Made register addr dependent on IO_BASE
- *  05-03-2000  SJH     Complete rewrite
- *  05-09-2000	SJH	Stripped out architecture specific serial stuff
- *                      and placed it in a separate file
- *  07-28-2000	SJH	Moved base baud rate variable
- */
-#ifndef __ASM_ARCH_SERIAL_H
-#define __ASM_ARCH_SERIAL_H
-
-/*
- * This assumes you have a 3.6864 MHz clock for your UART.
- */
-#define BASE_BAUD	3686400
-
-/*
- * Standard COM flags
- */
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-#define STD_SERIAL_PORT_DEFNS		\
-	/* MAGIC UART CLK   PORT       IRQ     FLAGS */			\
-	{ 0, BASE_BAUD, UART1_BASE, IRQ_UART_1, STD_COM_FLAGS },  /* ttyLU0 */ \
-	{ 0, BASE_BAUD, UART2_BASE, IRQ_UART_2, STD_COM_FLAGS },  /* ttyLU1 */ \
-
-#define EXTRA_SERIAL_PORT_DEFNS
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/serial_l7200.h b/arch/arm/mach-l7200/include/mach/serial_l7200.h
deleted file mode 100644
index 645f1c5..0000000
--- a/arch/arm/mach-l7200/include/mach/serial_l7200.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/serial_l7200.h
- *
- * Copyright (c) 2000 Steven Hill (sjhill@cotw.com)
- *
- * Changelog:
- *  05-09-2000	SJH	Created
- */
-#ifndef __ASM_ARCH_SERIAL_L7200_H
-#define __ASM_ARCH_SERIAL_L7200_H
-
-#include <mach/memory.h>
-
-/*
- * This assumes you have a 3.6864 MHz clock for your UART.
- */
-#define BASE_BAUD 3686400
-
-/*
- * UART base register addresses
- */
-#define UART1_BASE	(IO_BASE + 0x00044000)
-#define UART2_BASE	(IO_BASE + 0x00045000)
-
-/*
- * UART register offsets
- */
-#define UARTDR			0x00	/* Tx/Rx data */
-#define RXSTAT			0x04	/* Rx status */
-#define H_UBRLCR		0x08	/* mode register high */
-#define M_UBRLCR		0x0C	/* mode reg mid (MSB of baud)*/
-#define L_UBRLCR		0x10	/* mode reg low (LSB of baud)*/
-#define UARTCON			0x14	/* control register */
-#define UARTFLG			0x18	/* flag register */
-#define UARTINTSTAT		0x1C	/* FIFO IRQ status register */
-#define UARTINTMASK		0x20	/* FIFO IRQ mask register */
-
-/*
- * UART baud rate register values
- */
-#define BR_110			0x827
-#define BR_1200			0x06e
-#define BR_2400			0x05f
-#define BR_4800			0x02f
-#define BR_9600			0x017
-#define BR_14400		0x00f
-#define BR_19200		0x00b
-#define BR_38400		0x005
-#define BR_57600		0x003
-#define BR_76800 		0x002
-#define BR_115200		0x001
-
-/*
- * Receiver status register (RXSTAT) mask values
- */
-#define RXSTAT_NO_ERR		0x00	/* No error */
-#define RXSTAT_FRM_ERR		0x01	/* Framing error */
-#define RXSTAT_PAR_ERR		0x02	/* Parity error */
-#define RXSTAT_OVR_ERR		0x04	/* Overrun error */
-
-/*
- * High byte of UART bit rate and line control register (H_UBRLCR) values
- */
-#define UBRLCR_BRK		0x01	/* generate break on tx */
-#define UBRLCR_PEN		0x02	/* enable parity */
-#define UBRLCR_PDIS		0x00	/* disable parity */
-#define UBRLCR_EVEN		0x04	/* 1= even parity,0 = odd parity */
-#define UBRLCR_STP2		0x08	/* transmit 2 stop bits */
-#define UBRLCR_FIFO		0x10	/* enable FIFO */
-#define UBRLCR_LEN5		0x60	/* word length5 */
-#define UBRLCR_LEN6		0x40	/* word length6 */
-#define UBRLCR_LEN7		0x20	/* word length7 */
-#define UBRLCR_LEN8		0x00	/* word length8 */
-
-/*
- * UART control register (UARTCON) values
- */
-#define UARTCON_UARTEN		0x01	/* Enable UART */
-#define UARTCON_DMAONERR	0x08	/* Mask RxDmaRq when errors occur */
-
-/*
- * UART flag register (UARTFLG) mask values
- */
-#define UARTFLG_UTXFF		0x20	/* Transmit FIFO full */
-#define UARTFLG_URXFE		0x10	/* Receiver FIFO empty */
-#define UARTFLG_UBUSY		0x08	/* Transmitter busy */
-#define UARTFLG_DCD		0x04	/* Data carrier detect */
-#define UARTFLG_DSR		0x02	/* Data set ready */
-#define UARTFLG_CTS		0x01	/* Clear to send */
-
-/*
- * UART interrupt status/clear registers (UARTINTSTAT/CLR) values
- */
-#define UART_TXINT		0x01	/* TX interrupt */
-#define UART_RXINT		0x02	/* RX interrupt */
-#define UART_RXERRINT		0x04	/* RX error interrupt */
-#define UART_MSINT		0x08	/* Modem Status interrupt */
-#define UART_UDINT		0x10	/* UART Disabled interrupt */
-#define UART_ALLIRQS		0x1f	/* All interrupts */
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/sib.h b/arch/arm/mach-l7200/include/mach/sib.h
deleted file mode 100644
index 9657287..0000000
--- a/arch/arm/mach-l7200/include/mach/sib.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************/
-/*
- *  arch/arm/mach-l7200/include/mach/sib.h
- *
- *  Registers and helper functions for the Serial Interface Bus.
- *
- *  (C) Copyright 2000, S A McConnell  (samcconn@cotw.com)
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-/****************************************************************************/
-
-#define SIB_OFF   0x00040000  /* Offset from IO_START to the SIB reg's. */
-
-/* IO_START and IO_BASE are defined in hardware.h */
-
-#define SIB_START (IO_START + SIB_OFF) /* Physical addr of the SIB reg. */
-#define SIB_BASE  (IO_BASE  + SIB_OFF) /* Virtual addr of the SIB reg.  */
-
-/* Offsets from the start of the SIB for all the registers. */
-
-/* Define the SIB registers for use by device drivers and the kernel. */
-
-typedef struct
-{
-     unsigned int MCCR;    /* SIB Control Register           Offset: 0x00 */
-     unsigned int RES1;    /* Reserved                       Offset: 0x04 */
-     unsigned int MCDR0;   /* SIB Data Register 0            Offset: 0x08 */
-     unsigned int MCDR1;   /* SIB Data Register 1            Offset: 0x0c */
-     unsigned int MCDR2;   /* SIB Data Register 2 (UCB1x00)  Offset: 0x10 */
-     unsigned int RES2;    /* Reserved                       Offset: 0x14 */
-     unsigned int MCSR;    /* SIB Status Register            Offset: 0x18 */
-} SIB_Interface;
-
-#define SIB ((volatile SIB_Interface *) (SIB_BASE))
-
-/* MCCR */
-
-#define INTERNAL_FREQ   9216000  /* Hertz */
-#define AUDIO_FREQ         5000  /* Hertz */
-#define TELECOM_FREQ       5000  /* Hertz */
-
-#define AUDIO_DIVIDE    (INTERNAL_FREQ / (32 * AUDIO_FREQ))
-#define TELECOM_DIVIDE  (INTERNAL_FREQ / (32 * TELECOM_FREQ))
-
-#define MCCR_ASD57      AUDIO_DIVIDE
-#define MCCR_TSD57      (TELECOM_DIVIDE << 8)
-#define MCCR_MCE        (1 << 16)             /* SIB enable */
-#define MCCR_ECS        (1 << 17)             /* External Clock Select */
-#define MCCR_ADM        (1 << 18)             /* A/D Data Sampling */
-#define MCCR_PMC        (1 << 26)             /* PIN Multiplexer Control */
-
-
-#define GET_ASD ((SIB->MCCR >>  0) & 0x3f) /* Audio Sample Rate Div. */
-#define GET_TSD ((SIB->MCCR >>  8) & 0x3f) /* Telcom Sample Rate Div. */
-#define GET_MCE ((SIB->MCCR >> 16) & 0x01) /* SIB Enable */
-#define GET_ECS ((SIB->MCCR >> 17) & 0x01) /* External Clock Select */
-#define GET_ADM ((SIB->MCCR >> 18) & 0x01) /* A/D Data Sampling Mode */
-#define GET_TTM ((SIB->MCCR >> 19) & 0x01) /* Telco Trans. FIFO I mask */ 
-#define GET_TRM ((SIB->MCCR >> 20) & 0x01) /* Telco Recv. FIFO I mask */
-#define GET_ATM ((SIB->MCCR >> 21) & 0x01) /* Audio Trans. FIFO I mask */ 
-#define GET_ARM ((SIB->MCCR >> 22) & 0x01) /* Audio Recv. FIFO I mask */
-#define GET_LBM ((SIB->MCCR >> 23) & 0x01) /* Loop Back Mode */
-#define GET_ECP ((SIB->MCCR >> 24) & 0x03) /* Extern. Clck Prescale sel */
-#define GET_PMC ((SIB->MCCR >> 26) & 0x01) /* PIN Multiplexer Control */
-#define GET_ERI ((SIB->MCCR >> 27) & 0x01) /* External Read Interrupt */
-#define GET_EWI ((SIB->MCCR >> 28) & 0x01) /* External Write Interrupt */
-
-/* MCDR0 */
-
-#define AUDIO_RECV     ((SIB->MCDR0 >> 4) & 0xfff)
-#define AUDIO_WRITE(v) ((SIB->MCDR0 = (v & 0xfff) << 4))
-
-/* MCDR1 */
-
-#define TELECOM_RECV     ((SIB->MCDR1 >> 2) & 032fff)
-#define TELECOM_WRITE(v) ((SIB->MCDR1 = (v & 0x3fff) << 2))
-
-
-/* MCSR */
-
-#define MCSR_ATU (1 << 4)  /* Audio Transmit FIFO Underrun */
-#define MCSR_ARO (1 << 5)  /* Audio Receive  FIFO Underrun */
-#define MCSR_TTU (1 << 6)  /* TELECOM Transmit FIFO Underrun */
-#define MCSR_TRO (1 << 7)  /* TELECOM Receive  FIFO Underrun */
-
-#define MCSR_CLEAR_UNDERUN_BITS (MCSR_ATU | MCSR_ARO | MCSR_TTU | MCSR_TRO)
-
-
-#define GET_ATS ((SIB->MCSR >>  0) & 0x01) /* Audio Transmit FIFO Service Req*/
-#define GET_ARS ((SIB->MCSR >>  1) & 0x01) /* Audio Recv FIFO Service Request*/
-#define GET_TTS ((SIB->MCSR >>  2) & 0x01) /* TELECOM Transmit FIFO  Flag */
-#define GET_TRS ((SIB->MCSR >>  3) & 0x01) /* TELECOM Recv FIFO Service Req. */
-#define GET_ATU ((SIB->MCSR >>  4) & 0x01) /* Audio Transmit FIFO Underrun */
-#define GET_ARO ((SIB->MCSR >>  5) & 0x01) /* Audio Receive  FIFO Underrun */
-#define GET_TTU ((SIB->MCSR >>  6) & 0x01) /* TELECOM Transmit FIFO Underrun */
-#define GET_TRO ((SIB->MCSR >>  7) & 0x01) /* TELECOM Receive  FIFO Underrun */
-#define GET_ANF ((SIB->MCSR >>  8) & 0x01) /* Audio Transmit FIFO not full */
-#define GET_ANE ((SIB->MCSR >>  9) & 0x01) /* Audio Receive FIFO not empty */
-#define GET_TNF ((SIB->MCSR >> 10) & 0x01) /* Telecom Transmit FIFO not full */
-#define GET_TNE ((SIB->MCSR >> 11) & 0x01) /* Telecom Receive FIFO not empty */
-#define GET_CWC ((SIB->MCSR >> 12) & 0x01) /* Codec Write Complete */
-#define GET_CRC ((SIB->MCSR >> 13) & 0x01) /* Codec Read Complete */
-#define GET_ACE ((SIB->MCSR >> 14) & 0x01) /* Audio Codec Enabled */
-#define GET_TCE ((SIB->MCSR >> 15) & 0x01) /* Telecom Codec Enabled */
-
-/* MCDR2 */
-
-#define MCDR2_rW               (1 << 16)
-
-#define WRITE_MCDR2(reg, data) (SIB->MCDR2 =((reg<<17)|MCDR2_rW|(data&0xffff)))
-#define MCDR2_WRITE_COMPLETE   GET_CWC
-
-#define INITIATE_MCDR2_READ(reg) (SIB->MCDR2 = (reg << 17))
-#define MCDR2_READ_COMPLETE      GET_CRC
-#define MCDR2_READ               (SIB->MCDR2 & 0xffff)
diff --git a/arch/arm/mach-l7200/include/mach/sys-clock.h b/arch/arm/mach-l7200/include/mach/sys-clock.h
deleted file mode 100644
index e9729a3..0000000
--- a/arch/arm/mach-l7200/include/mach/sys-clock.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************/
-/*
- *  arch/arm/mach-l7200/include/mach/sys-clock.h
- *
- *   Registers and  helper functions for the L7200 Link-Up Systems
- *   System clocks.
- *
- *   (C) Copyright 2000, S A McConnell  (samcconn@cotw.com)
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-/****************************************************************************/
-
-#define SYS_CLOCK_OFF   0x00050030  /* Offset from IO_START. */
-
-/* IO_START and IO_BASE are defined in hardware.h */
-
-#define SYS_CLOCK_START (IO_START + SYS_CLOCK_OFF)  /* Physical address */
-#define SYS_CLOCK_BASE  (IO_BASE  + SYS_CLOCK_OFF)  /* Virtual address  */
-
-/* Define the interface to the SYS_CLOCK */
-
-typedef struct
-{
-     unsigned int ENABLE;
-     unsigned int ESYNC;
-     unsigned int SELECT;
-} sys_clock_interface;
-
-#define SYS_CLOCK   ((volatile sys_clock_interface *)(SYS_CLOCK_BASE))
-
-//#define CLOCK_EN    (*(volatile unsigned long *)(PMU_BASE+CLOCK_EN_OFF))
-//#define CLOCK_ESYNC (*(volatile unsigned long *)(PMU_BASE+CLOCK_ESYNC_OFF))
-//#define CLOCK_SEL   (*(volatile unsigned long *)(PMU_BASE+CLOCK_SEL_OFF))
-
-/* SYS_CLOCK -> ENABLE */
-
-#define SYN_EN          1<<0
-#define B18M_EN         1<<1
-#define CLK3M6_EN       1<<2
-#define BUART_EN        1<<3
-#define CLK18MU_EN      1<<4
-#define FIR_EN          1<<5
-#define MIRN_EN         1<<6
-#define UARTM_EN        1<<7
-#define SIBADC_EN       1<<8
-#define ALTD_EN         1<<9
-#define CLCLK_EN        1<<10
-
-/* SYS_CLOCK -> SELECT */
-
-#define CLK18M_DIV      1<<0
-#define MIR_SEL         1<<1
-#define SSP_SEL         1<<4
-#define MM_DIV          1<<5
-#define MM_SEL          1<<6
-#define ADC_SEL_2       0<<7
-#define ADC_SEL_4       1<<7
-#define ADC_SEL_8       3<<7
-#define ADC_SEL_16      7<<7
-#define ADC_SEL_32      0x0f<<7
-#define ADC_SEL_64      0x1f<<7
-#define ADC_SEL_128     0x3f<<7
-#define ALTD_SEL        1<<13
diff --git a/arch/arm/mach-l7200/include/mach/system.h b/arch/arm/mach-l7200/include/mach/system.h
deleted file mode 100644
index e0dd3b6..0000000
--- a/arch/arm/mach-l7200/include/mach/system.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/system.h
- *
- * Copyright (c) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog
- *  03-21-2000  SJH	Created
- *  04-26-2000  SJH	Fixed functions
- *  05-03-2000  SJH	Removed usage of obsolete 'iomd.h'
- *  05-31-2000  SJH	Properly implemented 'arch_idle'
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <mach/hardware.h>
-
-static inline void arch_idle(void)
-{
-	*(unsigned long *)(IO_BASE + 0x50004) = 1;	/* idle mode */
-}
-
-static inline void arch_reset(char mode, const char *cmd)
-{
-	if (mode == 's') {
-		cpu_reset(0);
-	}
-}
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/time.h b/arch/arm/mach-l7200/include/mach/time.h
deleted file mode 100644
index 061771c..0000000
--- a/arch/arm/mach-l7200/include/mach/time.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/time.h
- *
- * Copyright (C) 2000 Rob Scott (rscott@mtrob.fdns.net)
- *                    Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- *   01-02-2000	RS	Created l7200 version, derived from rpc code
- *   05-03-2000	SJH	Complete rewrite
- */
-#ifndef _ASM_ARCH_TIME_H
-#define _ASM_ARCH_TIME_H
-
-#include <mach/irqs.h>
-
-/*
- * RTC base register address
- */
-#define RTC_BASE	(IO_BASE_2 + 0x2000)
-
-/*
- * RTC registers
- */
-#define RTC_RTCDR	(*(volatile unsigned char *) (RTC_BASE + 0x000))
-#define RTC_RTCMR	(*(volatile unsigned char *) (RTC_BASE + 0x004))
-#define RTC_RTCS	(*(volatile unsigned char *) (RTC_BASE + 0x008))
-#define RTC_RTCC	(*(volatile unsigned char *) (RTC_BASE + 0x008))
-#define RTC_RTCDV	(*(volatile unsigned char *) (RTC_BASE + 0x00c))
-#define RTC_RTCCR	(*(volatile unsigned char *) (RTC_BASE + 0x010))
-
-/*
- * RTCCR register values
- */
-#define RTC_RATE_32	0x00      /* 32 Hz tick */
-#define RTC_RATE_64	0x10      /* 64 Hz tick */
-#define RTC_RATE_128	0x20      /* 128 Hz tick */
-#define RTC_RATE_256	0x30      /* 256 Hz tick */
-#define RTC_EN_ALARM	0x01      /* Enable alarm */
-#define RTC_EN_TIC	0x04      /* Enable counter */
-#define RTC_EN_STWDOG	0x08      /* Enable watchdog */
-
-/*
- * Handler for RTC timer interrupt
- */
-static irqreturn_t
-timer_interrupt(int irq, void *dev_id)
-{
-	struct pt_regs *regs = get_irq_regs();
-	do_timer(1);
-#ifndef CONFIG_SMP
-	update_process_times(user_mode(regs));
-#endif
-	do_profile(regs);
-	RTC_RTCC = 0;				/* Clear interrupt */
-
-	return IRQ_HANDLED;
-}
-
-/*
- * Set up RTC timer interrupt, and return the current time in seconds.
- */
-void __init time_init(void)
-{
-	RTC_RTCC = 0;				/* Clear interrupt */
-
-	timer_irq.handler = timer_interrupt;
-
-	setup_irq(IRQ_RTC_TICK, &timer_irq);
-
-	RTC_RTCCR = RTC_RATE_128 | RTC_EN_TIC;	/* Set rate and enable timer */
-}
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/timex.h b/arch/arm/mach-l7200/include/mach/timex.h
deleted file mode 100644
index ffc96a6..0000000
--- a/arch/arm/mach-l7200/include/mach/timex.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/timex.h
- *
- * Copyright (C) 2000 Rob Scott (rscott@mtrob.fdns.net)
- *                    Steve Hill (sjhill@cotw.com)
- *
- * 04-21-2000  RS Created file
- * 05-03-2000 SJH Tick rate was wrong
- *
- */
-
-/*
- * On the ARM720T, clock ticks are set to 128 Hz.
- *
- * NOTE: The actual RTC value is set in 'time.h' which
- *       must be changed when choosing a different tick
- *       rate. The value of HZ in 'param.h' must also
- *       be changed to match below.
- */
-#define CLOCK_TICK_RATE		128
diff --git a/arch/arm/mach-l7200/include/mach/uncompress.h b/arch/arm/mach-l7200/include/mach/uncompress.h
deleted file mode 100644
index 591c962..0000000
--- a/arch/arm/mach-l7200/include/mach/uncompress.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/uncompress.h
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- *  05-01-2000	SJH	Created
- *  05-13-2000	SJH	Filled in function bodies
- *  07-26-2000	SJH	Removed hard coded baud rate
- */
-
-#include <mach/hardware.h>
-
-#define IO_UART  IO_START + 0x00044000
-
-#define __raw_writeb(v,p)	(*(volatile unsigned char *)(p) = (v))
-#define __raw_readb(p)		(*(volatile unsigned char *)(p))
-
-static inline void putc(int c)
-{
-	while(__raw_readb(IO_UART + 0x18) & 0x20 ||
-	      __raw_readb(IO_UART + 0x18) & 0x08)
-		barrier();
-
-	__raw_writeb(c, IO_UART + 0x00);
-}
-
-static inline void flush(void)
-{
-}
-
-static __inline__ void arch_decomp_setup(void)
-{
-	__raw_writeb(0x00, IO_UART + 0x08);	/* Set HSB */
-	__raw_writeb(0x00, IO_UART + 0x20);	/* Disable IRQs */
-	__raw_writeb(0x01, IO_UART + 0x14);	/* Enable UART */
-}
-
-#define arch_decomp_wdog()
diff --git a/arch/arm/mach-l7200/include/mach/vmalloc.h b/arch/arm/mach-l7200/include/mach/vmalloc.h
deleted file mode 100644
index 85f0abb..0000000
--- a/arch/arm/mach-l7200/include/mach/vmalloc.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/vmalloc.h
- */
-#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
diff --git a/arch/arm/mach-lh7a40x/include/mach/memory.h b/arch/arm/mach-lh7a40x/include/mach/memory.h
index 189d20e..edb8f5f 100644
--- a/arch/arm/mach-lh7a40x/include/mach/memory.h
+++ b/arch/arm/mach-lh7a40x/include/mach/memory.h
@@ -19,50 +19,6 @@
  */
 #define PHYS_OFFSET	UL(0xc0000000)
 
-#ifdef CONFIG_DISCONTIGMEM
-
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-
-# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
-#  define KVADDR_TO_NID(addr) \
-  (  ((((unsigned long) (addr) - PAGE_OFFSET) >> 24) &  1)\
-   | ((((unsigned long) (addr) - PAGE_OFFSET) >> 25) & ~1))
-# else  /* 2 banks per node */
-#  define KVADDR_TO_NID(addr) \
-      (((unsigned long) (addr) - PAGE_OFFSET) >> 26)
-# endif
-
-/*
- * Given a page frame number, convert it to a node id.
- */
-
-# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
-#  define PFN_TO_NID(pfn) \
-  (((((pfn) - PHYS_PFN_OFFSET) >> (24 - PAGE_SHIFT)) &  1)\
- | ((((pfn) - PHYS_PFN_OFFSET) >> (25 - PAGE_SHIFT)) & ~1))
-# else  /* 2 banks per node */
-#  define PFN_TO_NID(pfn) \
-    (((pfn) - PHYS_PFN_OFFSET) >> (26 - PAGE_SHIFT))
-#endif
-
-/*
- * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
- * and returns the index corresponding to the appropriate page in the
- * node's mem_map.
- */
-
-# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
-#  define LOCAL_MAP_NR(addr) \
-       (((unsigned long)(addr) & 0x003fffff) >> PAGE_SHIFT)
-# else  /* 2 banks per node */
-#  define LOCAL_MAP_NR(addr) \
-       (((unsigned long)(addr) & 0x01ffffff) >> PAGE_SHIFT)
-# endif
-
-#endif
-
 /*
  * Sparsemem version of the above
  */
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c
index dca5a5f..e69a150 100644
--- a/arch/arm/mach-msm/board-trout.c
+++ b/arch/arm/mach-msm/board-trout.c
@@ -50,7 +50,6 @@
 {
 	mi->nr_banks = 1;
 	mi->bank[0].start = PHYS_OFFSET;
-	mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
 	mi->bank[0].size = (101*1024*1024);
 }
 
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c
index f035f41..89f793a 100644
--- a/arch/arm/mach-nomadik/clock.c
+++ b/arch/arm/mach-nomadik/clock.c
@@ -53,6 +53,10 @@
 	}
 
 static struct clk_lookup lookups[] = {
+	{
+		.con_id		= "apb_pclk",
+		.clk		= &clk_default,
+	},
 	CLK(&clk_24, "mtu0"),
 	CLK(&clk_24, "mtu1"),
 	CLK(&clk_48, "uart0"),
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index fdd1dd5..0a9d61d 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -301,6 +301,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= ams_delta_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= ams_delta_init_irq,
 	.init_machine	= ams_delta_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 096f2ed..059bac6 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -378,6 +378,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_fsample_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_fsample_init_irq,
 	.init_machine	= omap_fsample_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index e1195a3..7a65684 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -98,6 +98,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_generic_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_generic_init_irq,
 	.init_machine	= omap_generic_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index d1100e4..68b2bed 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -467,6 +467,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= h2_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= h2_init_irq,
 	.init_machine	= h2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index a53ab82..0b0825f 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -437,6 +437,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= h3_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= h3_init_irq,
 	.init_machine	= h3_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 8e313b4..d70a4f0 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -304,6 +304,7 @@
 	.io_pg_offst    = ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params    = 0x10000100,
 	.map_io         = htcherald_map_io,
+	.reserve	= omap_reserve,
 	.init_irq       = htcherald_init_irq,
 	.init_machine   = htcherald_init,
 	.timer          = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 5d12fd3..91064b3 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -463,6 +463,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= innovator_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= innovator_init_irq,
 	.init_machine	= innovator_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 71e1a3f..8c28b10f 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -400,6 +400,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_nokia770_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_nokia770_init_irq,
 	.init_machine	= omap_nokia770_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 80d8620..e2a72af 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -584,6 +584,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= osk_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= osk_init_irq,
 	.init_machine	= osk_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 569b4c9..61a2321 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -373,6 +373,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_palmte_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_palmte_init_irq,
 	.init_machine	= omap_palmte_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 6ad49a2..21c01c6 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -321,6 +321,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_palmtt_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_palmtt_init_irq,
 	.init_machine	= omap_palmtt_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 6641de9..f324924 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -338,10 +338,12 @@
 }
 
 MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
-	.phys_io = 0xfff00000,
-	.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
-	.boot_params = 0x10000100,.map_io = omap_palmz71_map_io,
-	.init_irq = omap_palmz71_init_irq,
-	.init_machine = omap_palmz71_init,
-	.timer = &omap_timer,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_palmz71_map_io,
+	.reserve	= omap_reserve,
+	.init_irq	= omap_palmz71_init_irq,
+	.init_machine	= omap_palmz71_init,
+	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index e854d57..8b5ab1f 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -339,6 +339,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_perseus2_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_perseus2_init_irq,
 	.init_machine	= omap_perseus2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 2fb1e5f..995566b 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -423,7 +423,8 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= omap_sx1_map_io,
-	.init_irq		= omap_sx1_init_irq,
+	.reserve	= omap_reserve,
+	.init_irq	= omap_sx1_init_irq,
 	.init_machine	= omap_sx1_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 87b9436..4c483dc 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -287,6 +287,7 @@
 	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
 	.boot_params	= 0x10000100,
 	.map_io		= voiceblue_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= voiceblue_init_irq,
 	.init_machine	= voiceblue_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index d9b8d82..0ce3fec 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -22,7 +22,6 @@
 
 extern void omap_check_revision(void);
 extern void omap_sram_init(void);
-extern void omapfb_reserve_sdram(void);
 
 /*
  * The machine specific code may provide the extra mapping besides the
@@ -122,7 +121,6 @@
 #endif
 
 	omap_sram_init();
-	omapfb_reserve_sdram();
 }
 
 /*
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index a11a575..42f49f7 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -248,6 +248,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_2430sdp_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_2430sdp_init_irq,
 	.init_machine	= omap_2430sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index f474a80..dd9c031 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -815,6 +815,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_3430sdp_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_3430sdp_init_irq,
 	.init_machine	= omap_3430sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 504d2bd..57290fb 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -108,6 +108,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_sdp_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_sdp_init_irq,
 	.init_machine	= omap_sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index e4a5d66..4bb2c5d 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -402,6 +402,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_4430sdp_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_4430sdp_init_irq,
 	.init_machine	= omap_4430sdp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index af383a8..7da92de 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -472,6 +472,7 @@
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= am3517_evm_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= am3517_evm_init_irq,
 	.init_machine	= am3517_evm_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index aa69fb9..bd75642 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -346,6 +346,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_apollon_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_apollon_init_irq,
 	.init_machine	= omap_apollon_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index e679a2c..bc4c3f8 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -837,6 +837,7 @@
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= cm_t35_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= cm_t35_init_irq,
 	.init_machine	= cm_t35_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 77022b5..922b746 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -825,6 +825,7 @@
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= devkit8000_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= devkit8000_init_irq,
 	.init_machine	= devkit8000_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 16cc068..9242902 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -59,6 +59,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_generic_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_generic_init_irq,
 	.init_machine	= omap_generic_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 0665f2c..16703fd 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -378,6 +378,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_h4_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_h4_init_irq,
 	.init_machine	= omap_h4_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index d55c57b..759e39d 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -543,6 +543,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= igep2_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= igep2_init_irq,
 	.init_machine	= igep2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index fefd7e6..9cd2669 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -417,6 +417,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_ldp_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_ldp_init_irq,
 	.init_machine	= omap_ldp_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 3ccc34e..2565ff0 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -667,6 +667,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= n8x0_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= n8x0_init_irq,
 	.init_machine	= n8x0_init_machine,
 	.timer		= &omap_timer,
@@ -677,6 +678,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= n8x0_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= n8x0_init_irq,
 	.init_machine	= n8x0_init_machine,
 	.timer		= &omap_timer,
@@ -687,6 +689,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= n8x0_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= n8x0_init_irq,
 	.init_machine	= n8x0_init_machine,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 69b154c..0ab0c26 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -519,6 +519,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_beagle_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap3_beagle_init_irq,
 	.init_machine	= omap3_beagle_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index b952610..a3d2e28 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -727,6 +727,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_evm_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap3_evm_init_irq,
 	.init_machine	= omap3_evm_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index db06dc9..c0f4f12 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -601,6 +601,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3pandora_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap3pandora_init_irq,
 	.init_machine	= omap3pandora_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 2f5f823..f05b867 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -571,6 +571,7 @@
 	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap3_touchbook_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap3_touchbook_init_irq,
 	.init_machine	= omap3_touchbook_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 79ac414..87acb2f 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -495,6 +495,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= overo_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= overo_init_irq,
 	.init_machine	= overo_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 1b86b5b..3bd956f 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -154,6 +154,7 @@
 	.io_pg_offst	= ((0xfa000000) >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= rx51_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= rx51_init_irq,
 	.init_machine	= rx51_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 803ef14..ffe188c 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -95,6 +95,7 @@
 	.io_pg_offst	= (ZOOM_UART_VIRT >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_zoom2_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_zoom2_init_irq,
 	.init_machine	= omap_zoom2_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
index 3314704..5b605eb 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -77,6 +77,7 @@
 	.io_pg_offst	= (ZOOM_UART_VIRT >> 18) & 0xfffc,
 	.boot_params	= 0x80000100,
 	.map_io		= omap_zoom_map_io,
+	.reserve	= omap_reserve,
 	.init_irq	= omap_zoom_init_irq,
 	.init_machine	= omap_zoom_init,
 	.timer		= &omap_timer,
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 41b155a..d337441 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3166,6 +3166,10 @@
 	.recalc		= &followparent_recalc,
 };
 
+static struct clk dummy_apb_pclk = {
+	.name		= "apb_pclk",
+	.ops		= &clkops_null,
+};
 
 /*
  * clkdev
@@ -3173,6 +3177,7 @@
 
 /* XXX At some point we should rename this file to clock3xxx_data.c */
 static struct omap_clk omap3xxx_clks[] = {
+	CLK(NULL,	"apb_pclk",	&dummy_apb_pclk,	CK_3XXX),
 	CLK(NULL,	"omap_32k_fck",	&omap_32k_fck,	CK_3XXX),
 	CLK(NULL,	"virt_12m_ck",	&virt_12m_ck,	CK_3XXX),
 	CLK(NULL,	"virt_13m_ck",	&virt_13m_ck,	CK_3XXX),
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 3cfb425..4e1f53d 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -33,7 +33,6 @@
 #include <plat/sdrc.h>
 #include <plat/gpmc.h>
 #include <plat/serial.h>
-#include <plat/vram.h>
 
 #include "clock2xxx.h"
 #include "clock3xxx.h"
@@ -241,8 +240,6 @@
 
 	omap2_check_revision();
 	omap_sram_init();
-	omapfb_reserve_sdram();
-	omap_vram_reserve_sdram();
 }
 
 #ifdef CONFIG_ARCH_OMAP2420
diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c
index 161fc2d..0f31305 100644
--- a/arch/arm/mach-pxa/cm-x2xx-pci.c
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.c
@@ -35,7 +35,7 @@
  * This is really ugly and we need a better way of specifying
  * DMA-capable regions of memory.
  */
-void __init cmx2xx_pci_adjust_zones(int node, unsigned long *zone_size,
+void __init cmx2xx_pci_adjust_zones(unsigned long *zone_size,
 	unsigned long *zhole_size)
 {
 	unsigned int sz = SZ_64M >> PAGE_SHIFT;
@@ -46,7 +46,7 @@
 		/*
 		 * Only adjust if > 64M on current system
 		 */
-		if (node || (zone_size[0] <= sz))
+		if (zone_size[0] <= sz)
 			return;
 
 		zone_size[1] = zone_size[0] - sz;
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 51ffa6a..461ba40 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -715,7 +715,6 @@
 	sharpsl_save_param();
 	mi->nr_banks=1;
 	mi->bank[0].start = 0xa0000000;
-	mi->bank[0].node = 0;
 	if (machine_is_corgi())
 		mi->bank[0].size = (32*1024*1024);
 	else
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index 96ed130..a0ab308 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -34,7 +34,6 @@
 {
 	mi->nr_banks=1;
 	mi->bank[0].start = 0xa0000000;
-	mi->bank[0].node = 0;
 	if (machine_is_e800())
 		mi->bank[0].size = (128*1024*1024);
 	else
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 890fb90..c6305c5 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -26,8 +26,7 @@
 
 #define SET_BANK(__nr,__start,__size) \
 	mi->bank[__nr].start = (__start), \
-	mi->bank[__nr].size = (__size), \
-	mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
+	mi->bank[__nr].size = (__size)
 
 #define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
 
diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h
index f626730..92361a6 100644
--- a/arch/arm/mach-pxa/include/mach/memory.h
+++ b/arch/arm/mach-pxa/include/mach/memory.h
@@ -17,24 +17,11 @@
  */
 #define PHYS_OFFSET	UL(0xa0000000)
 
-/*
- * The nodes are matched with the physical SDRAM banks as follows:
- *
- * 	node 0:  0xa0000000-0xa3ffffff	-->  0xc0000000-0xc3ffffff
- * 	node 1:  0xa4000000-0xa7ffffff	-->  0xc4000000-0xc7ffffff
- * 	node 2:  0xa8000000-0xabffffff	-->  0xc8000000-0xcbffffff
- * 	node 3:  0xac000000-0xafffffff	-->  0xcc000000-0xcfffffff
- *
- * This needs a node mem size of 26 bits.
- */
-#define NODE_MEM_SIZE_BITS	26
-
 #if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
-void cmx2xx_pci_adjust_zones(int node, unsigned long *size,
-			     unsigned long *holes);
+void cmx2xx_pci_adjust_zones(unsigned long *size, unsigned long *holes);
 
-#define arch_adjust_zones(node, size, holes) \
-	cmx2xx_pci_adjust_zones(node, size, holes)
+#define arch_adjust_zones(size, holes) \
+	cmx2xx_pci_adjust_zones(size, holes)
 
 #define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_64M - 1)
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_64M)
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 5305a39..5e92d84 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/memblock.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -396,6 +397,11 @@
 	}
 }
 
+static void __init palmt5_reserve(void)
+{
+	memblock_reserve(0xa0200000, 0x1000);
+}
+
 static void __init palmt5_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
@@ -421,6 +427,7 @@
 	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
 	.boot_params	= 0xa0000100,
 	.map_io		= pxa_map_io,
+	.reserve	= palmt5_reserve,
 	.init_irq	= pxa27x_init_irq,
 	.timer		= &pxa_timer,
 	.init_machine	= palmt5_init
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index d8b4469..3d0c9cc 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -20,6 +20,7 @@
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/memblock.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
@@ -633,6 +634,12 @@
 	treo_lcd_screen.pxafb_lcd_power = treo_lcd_power;
 }
 
+static void __init treo_reserve(void)
+{
+	memblock_reserve(0xa0000000, 0x1000);
+	memblock_reserve(0xa2000000, 0x1000);
+}
+
 static void __init treo_init(void)
 {
 	pxa_set_ffuart_info(NULL);
@@ -668,6 +675,7 @@
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
 	.init_machine   = treo680_init,
@@ -691,6 +699,7 @@
 	.io_pg_offst    = io_p2v(0x40000000),
 	.boot_params    = 0xa0000100,
 	.map_io         = pxa_map_io,
+	.reserve	= treo_reserve,
 	.init_irq       = pxa27x_init_irq,
 	.timer          = &pxa_timer,
        .init_machine   = centro_init,
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index f4abdaa..bc2758b 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -463,7 +463,6 @@
 	sharpsl_save_param();
 	mi->nr_banks=1;
 	mi->bank[0].start = 0xa0000000;
-	mi->bank[0].node = 0;
 	mi->bank[0].size = (32*1024*1024);
 }
 
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index c1048a3..51756c7 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -847,7 +847,6 @@
 	sharpsl_save_param();
 	mi->nr_banks = 1;
 	mi->bank[0].start = 0xa0000000;
-	mi->bank[0].node = 0;
 	mi->bank[0].size = (64*1024*1024);
 }
 
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 7512b82..83cc3a1 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -948,7 +948,6 @@
 	sharpsl_save_param();
 	mi->nr_banks=1;
 	mi->bank[0].start = 0xa0000000;
-	mi->bank[0].node = 0;
 	mi->bank[0].size = (64*1024*1024);
 }
 
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 595be19..a54fbda 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -61,12 +61,11 @@
 /*
  * Adjust the zones if there are restrictions for DMA access.
  */
-void __init realview_adjust_zones(int node, unsigned long *size,
-				  unsigned long *hole)
+void __init realview_adjust_zones(unsigned long *size, unsigned long *hole)
 {
 	unsigned long dma_size = SZ_256M >> PAGE_SHIFT;
 
-	if (!machine_is_realview_pbx() || node || (size[0] <= dma_size))
+	if (!machine_is_realview_pbx() || size[0] <= dma_size)
 		return;
 
 	size[ZONE_NORMAL] = size[0] - dma_size;
@@ -232,6 +231,21 @@
 	struct amba_device *adev = container_of(dev, struct amba_device, dev);
 	u32 mask;
 
+	if (machine_is_realview_pb1176()) {
+		static bool inserted = false;
+
+		/*
+		 * The PB1176 does not have the status register,
+		 * assume it is inserted at startup, then invert
+		 * for each call so card insertion/removal will
+		 * be detected anyway. This will not be called if
+		 * GPIO on PL061 is active, which is the proper
+		 * way to do this on the PB1176.
+		 */
+		inserted = !inserted;
+		return inserted ? 0 : 1;
+	}
+
 	if (adev->res.start == REALVIEW_MMCI0_BASE)
 		mask = 1;
 	else
@@ -300,8 +314,13 @@
 	.rate	= 24000000,
 };
 
+static struct clk dummy_apb_pclk;
+
 static struct clk_lookup lookups[] = {
-	{	/* UART0 */
+	{	/* Bus clock */
+		.con_id		= "apb_pclk",
+		.clk		= &dummy_apb_pclk,
+	}, {	/* UART0 */
 		.dev_id		= "dev:uart0",
 		.clk		= &ref24_clk,
 	}, {	/* UART1 */
@@ -313,6 +332,12 @@
 	}, {	/* UART3 */
 		.dev_id		= "fpga:uart3",
 		.clk		= &ref24_clk,
+	}, {	/* UART3 is on the dev chip in PB1176 */
+		.dev_id		= "dev:uart3",
+		.clk		= &ref24_clk,
+	}, {	/* UART4 only exists in PB1176 */
+		.dev_id		= "fpga:uart4",
+		.clk		= &ref24_clk,
 	}, {	/* KMI0 */
 		.dev_id		= "fpga:kmi0",
 		.clk		= &ref24_clk,
@@ -322,12 +347,15 @@
 	}, {	/* MMC0 */
 		.dev_id		= "fpga:mmc0",
 		.clk		= &ref24_clk,
-	}, {	/* EB:CLCD */
+	}, {	/* CLCD is in the PB1176 and EB DevChip */
 		.dev_id		= "dev:clcd",
 		.clk		= &oscvco_clk,
 	}, {	/* PB:CLCD */
 		.dev_id		= "issp:clcd",
 		.clk		= &oscvco_clk,
+	}, {	/* SSP */
+		.dev_id		= "dev:ssp0",
+		.clk		= &ref24_clk,
 	}
 };
 
@@ -342,7 +370,7 @@
 
 	return 0;
 }
-arch_initcall(clk_init);
+core_initcall(clk_init);
 
 /*
  * CLCD support.
diff --git a/arch/arm/mach-realview/include/mach/board-pb1176.h b/arch/arm/mach-realview/include/mach/board-pb1176.h
index 2f5ccb2..002ab5d 100644
--- a/arch/arm/mach-realview/include/mach/board-pb1176.h
+++ b/arch/arm/mach-realview/include/mach/board-pb1176.h
@@ -26,6 +26,7 @@
 /*
  * Peripheral addresses
  */
+#define REALVIEW_PB1176_UART4_BASE		0x10009000 /* UART 4 */
 #define REALVIEW_PB1176_SCTL_BASE		0x10100000 /* System controller */
 #define REALVIEW_PB1176_SMC_BASE		0x10111000 /* SMC */
 #define REALVIEW_PB1176_DMC_BASE		0x10109000 /* DMC configuration */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
index 830055b..5c3c625 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pb1176.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
@@ -40,6 +40,7 @@
 #define IRQ_DC1176_L2CC		(IRQ_DC1176_GIC_START + 13)
 #define IRQ_DC1176_RTC		(IRQ_DC1176_GIC_START + 14)
 #define IRQ_DC1176_CLCD		(IRQ_DC1176_GIC_START + 15)	/* CLCD controller */
+#define IRQ_DC1176_SSP		(IRQ_DC1176_GIC_START + 17)	/* SSP port */
 #define IRQ_DC1176_UART0	(IRQ_DC1176_GIC_START + 18)	/* UART 0 on development chip */
 #define IRQ_DC1176_UART1	(IRQ_DC1176_GIC_START + 19)	/* UART 1 on development chip */
 #define IRQ_DC1176_UART2	(IRQ_DC1176_GIC_START + 20)	/* UART 2 on development chip */
@@ -73,7 +74,6 @@
 #define IRQ_PB1176_RTC		(IRQ_PB1176_GIC_START + 25)	/* Real Time Clock */
 
 #define IRQ_PB1176_GPIO0	-1
-#define IRQ_PB1176_SSP		-1
 #define IRQ_PB1176_SCTL		-1
 
 #define NR_GIC_PB1176		2
diff --git a/arch/arm/mach-realview/include/mach/memory.h b/arch/arm/mach-realview/include/mach/memory.h
index 2417bbc..5dafc15 100644
--- a/arch/arm/mach-realview/include/mach/memory.h
+++ b/arch/arm/mach-realview/include/mach/memory.h
@@ -30,10 +30,9 @@
 #endif
 
 #if !defined(__ASSEMBLY__) && defined(CONFIG_ZONE_DMA)
-extern void realview_adjust_zones(int node, unsigned long *size,
-				  unsigned long *hole);
-#define arch_adjust_zones(node, size, hole) \
-	realview_adjust_zones(node, size, hole)
+extern void realview_adjust_zones(unsigned long *size, unsigned long *hole);
+#define arch_adjust_zones(size, hole) \
+	realview_adjust_zones(size, hole)
 
 #define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_256M - 1)
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_256M)
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 4425018..991c1f8 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -25,6 +25,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/pl061.h>
 #include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
@@ -129,6 +130,12 @@
 	.irq_base	= -1,
 };
 
+static struct pl022_ssp_controller ssp0_plat_data = {
+	.bus_id = 0,
+	.enable_dma = 0,
+	.num_chipselect = 1,
+};
+
 /*
  * RealView EB AMBA devices
  */
@@ -213,7 +220,7 @@
 AMBA_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
 AMBA_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
 AMBA_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
-AMBA_DEVICE(ssp0,  "dev:ssp0",  EB_SSP,   NULL);
+AMBA_DEVICE(ssp0,  "dev:ssp0",  EB_SSP,   &ssp0_plat_data);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&dmac_device,
@@ -324,6 +331,26 @@
 	.resource		= pmu_resources,
 };
 
+static struct resource char_lcd_resources[] = {
+	{
+		.start = REALVIEW_CHAR_LCD_BASE,
+		.end   = (REALVIEW_CHAR_LCD_BASE + SZ_4K - 1),
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_EB_CHARLCD,
+		.end	= IRQ_EB_CHARLCD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device char_lcd_device = {
+	.name		=	"arm-charlcd",
+	.id		=	-1,
+	.num_resources	=	ARRAY_SIZE(char_lcd_resources),
+	.resource	=	char_lcd_resources,
+};
+
 static void __init gic_init_irq(void)
 {
 	if (core_tile_eb11mp() || core_tile_a9mp()) {
@@ -442,6 +469,7 @@
 
 	realview_flash_register(&realview_eb_flash_resource, 1);
 	platform_device_register(&realview_i2c_device);
+	platform_device_register(&char_lcd_device);
 	eth_device_register();
 	realview_usb_register(realview_eb_isp1761_resources);
 
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 099a1f1..d2be12e 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -25,6 +25,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/pl061.h>
 #include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
@@ -123,6 +124,12 @@
 	.irq_base	= -1,
 };
 
+static struct pl022_ssp_controller ssp0_plat_data = {
+	.bus_id = 0,
+	.enable_dma = 0,
+	.num_chipselect = 1,
+};
+
 /*
  * RealView PB1176 AMBA devices
  */
@@ -144,8 +151,6 @@
 #define MPMC_DMA	{ 0, 0 }
 #define PB1176_CLCD_IRQ	{ IRQ_DC1176_CLCD, NO_IRQ }
 #define PB1176_CLCD_DMA	{ 0, 0 }
-#define DMAC_IRQ	{ IRQ_PB1176_DMAC, NO_IRQ }
-#define DMAC_DMA	{ 0, 0 }
 #define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
 #define SCTL_DMA	{ 0, 0 }
 #define PB1176_WATCHDOG_IRQ	{ IRQ_DC1176_WATCHDOG, NO_IRQ }
@@ -166,7 +171,9 @@
 #define PB1176_UART2_DMA	{ 11, 10 }
 #define PB1176_UART3_IRQ	{ IRQ_DC1176_UART3, NO_IRQ }
 #define PB1176_UART3_DMA	{ 0x86, 0x87 }
-#define PB1176_SSP_IRQ		{ IRQ_PB1176_SSP, NO_IRQ }
+#define PB1176_UART4_IRQ	{ IRQ_PB1176_UART4, NO_IRQ }
+#define PB1176_UART4_DMA	{ 0, 0 }
+#define PB1176_SSP_IRQ		{ IRQ_DC1176_SSP, NO_IRQ }
 #define PB1176_SSP_DMA		{ 9, 8 }
 
 /* FPGA Primecells */
@@ -174,7 +181,7 @@
 AMBA_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
 AMBA_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
 AMBA_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
-AMBA_DEVICE(uart3,	"fpga:uart3",	PB1176_UART3,	NULL);
+AMBA_DEVICE(uart4,	"fpga:uart4",	PB1176_UART4,	NULL);
 
 /* DevChip Primecells */
 AMBA_DEVICE(smc,	"dev:smc",	PB1176_SMC,	NULL);
@@ -188,18 +195,16 @@
 AMBA_DEVICE(uart0,	"dev:uart0",	PB1176_UART0,	NULL);
 AMBA_DEVICE(uart1,	"dev:uart1",	PB1176_UART1,	NULL);
 AMBA_DEVICE(uart2,	"dev:uart2",	PB1176_UART2,	NULL);
-AMBA_DEVICE(ssp0,	"dev:ssp0",	PB1176_SSP,	NULL);
-
-/* Primecells on the NEC ISSP chip */
-AMBA_DEVICE(clcd,	"issp:clcd",	PB1176_CLCD,	&clcd_plat_data);
-//AMBA_DEVICE(dmac,	"issp:dmac",	PB1176_DMAC,	NULL);
+AMBA_DEVICE(uart3,	"dev:uart3",	PB1176_UART3,	NULL);
+AMBA_DEVICE(ssp0,	"dev:ssp0",	PB1176_SSP,	&ssp0_plat_data);
+AMBA_DEVICE(clcd,	"dev:clcd",	PB1176_CLCD,	&clcd_plat_data);
 
 static struct amba_device *amba_devs[] __initdata = {
-//	&dmac_device,
 	&uart0_device,
 	&uart1_device,
 	&uart2_device,
 	&uart3_device,
+	&uart4_device,
 	&smc_device,
 	&clcd_device,
 	&sctl_device,
@@ -276,6 +281,26 @@
 	.resource		= &pmu_resource,
 };
 
+static struct resource char_lcd_resources[] = {
+	{
+		.start = REALVIEW_CHAR_LCD_BASE,
+		.end   = (REALVIEW_CHAR_LCD_BASE + SZ_4K - 1),
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_PB1176_CHARLCD,
+		.end	= IRQ_PB1176_CHARLCD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device char_lcd_device = {
+	.name		=	"arm-charlcd",
+	.id		=	-1,
+	.num_resources	=	ARRAY_SIZE(char_lcd_resources),
+	.resource	=	char_lcd_resources,
+};
+
 static void __init gic_init_irq(void)
 {
 	/* ARM1176 DevChip GIC, primary */
@@ -338,6 +363,7 @@
 	platform_device_register(&realview_i2c_device);
 	realview_usb_register(realview_pb1176_isp1761_resources);
 	platform_device_register(&pmu_device);
+	platform_device_register(&char_lcd_device);
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 0e07a5c..d591bc0 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -25,6 +25,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/pl061.h>
 #include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
@@ -124,6 +125,12 @@
 	.irq_base	= -1,
 };
 
+static struct pl022_ssp_controller ssp0_plat_data = {
+	.bus_id = 0,
+	.enable_dma = 0,
+	.num_chipselect = 1,
+};
+
 /*
  * RealView PB11MPCore AMBA devices
  */
@@ -190,7 +197,7 @@
 AMBA_DEVICE(uart0,	"dev:uart0",	PB11MP_UART0,	NULL);
 AMBA_DEVICE(uart1,	"dev:uart1",	PB11MP_UART1,	NULL);
 AMBA_DEVICE(uart2,	"dev:uart2",	PB11MP_UART2,	NULL);
-AMBA_DEVICE(ssp0,	"dev:ssp0",	PB11MP_SSP,	NULL);
+AMBA_DEVICE(ssp0,	"dev:ssp0",	PB11MP_SSP,	&ssp0_plat_data);
 
 /* Primecells on the NEC ISSP chip */
 AMBA_DEVICE(clcd,	"issp:clcd",	PB11MP_CLCD,	&clcd_plat_data);
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index ac2f06f..6c37621 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -25,6 +25,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/pl061.h>
 #include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
 #include <linux/io.h>
 
 #include <asm/irq.h>
@@ -114,6 +115,12 @@
 	.irq_base	= -1,
 };
 
+static struct pl022_ssp_controller ssp0_plat_data = {
+	.bus_id = 0,
+	.enable_dma = 0,
+	.num_chipselect = 1,
+};
+
 /*
  * RealView PBA8Core AMBA devices
  */
@@ -180,7 +187,7 @@
 AMBA_DEVICE(uart0,	"dev:uart0",	PBA8_UART0,	NULL);
 AMBA_DEVICE(uart1,	"dev:uart1",	PBA8_UART1,	NULL);
 AMBA_DEVICE(uart2,	"dev:uart2",	PBA8_UART2,	NULL);
-AMBA_DEVICE(ssp0,	"dev:ssp0",	PBA8_SSP,	NULL);
+AMBA_DEVICE(ssp0,	"dev:ssp0",	PBA8_SSP,	&ssp0_plat_data);
 
 /* Primecells on the NEC ISSP chip */
 AMBA_DEVICE(clcd,	"issp:clcd",	PBA8_CLCD,	&clcd_plat_data);
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 08fd683..9428eff 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -24,6 +24,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/pl061.h>
 #include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
 #include <linux/io.h>
 
 #include <asm/irq.h>
@@ -136,6 +137,12 @@
 	.irq_base	= -1,
 };
 
+static struct pl022_ssp_controller ssp0_plat_data = {
+	.bus_id = 0,
+	.enable_dma = 0,
+	.num_chipselect = 1,
+};
+
 /*
  * RealView PBXCore AMBA devices
  */
@@ -202,7 +209,7 @@
 AMBA_DEVICE(uart0,	"dev:uart0",	PBX_UART0,	NULL);
 AMBA_DEVICE(uart1,	"dev:uart1",	PBX_UART1,	NULL);
 AMBA_DEVICE(uart2,	"dev:uart2",	PBX_UART2,	NULL);
-AMBA_DEVICE(ssp0,	"dev:ssp0",	PBX_SSP,	NULL);
+AMBA_DEVICE(ssp0,	"dev:ssp0",	PBX_SSP,	&ssp0_plat_data);
 
 /* Primecells on the NEC ISSP chip */
 AMBA_DEVICE(clcd,	"issp:clcd",	PBX_CLCD,	&clcd_plat_data);
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 779b45b..3ba3bab 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/memblock.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
@@ -304,6 +305,13 @@
 	s3c_pm_init();
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init h1940_reserve(void)
+{
+	memblock_reserve(0x30003000, 0x1000);
+	memblock_reserve(0x30081000, 0x1000);
+}
+
 static void __init h1940_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -346,6 +354,7 @@
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= h1940_map_io,
+	.reserve	= h1940_reserve,
 	.init_irq	= h1940_init_irq,
 	.init_machine	= h1940_init,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index ba93a35..054c9f9 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -119,7 +119,6 @@
 		mi->nr_banks=1;
 		mi->bank[0].start = 0x30000000;
 		mi->bank[0].size = SZ_64M;
-		mi->bank[0].node = 0;
 	}
 }
 
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
index 3ca9265..f291ac2 100644
--- a/arch/arm/mach-s3c2412/mach-vstms.c
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -137,7 +137,6 @@
 		mi->nr_banks=1;
 		mi->bank[0].start = 0x30000000;
 		mi->bank[0].size = SZ_64M;
-		mi->bank[0].node = 0;
 	}
 }
 
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 8603b57..142d1f9 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/memblock.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
 #include <linux/init.h>
@@ -570,12 +571,20 @@
 	platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx1950_reserve(void)
+{
+	memblock_reserve(0x30003000, 0x1000);
+	memblock_reserve(0x30081000, 0x1000);
+}
+
 MACHINE_START(RX1950, "HP iPAQ RX1950")
     /* Maintainers: Vasily Khoruzhick */
     .phys_io = S3C2410_PA_UART,
 	.io_pg_offst = (((u32) S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params = S3C2410_SDRAM_PA + 0x100,
 	.map_io = rx1950_map_io,
+	.reserve	= rx1950_reserve,
 	.init_irq = s3c24xx_init_irq,
 	.init_machine = rx1950_init_machine,
 	.timer = &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index d2946de..6bb44f7 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/memblock.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/tty.h>
@@ -191,6 +192,13 @@
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 }
 
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx3715_reserve(void)
+{
+	memblock_reserve(0x30003000, 0x1000);
+	memblock_reserve(0x30081000, 0x1000);
+}
+
 static void __init rx3715_init_irq(void)
 {
 	s3c24xx_init_irq();
@@ -214,6 +222,7 @@
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= rx3715_map_io,
+	.reserve	= rx3715_reserve,
 	.init_irq	= rx3715_init_irq,
 	.init_machine	= rx3715_init_machine,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index ec03f187..b7a9a60 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -13,8 +13,7 @@
 
 #define SET_BANK(__nr,__start,__size) \
 	mi->bank[__nr].start = (__start), \
-	mi->bank[__nr].size = (__size), \
-	mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
+	mi->bank[__nr].size = (__size)
 
 extern void (*sa1100fb_backlight_power)(int on);
 extern void (*sa1100fb_lcd_power)(int on);
diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h
index d5277f9..128a1df 100644
--- a/arch/arm/mach-sa1100/include/mach/memory.h
+++ b/arch/arm/mach-sa1100/include/mach/memory.h
@@ -17,10 +17,10 @@
 #ifndef __ASSEMBLY__
 
 #ifdef CONFIG_SA1111
-void sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes);
+void sa1111_adjust_zones(unsigned long *size, unsigned long *holes);
 
-#define arch_adjust_zones(node, size, holes) \
-	sa1111_adjust_zones(node, size, holes)
+#define arch_adjust_zones(size, holes) \
+	sa1111_adjust_zones(size, holes)
 
 #define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_1M - 1)
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_1M)
diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h
index 3053e5b..d9c4812 100644
--- a/arch/arm/mach-shark/include/mach/memory.h
+++ b/arch/arm/mach-shark/include/mach/memory.h
@@ -19,9 +19,8 @@
 
 #ifndef __ASSEMBLY__
 
-static inline void __arch_adjust_zones(int node, unsigned long *zone_size, unsigned long *zhole_size) 
+static inline void __arch_adjust_zones(unsigned long *zone_size, unsigned long *zhole_size)
 {
-  if (node != 0) return;
   /* Only the first 4 MB (=1024 Pages) are usable for DMA */
   /* See dev / -> .properties in OpenFirmware. */
   zone_size[1] = zone_size[0] - 1024;
@@ -30,8 +29,8 @@
   zhole_size[0] = 0;
 }
 
-#define arch_adjust_zones(node, size, holes) \
-	__arch_adjust_zones(node, size, holes)
+#define arch_adjust_zones(size, holes) \
+	__arch_adjust_zones(size, holes)
 
 #define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_4M - 1)
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_4M)
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index f2b88c5..4c704b4 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -70,6 +70,18 @@
 
 menu "Timer and clock configuration"
 
+config SHMOBILE_TIMER_HZ
+	int "Kernel HZ (jiffies per second)"
+	range 32 1024
+	default "128"
+	help
+	  Allows the configuration of the timer frequency. It is customary
+	  to have the timer interrupt run at 1000 Hz or 100 Hz, but in the
+	  case of low timer frequencies other values may be more suitable.
+	  SH-Mobile systems using a 32768 Hz RCLK for clock events may want
+	  to select a HZ value such as 128 that can evenly divide RCLK.
+	  A HZ value that does not divide evenly may cause timer drift.
+
 config SH_TIMER_CMT
 	bool "CMT timer driver"
 	default y
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
index 5179b72..132256b 100644
--- a/arch/arm/mach-shmobile/include/mach/irqs.h
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -2,7 +2,6 @@
 #define __ASM_MACH_IRQS_H
 
 #define NR_IRQS         512
-#define NR_IRQS_LEGACY  8
 
 #define evt2irq(evt)		(((evt) >> 5) - 16)
 #define irq2evt(irq)		(((irq) + 16) << 5)
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 39f6ccf..18febf9 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -341,8 +341,11 @@
 	.recalc = &follow_parent,
 };
 
+static struct clk dummy_apb_pclk;
+
 /* array of all spear 3xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
+	{ .con_id = "apb_pclk",	.clk = &dummy_apb_pclk},
 	/* root clks */
 	{ .con_id = "osc_32k_clk",	.clk = &osc_32k_clk},
 	{ .con_id = "osc_24m_clk",	.clk = &osc_24m_clk},
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index 13e27c7..36ff056 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -428,8 +428,11 @@
 	.recalc = &follow_parent,
 };
 
+static struct clk dummy_apb_pclk;
+
 /* array of all spear 6xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
+	{ .con_id = "apb_pclk",	.clk = &dummy_apb_pclk},
 	/* root clks */
 	{ .con_id = "osc_32k_clk",	.clk = &osc_32k_clk},
 	{ .con_id = "osc_30m_clk",	.clk = &osc_30m_clk},
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
index 5af71d5..5d12d54 100644
--- a/arch/arm/mach-u300/clock.c
+++ b/arch/arm/mach-u300/clock.c
@@ -1212,6 +1212,8 @@
 };
 #endif
 
+static struct clk dummy_apb_pclk;
+
 #define DEF_LOOKUP(devid, clkref)		\
 	{					\
 	.dev_id = devid,			\
@@ -1223,6 +1225,10 @@
  * look up through clockdevice.
  */
 static struct clk_lookup lookups[] = {
+	{
+		.con_id = "apb_pclk",
+		.clk = &dummy_apb_pclk,
+	},
 	/* Connected directly to the AMBA bus */
 	DEF_LOOKUP("amba",      &amba_clk),
 	DEF_LOOKUP("cpu",       &cpu_clk),
diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h
index ab000df..bf134bc 100644
--- a/arch/arm/mach-u300/include/mach/memory.h
+++ b/arch/arm/mach-u300/include/mach/memory.h
@@ -35,14 +35,6 @@
 #endif
 
 /*
- * TCM memory whereabouts
- */
-#define ITCM_OFFSET	0xffff2000
-#define ITCM_END	0xffff3fff
-#define DTCM_OFFSET	0xffff4000
-#define DTCM_END	0xffff5fff
-
-/*
  * We enable a real big DMA buffer if need be.
  */
 #define CONSISTENT_DMA_SIZE SZ_4M
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index d2a0b88..bfcda98 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/memblock.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <mach/hardware.h>
@@ -22,6 +23,21 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+static void __init u300_reserve(void)
+{
+	/*
+	 * U300 - This platform family can share physical memory
+	 * between two ARM cpus, one running Linux and the other
+	 * running another OS.
+	 */
+#ifdef CONFIG_MACH_U300_SINGLE_RAM
+#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+        memblock_reserve(PHYS_OFFSET, 0x00100000);
+#endif
+#endif
+}
+
 static void __init u300_init_machine(void)
 {
 	u300_init_devices();
@@ -49,6 +65,7 @@
 	.io_pg_offst	= ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc,
 	.boot_params	= BOOT_PARAMS_OFFSET,
 	.map_io		= u300_map_io,
+	.reserve	= u300_reserve,
 	.init_irq	= u300_init_irq,
 	.timer		= &u300_timer,
 	.init_machine	= u300_init_machine,
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index bb8d7b7..0e8fd13 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -13,19 +13,42 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl022.h>
 #include <linux/spi/spi.h>
+#include <linux/mfd/ab8500.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include <plat/pincfg.h>
 #include <plat/i2c.h>
 
 #include <mach/hardware.h>
 #include <mach/setup.h>
 #include <mach/devices.h>
 
+#include "pins-db8500.h"
+
+static pin_cfg_t mop500_pins[] = {
+	/* SSP0 */
+	GPIO143_SSP0_CLK,
+	GPIO144_SSP0_FRM,
+	GPIO145_SSP0_RXD,
+	GPIO146_SSP0_TXD,
+
+	/* I2C */
+	GPIO147_I2C0_SCL,
+	GPIO148_I2C0_SDA,
+	GPIO16_I2C1_SCL,
+	GPIO17_I2C1_SDA,
+	GPIO10_I2C2_SDA,
+	GPIO11_I2C2_SCL,
+	GPIO229_I2C3_SDA,
+	GPIO230_I2C3_SCL,
+};
+
 static void ab4500_spi_cs_control(u32 command)
 {
 	/* set the FRM signal, which is CS  - TODO */
@@ -48,15 +71,20 @@
 	.cs_control = ab4500_spi_cs_control,
 };
 
+static struct ab8500_platform_data ab8500_platdata = {
+	.irq_base	= MOP500_AB8500_IRQ_BASE,
+};
+
 static struct spi_board_info u8500_spi_devices[] = {
 	{
 		.modalias = "ab8500",
 		.controller_data = &ab4500_chip_info,
+		.platform_data = &ab8500_platdata,
 		.max_speed_hz = 12000000,
 		.bus_num = 0,
 		.chip_select = 0,
 		.mode = SPI_MODE_0,
-		.irq = IRQ_AB4500,
+		.irq = IRQ_DB8500_AB8500,
 	},
 };
 
@@ -118,6 +146,10 @@
 {
 	int i;
 
+	u8500_init_devices();
+
+	nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins));
+
 	u8500_i2c0_device.dev.platform_data = &u8500_i2c0_data;
 	ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data;
 	ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data;
@@ -133,8 +165,6 @@
 
 	spi_register_board_info(u8500_spi_devices,
 			ARRAY_SIZE(u8500_spi_devices));
-
-	u8500_init_devices();
 }
 
 MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 0a1318f..d8ab7f1 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -453,7 +453,11 @@
 static DEFINE_PRCC_CLK(7, wdg_ed, 	1, -1, NULL);
 static DEFINE_PRCC_CLK(7, cfgreg_ed, 	0, -1, NULL);
 
+static struct clk clk_dummy_apb_pclk;
+
 static struct clk_lookup u8500_common_clks[] = {
+	CLK(dummy_apb_pclk, NULL,	"apb_pclk"),
+
 	/* Peripheral Cluster #1 */
 	CLK(gpio0,	"gpio.0",	NULL),
 	CLK(gpio0,	"gpio.1",	NULL),
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 8229034..654fca9 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -65,7 +65,7 @@
 		.end   = U8500_SSP0_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {IRQ_SSP0, NO_IRQ },
+	.irq = {IRQ_DB8500_SSP0, NO_IRQ },
 	/* ST-Ericsson modified id */
 	.periphid = SSP_PER_ID,
 };
@@ -77,8 +77,8 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= IRQ_I2C0,
-		.end	= IRQ_I2C0,
+		.start	= IRQ_DB8500_I2C0,
+		.end	= IRQ_DB8500_I2C0,
 		.flags	= IORESOURCE_IRQ,
 	}
 };
@@ -97,8 +97,8 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= IRQ_I2C4,
-		.end	= IRQ_I2C4,
+		.start	= IRQ_DB8500_I2C4,
+		.end	= IRQ_DB8500_I2C4,
 		.flags	= IORESOURCE_IRQ,
 	}
 };
@@ -130,8 +130,8 @@
 		.name = "lcla",
 	},
 	[3] = {
-		.start = IRQ_DMA,
-		.end = IRQ_DMA,
+		.start = IRQ_DB8500_DMA,
+		.end   = IRQ_DB8500_DMA,
 		.flags = IORESOURCE_IRQ}
 };
 
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
new file mode 100644
index 0000000..cca4f70
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_IRQS_BOARD_MOP500_H
+#define __MACH_IRQS_BOARD_MOP500_H
+
+#define AB8500_NR_IRQS			104
+
+#define MOP500_AB8500_IRQ_BASE		IRQ_BOARD_START
+#define MOP500_AB8500_IRQ_END		(MOP500_AB8500_IRQ_BASE \
+					 + AB8500_NR_IRQS)
+#define MOP500_IRQ_END			MOP500_AB8500_IRQ_END
+
+#if MOP500_IRQ_END > IRQ_BOARD_END
+#undef IRQ_BOARD_END
+#define IRQ_BOARD_END	MOP500_IRQ_END
+#endif
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs-db5500.h b/arch/arm/mach-ux500/include/mach/irqs-db5500.h
new file mode 100644
index 0000000..6fbfe5e
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/irqs-db5500.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_IRQS_DB5500_H
+#define __MACH_IRQS_DB5500_H
+
+#define IRQ_DB5500_MTU0			(IRQ_SHPI_START + 4)
+#define IRQ_DB5500_SPI2			(IRQ_SHPI_START + 6)
+#define IRQ_DB5500_PMU0			(IRQ_SHPI_START + 7)
+#define IRQ_DB5500_SPI0			(IRQ_SHPI_START + 8)
+#define IRQ_DB5500_RTT			(IRQ_SHPI_START + 9)
+#define IRQ_DB5500_PKA			(IRQ_SHPI_START + 10)
+#define IRQ_DB5500_UART0		(IRQ_SHPI_START + 11)
+#define IRQ_DB5500_I2C3			(IRQ_SHPI_START + 12)
+#define IRQ_DB5500_L2CC			(IRQ_SHPI_START + 13)
+#define IRQ_DB5500_MSP0			(IRQ_SHPI_START + 14)
+#define IRQ_DB5500_CRYP1		(IRQ_SHPI_START + 15)
+#define IRQ_DB5500_PMU1			(IRQ_SHPI_START + 16)
+#define IRQ_DB5500_MTU1			(IRQ_SHPI_START + 17)
+#define IRQ_DB5500_RTC			(IRQ_SHPI_START + 18)
+#define IRQ_DB5500_UART1		(IRQ_SHPI_START + 19)
+#define IRQ_DB5500_USB_WAKEUP		(IRQ_SHPI_START + 20)
+#define IRQ_DB5500_I2C0			(IRQ_SHPI_START + 21)
+#define IRQ_DB5500_I2C1			(IRQ_SHPI_START + 22)
+#define IRQ_DB5500_USBOTG		(IRQ_SHPI_START + 23)
+#define IRQ_DB5500_DMA_SECURE		(IRQ_SHPI_START + 24)
+#define IRQ_DB5500_DMA			(IRQ_SHPI_START + 25)
+#define IRQ_DB5500_UART2		(IRQ_SHPI_START + 26)
+#define IRQ_DB5500_ICN_PMU1		(IRQ_SHPI_START + 27)
+#define IRQ_DB5500_ICN_PMU2		(IRQ_SHPI_START + 28)
+#define IRQ_DB5500_UART3		(IRQ_SHPI_START + 29)
+#define IRQ_DB5500_SPI3			(IRQ_SHPI_START + 30)
+#define IRQ_DB5500_SDMMC4		(IRQ_SHPI_START + 31)
+#define IRQ_DB5500_IRRC			(IRQ_SHPI_START + 33)
+#define IRQ_DB5500_IRDA_FT		(IRQ_SHPI_START + 34)
+#define IRQ_DB5500_IRDA_SD		(IRQ_SHPI_START + 35)
+#define IRQ_DB5500_IRDA_FI		(IRQ_SHPI_START + 36)
+#define IRQ_DB5500_IRDA_FD		(IRQ_SHPI_START + 37)
+#define IRQ_DB5500_FSMC_CODEREADY	(IRQ_SHPI_START + 38)
+#define IRQ_DB5500_FSMC_NANDWAIT	(IRQ_SHPI_START + 39)
+#define IRQ_DB5500_AB5500		(IRQ_SHPI_START + 40)
+#define IRQ_DB5500_SDMMC2		(IRQ_SHPI_START + 41)
+#define IRQ_DB5500_SIA			(IRQ_SHPI_START + 42)
+#define IRQ_DB5500_SIA2			(IRQ_SHPI_START + 43)
+#define IRQ_DB5500_HVA			(IRQ_SHPI_START + 44)
+#define IRQ_DB5500_HVA2			(IRQ_SHPI_START + 45)
+#define IRQ_DB5500_PRCMU0		(IRQ_SHPI_START + 46)
+#define IRQ_DB5500_PRCMU1		(IRQ_SHPI_START + 47)
+#define IRQ_DB5500_DISP			(IRQ_SHPI_START + 48)
+#define IRQ_DB5500_SDMMC1		(IRQ_SHPI_START + 50)
+#define IRQ_DB5500_MSP1			(IRQ_SHPI_START + 52)
+#define IRQ_DB5500_KBD			(IRQ_SHPI_START + 53)
+#define IRQ_DB5500_I2C2			(IRQ_SHPI_START + 55)
+#define IRQ_DB5500_B2R2			(IRQ_SHPI_START + 56)
+#define IRQ_DB5500_CRYP0		(IRQ_SHPI_START + 57)
+#define IRQ_DB5500_SDMMC3		(IRQ_SHPI_START + 59)
+#define IRQ_DB5500_SDMMC0		(IRQ_SHPI_START + 60)
+#define IRQ_DB5500_HSEM			(IRQ_SHPI_START + 61)
+#define IRQ_DB5500_SBAG			(IRQ_SHPI_START + 63)
+#define IRQ_DB5500_SPI1			(IRQ_SHPI_START + 96)
+#define IRQ_DB5500_MSP2			(IRQ_SHPI_START + 98)
+#define IRQ_DB5500_SRPTIMER		(IRQ_SHPI_START + 101)
+#define IRQ_DB5500_CTI0			(IRQ_SHPI_START + 108)
+#define IRQ_DB5500_CTI1			(IRQ_SHPI_START + 109)
+#define IRQ_DB5500_ICN_ERR		(IRQ_SHPI_START + 110)
+#define IRQ_DB5500_MALI_PPMMU		(IRQ_SHPI_START + 112)
+#define IRQ_DB5500_MALI_PP		(IRQ_SHPI_START + 113)
+#define IRQ_DB5500_MALI_GPMMU		(IRQ_SHPI_START + 114)
+#define IRQ_DB5500_MALI_GP		(IRQ_SHPI_START + 115)
+#define IRQ_DB5500_MALI			(IRQ_SHPI_START + 116)
+#define IRQ_DB5500_PRCMU_SEM		(IRQ_SHPI_START + 118)
+#define IRQ_DB5500_GPIO0		(IRQ_SHPI_START + 119)
+#define IRQ_DB5500_GPIO1		(IRQ_SHPI_START + 120)
+#define IRQ_DB5500_GPIO2		(IRQ_SHPI_START + 121)
+#define IRQ_DB5500_GPIO3		(IRQ_SHPI_START + 122)
+#define IRQ_DB5500_GPIO4		(IRQ_SHPI_START + 123)
+#define IRQ_DB5500_GPIO5		(IRQ_SHPI_START + 124)
+#define IRQ_DB5500_GPIO6		(IRQ_SHPI_START + 125)
+#define IRQ_DB5500_GPIO7		(IRQ_SHPI_START + 126)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs-db8500.h b/arch/arm/mach-ux500/include/mach/irqs-db8500.h
new file mode 100644
index 0000000..8b5d9f0
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/irqs-db8500.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_IRQS_DB8500_H
+#define __MACH_IRQS_DB8500_H
+
+#define IRQ_DB8500_MTU0			(IRQ_SHPI_START + 4)
+#define IRQ_DB8500_SPI2			(IRQ_SHPI_START + 6)
+#define IRQ_DB8500_PMU			(IRQ_SHPI_START + 7)
+#define IRQ_DB8500_SPI0			(IRQ_SHPI_START + 8)
+#define IRQ_DB8500_RTT			(IRQ_SHPI_START + 9)
+#define IRQ_DB8500_PKA			(IRQ_SHPI_START + 10)
+#define IRQ_DB8500_UART0		(IRQ_SHPI_START + 11)
+#define IRQ_DB8500_I2C3			(IRQ_SHPI_START + 12)
+#define IRQ_DB8500_L2CC			(IRQ_SHPI_START + 13)
+#define IRQ_DB8500_SSP0			(IRQ_SHPI_START + 14)
+#define IRQ_DB8500_CRYP1		(IRQ_SHPI_START + 15)
+#define IRQ_DB8500_MSP1_RX		(IRQ_SHPI_START + 16)
+#define IRQ_DB8500_MTU1			(IRQ_SHPI_START + 17)
+#define IRQ_DB8500_RTC			(IRQ_SHPI_START + 18)
+#define IRQ_DB8500_UART1		(IRQ_SHPI_START + 19)
+#define IRQ_DB8500_USB_WAKEUP		(IRQ_SHPI_START + 20)
+#define IRQ_DB8500_I2C0			(IRQ_SHPI_START + 21)
+#define IRQ_DB8500_I2C1			(IRQ_SHPI_START + 22)
+#define IRQ_DB8500_USBOTG		(IRQ_SHPI_START + 23)
+#define IRQ_DB8500_DMA_SECURE		(IRQ_SHPI_START + 24)
+#define IRQ_DB8500_DMA			(IRQ_SHPI_START + 25)
+#define IRQ_DB8500_UART2		(IRQ_SHPI_START + 26)
+#define IRQ_DB8500_ICN_PMU1		(IRQ_SHPI_START + 27)
+#define IRQ_DB8500_ICN_PMU2		(IRQ_SHPI_START + 28)
+#define IRQ_DB8500_HSIR_EXCEP		(IRQ_SHPI_START + 29)
+#define IRQ_DB8500_MSP0			(IRQ_SHPI_START + 31)
+#define IRQ_DB8500_HSIR_CH0_OVRRUN	(IRQ_SHPI_START + 32)
+#define IRQ_DB8500_HSIR_CH1_OVRRUN	(IRQ_SHPI_START + 33)
+#define IRQ_DB8500_HSIR_CH2_OVRRUN	(IRQ_SHPI_START + 34)
+#define IRQ_DB8500_HSIR_CH3_OVRRUN	(IRQ_SHPI_START + 35)
+#define IRQ_DB8500_HSIR_CH4_OVRRUN	(IRQ_SHPI_START + 36)
+#define IRQ_DB8500_HSIR_CH5_OVRRUN	(IRQ_SHPI_START + 37)
+#define IRQ_DB8500_HSIR_CH6_OVRRUN	(IRQ_SHPI_START + 38)
+#define IRQ_DB8500_HSIR_CH7_OVRRUN	(IRQ_SHPI_START + 39)
+#define IRQ_DB8500_AB8500		(IRQ_SHPI_START + 40)
+#define IRQ_DB8500_SDMMC2		(IRQ_SHPI_START + 41)
+#define IRQ_DB8500_SIA			(IRQ_SHPI_START + 42)
+#define IRQ_DB8500_SIA2			(IRQ_SHPI_START + 43)
+#define IRQ_DB8500_SVA			(IRQ_SHPI_START + 44)
+#define IRQ_DB8500_SVA2			(IRQ_SHPI_START + 45)
+#define IRQ_DB8500_PRCMU0		(IRQ_SHPI_START + 46)
+#define IRQ_DB8500_PRCMU1		(IRQ_SHPI_START + 47)
+#define IRQ_DB8500_DISP			(IRQ_SHPI_START + 48)
+#define IRQ_DB8500_SPI3			(IRQ_SHPI_START + 49)
+#define IRQ_DB8500_SDMMC1		(IRQ_SHPI_START + 50)
+#define IRQ_DB8500_I2C4			(IRQ_SHPI_START + 51)
+#define IRQ_DB8500_SSP1			(IRQ_SHPI_START + 52)
+#define IRQ_DB8500_SKE			(IRQ_SHPI_START + 53)
+#define IRQ_DB8500_KB			(IRQ_SHPI_START + 54)
+#define IRQ_DB8500_I2C2			(IRQ_SHPI_START + 55)
+#define IRQ_DB8500_B2R2			(IRQ_SHPI_START + 56)
+#define IRQ_DB8500_CRYP0		(IRQ_SHPI_START + 57)
+#define IRQ_DB8500_SDMMC3		(IRQ_SHPI_START + 59)
+#define IRQ_DB8500_SDMMC0		(IRQ_SHPI_START + 60)
+#define IRQ_DB8500_HSEM			(IRQ_SHPI_START + 61)
+#define IRQ_DB8500_MSP1			(IRQ_SHPI_START + 62)
+#define IRQ_DB8500_SBAG			(IRQ_SHPI_START + 63)
+#define IRQ_DB8500_SPI1			(IRQ_SHPI_START + 96)
+#define IRQ_DB8500_SRPTIMER		(IRQ_SHPI_START + 97)
+#define IRQ_DB8500_MSP2			(IRQ_SHPI_START + 98)
+#define IRQ_DB8500_SDMMC4		(IRQ_SHPI_START + 99)
+#define IRQ_DB8500_SDMMC5		(IRQ_SHPI_START + 100)
+#define IRQ_DB8500_HSIRD0		(IRQ_SHPI_START + 104)
+#define IRQ_DB8500_HSIRD1		(IRQ_SHPI_START + 105)
+#define IRQ_DB8500_HSITD0		(IRQ_SHPI_START + 106)
+#define IRQ_DB8500_HSITD1		(IRQ_SHPI_START + 107)
+#define IRQ_DB8500_CTI0			(IRQ_SHPI_START + 108)
+#define IRQ_DB8500_CTI1			(IRQ_SHPI_START + 109)
+#define IRQ_DB8500_ICN_ERR		(IRQ_SHPI_START + 110)
+#define IRQ_DB8500_MALI_PPMMU		(IRQ_SHPI_START + 112)
+#define IRQ_DB8500_MALI_PP		(IRQ_SHPI_START + 113)
+#define IRQ_DB8500_MALI_GPMMU		(IRQ_SHPI_START + 114)
+#define IRQ_DB8500_MALI_GP		(IRQ_SHPI_START + 115)
+#define IRQ_DB8500_MALI			(IRQ_SHPI_START + 116)
+#define IRQ_DB8500_PRCMU_SEM		(IRQ_SHPI_START + 118)
+#define IRQ_DB8500_GPIO0		(IRQ_SHPI_START + 119)
+#define IRQ_DB8500_GPIO1		(IRQ_SHPI_START + 120)
+#define IRQ_DB8500_GPIO2		(IRQ_SHPI_START + 121)
+#define IRQ_DB8500_GPIO3		(IRQ_SHPI_START + 122)
+#define IRQ_DB8500_GPIO4		(IRQ_SHPI_START + 123)
+#define IRQ_DB8500_GPIO5		(IRQ_SHPI_START + 124)
+#define IRQ_DB8500_GPIO6		(IRQ_SHPI_START + 125)
+#define IRQ_DB8500_GPIO7		(IRQ_SHPI_START + 126)
+#define IRQ_DB8500_GPIO8		(IRQ_SHPI_START + 127)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h
index 7970684..10385bd 100644
--- a/arch/arm/mach-ux500/include/mach/irqs.h
+++ b/arch/arm/mach-ux500/include/mach/irqs.h
@@ -10,7 +10,8 @@
 #ifndef ASM_ARCH_IRQS_H
 #define ASM_ARCH_IRQS_H
 
-#include <mach/hardware.h>
+#include <mach/irqs-db5500.h>
+#include <mach/irqs-db8500.h>
 
 #define IRQ_LOCALTIMER                  29
 #define IRQ_LOCALWDOG                   30
@@ -67,12 +68,21 @@
 /* There are 128 shared peripheral interrupts assigned to
  * INTID[160:32]. The first 32 interrupts are reserved.
  */
-#define U8500_SOC_NR_IRQS		161
+#define DBX500_NR_INTERNAL_IRQS		161
 
 /* After chip-specific IRQ numbers we have the GPIO ones */
 #define NOMADIK_NR_GPIO			288
-#define NOMADIK_GPIO_TO_IRQ(gpio)	((gpio) + U8500_SOC_NR_IRQS)
-#define NOMADIK_IRQ_TO_GPIO(irq)	((irq) - U8500_SOC_NR_IRQS)
-#define NR_IRQS				NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
+#define NOMADIK_GPIO_TO_IRQ(gpio)	((gpio) + DBX500_NR_INTERNAL_IRQS)
+#define NOMADIK_IRQ_TO_GPIO(irq)	((irq) - DBX500_NR_INTERNAL_IRQS)
+#define IRQ_BOARD_START			NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
 
-#endif /*ASM_ARCH_IRQS_H*/
+/* This will be overridden by board-specific irq headers */
+#define IRQ_BOARD_END			IRQ_BOARD_START
+
+#ifdef CONFIG_MACH_U8500_MOP
+#include <mach/irqs-board-mop500.h>
+#endif
+
+#define NR_IRQS				IRQ_BOARD_END
+
+#endif /* ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-ux500/pins-db8500.h b/arch/arm/mach-ux500/pins-db8500.h
new file mode 100644
index 0000000..9055d5d
--- /dev/null
+++ b/arch/arm/mach-ux500/pins-db8500.h
@@ -0,0 +1,742 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ */
+
+#ifndef __MACH_PINS_DB8500_H
+#define __MACH_PINS_DB8500_H
+
+/*
+ * TODO: Eventually encode all non-board specific pull up/down configuration
+ * here.
+ */
+
+#define GPIO0_GPIO		PIN_CFG(0, GPIO)
+#define GPIO0_U0_CTSn		PIN_CFG(0, ALT_A)
+#define GPIO0_TRIG_OUT		PIN_CFG(0, ALT_B)
+#define GPIO0_IP_TDO		PIN_CFG(0, ALT_C)
+
+#define GPIO1_GPIO		PIN_CFG(1, GPIO)
+#define GPIO1_U0_RTSn		PIN_CFG(1, ALT_A)
+#define GPIO1_TRIG_IN		PIN_CFG(1, ALT_B)
+#define GPIO1_IP_TDI		PIN_CFG(1, ALT_C)
+
+#define GPIO2_GPIO		PIN_CFG(2, GPIO)
+#define GPIO2_U0_RXD		PIN_CFG(2, ALT_A)
+#define GPIO2_NONE		PIN_CFG(2, ALT_B)
+#define GPIO2_IP_TMS		PIN_CFG(2, ALT_C)
+
+#define GPIO3_GPIO		PIN_CFG(3, GPIO)
+#define GPIO3_U0_TXD		PIN_CFG(3, ALT_A)
+#define GPIO3_NONE		PIN_CFG(3, ALT_B)
+#define GPIO3_IP_TCK		PIN_CFG(3, ALT_C)
+
+#define GPIO4_GPIO		PIN_CFG(4, GPIO)
+#define GPIO4_U1_RXD		PIN_CFG(4, ALT_A)
+#define GPIO4_I2C4_SCL		PIN_CFG_PULL(4, ALT_B, UP)
+#define GPIO4_IP_TRSTn		PIN_CFG(4, ALT_C)
+
+#define GPIO5_GPIO		PIN_CFG(5, GPIO)
+#define GPIO5_U1_TXD		PIN_CFG(5, ALT_A)
+#define GPIO5_I2C4_SDA		PIN_CFG_PULL(5, ALT_B, UP)
+#define GPIO5_IP_GPIO6		PIN_CFG(5, ALT_C)
+
+#define GPIO6_GPIO		PIN_CFG(6, GPIO)
+#define GPIO6_U1_CTSn		PIN_CFG(6, ALT_A)
+#define GPIO6_I2C1_SCL		PIN_CFG_PULL(6, ALT_B, UP)
+#define GPIO6_IP_GPIO0		PIN_CFG(6, ALT_C)
+
+#define GPIO7_GPIO		PIN_CFG(7, GPIO)
+#define GPIO7_U1_RTSn		PIN_CFG(7, ALT_A)
+#define GPIO7_I2C1_SDA		PIN_CFG_PULL(7, ALT_B, UP)
+#define GPIO7_IP_GPIO1		PIN_CFG(7, ALT_C)
+
+#define GPIO8_GPIO		PIN_CFG(8, GPIO)
+#define GPIO8_IPI2C_SDA		PIN_CFG_PULL(8, ALT_A, UP)
+#define GPIO8_I2C2_SDA		PIN_CFG_PULL(8, ALT_B, UP)
+
+#define GPIO9_GPIO		PIN_CFG(9, GPIO)
+#define GPIO9_IPI2C_SCL		PIN_CFG_PULL(9, ALT_A, UP)
+#define GPIO9_I2C2_SCL		PIN_CFG_PULL(9, ALT_B, UP)
+
+#define GPIO10_GPIO		PIN_CFG(10, GPIO)
+#define GPIO10_IPI2C_SDA	PIN_CFG_PULL(10, ALT_A, UP)
+#define GPIO10_I2C2_SDA		PIN_CFG_PULL(10, ALT_B, UP)
+#define GPIO10_IP_GPIO3		PIN_CFG(10, ALT_C)
+
+#define GPIO11_GPIO		PIN_CFG(11, GPIO)
+#define GPIO11_IPI2C_SCL	PIN_CFG_PULL(11, ALT_A, UP)
+#define GPIO11_I2C2_SCL		PIN_CFG_PULL(11, ALT_B, UP)
+#define GPIO11_IP_GPIO2		PIN_CFG(11, ALT_C)
+
+#define GPIO12_GPIO		PIN_CFG(12, GPIO)
+#define GPIO12_MSP0_TXD		PIN_CFG(12, ALT_A)
+#define GPIO12_MSP0_RXD		PIN_CFG(12, ALT_B)
+
+#define GPIO13_GPIO		PIN_CFG(13, GPIO)
+#define GPIO13_MSP0_TFS		PIN_CFG(13, ALT_A)
+
+#define GPIO14_GPIO		PIN_CFG(14, GPIO)
+#define GPIO14_MSP0_TCK		PIN_CFG(14, ALT_A)
+
+#define GPIO15_GPIO		PIN_CFG(15, GPIO)
+#define GPIO15_MSP0_RXD		PIN_CFG(15, ALT_A)
+#define GPIO15_MSP0_TXD		PIN_CFG(15, ALT_B)
+
+#define GPIO16_GPIO		PIN_CFG(16, GPIO)
+#define GPIO16_MSP0_RFS		PIN_CFG(16, ALT_A)
+#define GPIO16_I2C1_SCL		PIN_CFG_PULL(16, ALT_B, UP)
+#define GPIO16_SLIM0_DAT	PIN_CFG(16, ALT_C)
+
+#define GPIO17_GPIO		PIN_CFG(17, GPIO)
+#define GPIO17_MSP0_RCK		PIN_CFG(17, ALT_A)
+#define GPIO17_I2C1_SDA		PIN_CFG_PULL(17, ALT_B, UP)
+#define GPIO17_SLIM0_CLK	PIN_CFG(17, ALT_C)
+
+#define GPIO18_GPIO		PIN_CFG(18, GPIO)
+#define GPIO18_MC0_CMDDIR	PIN_CFG(18, ALT_A)
+#define GPIO18_U2_RXD		PIN_CFG(18, ALT_B)
+#define GPIO18_MS_IEP		PIN_CFG(18, ALT_C)
+
+#define GPIO19_GPIO		PIN_CFG(19, GPIO)
+#define GPIO19_MC0_DAT0DIR	PIN_CFG(19, ALT_A)
+#define GPIO19_U2_TXD		PIN_CFG(19, ALT_B)
+#define GPIO19_MS_DAT0DIR	PIN_CFG(19, ALT_C)
+
+#define GPIO20_GPIO		PIN_CFG(20, GPIO)
+#define GPIO20_MC0_DAT2DIR	PIN_CFG(20, ALT_A)
+#define GPIO20_UARTMOD_TXD	PIN_CFG(20, ALT_B)
+#define GPIO20_IP_TRIGOUT	PIN_CFG(20, ALT_C)
+
+#define GPIO21_GPIO		PIN_CFG(21, GPIO)
+#define GPIO21_MC0_DAT31DIR	PIN_CFG(21, ALT_A)
+#define GPIO21_MSP0_SCK		PIN_CFG(21, ALT_B)
+#define GPIO21_MS_DAT31DIR	PIN_CFG(21, ALT_C)
+
+#define GPIO22_GPIO		PIN_CFG(22, GPIO)
+#define GPIO22_MC0_FBCLK	PIN_CFG(22, ALT_A)
+#define GPIO22_UARTMOD_RXD	PIN_CFG(22, ALT_B)
+#define GPIO22_MS_FBCLK		PIN_CFG(22, ALT_C)
+
+#define GPIO23_GPIO		PIN_CFG(23, GPIO)
+#define GPIO23_MC0_CLK		PIN_CFG(23, ALT_A)
+#define GPIO23_STMMOD_CLK	PIN_CFG(23, ALT_B)
+#define GPIO23_MS_CLK		PIN_CFG(23, ALT_C)
+
+#define GPIO24_GPIO		PIN_CFG(24, GPIO)
+#define GPIO24_MC0_CMD		PIN_CFG(24, ALT_A)
+#define GPIO24_UARTMOD_RXD	PIN_CFG(24, ALT_B)
+#define GPIO24_MS_BS		PIN_CFG(24, ALT_C)
+
+#define GPIO25_GPIO		PIN_CFG(25, GPIO)
+#define GPIO25_MC0_DAT0		PIN_CFG(25, ALT_A)
+#define GPIO25_STMMOD_DAT0	PIN_CFG(25, ALT_B)
+#define GPIO25_MS_DAT0		PIN_CFG(25, ALT_C)
+
+#define GPIO26_GPIO		PIN_CFG(26, GPIO)
+#define GPIO26_MC0_DAT1		PIN_CFG(26, ALT_A)
+#define GPIO26_STMMOD_DAT1	PIN_CFG(26, ALT_B)
+#define GPIO26_MS_DAT1		PIN_CFG(26, ALT_C)
+
+#define GPIO27_GPIO		PIN_CFG(27, GPIO)
+#define GPIO27_MC0_DAT2		PIN_CFG(27, ALT_A)
+#define GPIO27_STMMOD_DAT2	PIN_CFG(27, ALT_B)
+#define GPIO27_MS_DAT2		PIN_CFG(27, ALT_C)
+
+#define GPIO28_GPIO		PIN_CFG(28, GPIO)
+#define GPIO28_MC0_DAT3		PIN_CFG(28, ALT_A)
+#define GPIO28_STMMOD_DAT3	PIN_CFG(28, ALT_B)
+#define GPIO28_MS_DAT3		PIN_CFG(28, ALT_C)
+
+#define GPIO29_GPIO		PIN_CFG(29, GPIO)
+#define GPIO29_MC0_DAT4		PIN_CFG(29, ALT_A)
+#define GPIO29_SPI3_CLK		PIN_CFG(29, ALT_B)
+#define GPIO29_U2_RXD		PIN_CFG(29, ALT_C)
+
+#define GPIO30_GPIO		PIN_CFG(30, GPIO)
+#define GPIO30_MC0_DAT5		PIN_CFG(30, ALT_A)
+#define GPIO30_SPI3_RXD		PIN_CFG(30, ALT_B)
+#define GPIO30_U2_TXD		PIN_CFG(30, ALT_C)
+
+#define GPIO31_GPIO		PIN_CFG(31, GPIO)
+#define GPIO31_MC0_DAT6		PIN_CFG(31, ALT_A)
+#define GPIO31_SPI3_FRM		PIN_CFG(31, ALT_B)
+#define GPIO31_U2_CTSn		PIN_CFG(31, ALT_C)
+
+#define GPIO32_GPIO		PIN_CFG(32, GPIO)
+#define GPIO32_MC0_DAT7		PIN_CFG(32, ALT_A)
+#define GPIO32_SPI3_TXD		PIN_CFG(32, ALT_B)
+#define GPIO32_U2_RTSn		PIN_CFG(32, ALT_C)
+
+#define GPIO33_GPIO		PIN_CFG(33, GPIO)
+#define GPIO33_MSP1_TXD		PIN_CFG(33, ALT_A)
+#define GPIO33_MSP1_RXD		PIN_CFG(33, ALT_B)
+#define GPIO33_U0_DTRn		PIN_CFG(33, ALT_C)
+
+#define GPIO34_GPIO		PIN_CFG(34, GPIO)
+#define GPIO34_MSP1_TFS		PIN_CFG(34, ALT_A)
+#define GPIO34_NONE		PIN_CFG(34, ALT_B)
+#define GPIO34_U0_DCDn		PIN_CFG(34, ALT_C)
+
+#define GPIO35_GPIO		PIN_CFG(35, GPIO)
+#define GPIO35_MSP1_TCK		PIN_CFG(35, ALT_A)
+#define GPIO35_NONE		PIN_CFG(35, ALT_B)
+#define GPIO35_U0_DSRn		PIN_CFG(35, ALT_C)
+
+#define GPIO36_GPIO		PIN_CFG(36, GPIO)
+#define GPIO36_MSP1_RXD		PIN_CFG(36, ALT_A)
+#define GPIO36_MSP1_TXD		PIN_CFG(36, ALT_B)
+#define GPIO36_U0_RIn		PIN_CFG(36, ALT_C)
+
+#define GPIO64_GPIO		PIN_CFG(64, GPIO)
+#define GPIO64_LCDB_DE		PIN_CFG(64, ALT_A)
+#define GPIO64_KP_O1		PIN_CFG(64, ALT_B)
+#define GPIO64_IP_GPIO4		PIN_CFG(64, ALT_C)
+
+#define GPIO65_GPIO		PIN_CFG(65, GPIO)
+#define GPIO65_LCDB_HSO		PIN_CFG(65, ALT_A)
+#define GPIO65_KP_O0		PIN_CFG(65, ALT_B)
+#define GPIO65_IP_GPIO5		PIN_CFG(65, ALT_C)
+
+#define GPIO66_GPIO		PIN_CFG(66, GPIO)
+#define GPIO66_LCDB_VSO		PIN_CFG(66, ALT_A)
+#define GPIO66_KP_I1		PIN_CFG(66, ALT_B)
+#define GPIO66_IP_GPIO6		PIN_CFG(66, ALT_C)
+
+#define GPIO67_GPIO		PIN_CFG(67, GPIO)
+#define GPIO67_LCDB_CLK		PIN_CFG(67, ALT_A)
+#define GPIO67_KP_I0		PIN_CFG(67, ALT_B)
+#define GPIO67_IP_GPIO7		PIN_CFG(67, ALT_C)
+
+#define GPIO68_GPIO		PIN_CFG(68, GPIO)
+#define GPIO68_LCD_VSI0		PIN_CFG(68, ALT_A)
+#define GPIO68_KP_O7		PIN_CFG(68, ALT_B)
+#define GPIO68_SM_CLE		PIN_CFG(68, ALT_C)
+
+#define GPIO69_GPIO		PIN_CFG(69, GPIO)
+#define GPIO69_LCD_VSI1		PIN_CFG(69, ALT_A)
+#define GPIO69_KP_I7		PIN_CFG(69, ALT_B)
+#define GPIO69_SM_ALE		PIN_CFG(69, ALT_C)
+
+#define GPIO70_GPIO		PIN_CFG(70, GPIO)
+#define GPIO70_LCD_D0		PIN_CFG(70, ALT_A)
+#define GPIO70_KP_O5		PIN_CFG(70, ALT_B)
+#define GPIO70_STMAPE_CLK	PIN_CFG(70, ALT_C)
+
+#define GPIO71_GPIO		PIN_CFG(71, GPIO)
+#define GPIO71_LCD_D1		PIN_CFG(71, ALT_A)
+#define GPIO71_KP_O4		PIN_CFG(71, ALT_B)
+#define GPIO71_STMAPE_DAT3	PIN_CFG(71, ALT_C)
+
+#define GPIO72_GPIO		PIN_CFG(72, GPIO)
+#define GPIO72_LCD_D2		PIN_CFG(72, ALT_A)
+#define GPIO72_KP_O3		PIN_CFG(72, ALT_B)
+#define GPIO72_STMAPE_DAT2	PIN_CFG(72, ALT_C)
+
+#define GPIO73_GPIO		PIN_CFG(73, GPIO)
+#define GPIO73_LCD_D3		PIN_CFG(73, ALT_A)
+#define GPIO73_KP_O2		PIN_CFG(73, ALT_B)
+#define GPIO73_STMAPE_DAT1	PIN_CFG(73, ALT_C)
+
+#define GPIO74_GPIO		PIN_CFG(74, GPIO)
+#define GPIO74_LCD_D4		PIN_CFG(74, ALT_A)
+#define GPIO74_KP_I5		PIN_CFG(74, ALT_B)
+#define GPIO74_STMAPE_DAT0	PIN_CFG(74, ALT_C)
+
+#define GPIO75_GPIO		PIN_CFG(75, GPIO)
+#define GPIO75_LCD_D5		PIN_CFG(75, ALT_A)
+#define GPIO75_KP_I4		PIN_CFG(75, ALT_B)
+#define GPIO75_U2_RXD		PIN_CFG(75, ALT_C)
+
+#define GPIO76_GPIO		PIN_CFG(76, GPIO)
+#define GPIO76_LCD_D6		PIN_CFG(76, ALT_A)
+#define GPIO76_KP_I3		PIN_CFG(76, ALT_B)
+#define GPIO76_U2_TXD		PIN_CFG(76, ALT_C)
+
+#define GPIO77_GPIO		PIN_CFG(77, GPIO)
+#define GPIO77_LCD_D7		PIN_CFG(77, ALT_A)
+#define GPIO77_KP_I2		PIN_CFG(77, ALT_B)
+#define GPIO77_NONE		PIN_CFG(77, ALT_C)
+
+#define GPIO78_GPIO		PIN_CFG(78, GPIO)
+#define GPIO78_LCD_D8		PIN_CFG(78, ALT_A)
+#define GPIO78_KP_O6		PIN_CFG(78, ALT_B)
+#define GPIO78_IP_GPIO2		PIN_CFG(78, ALT_C)
+
+#define GPIO79_GPIO		PIN_CFG(79, GPIO)
+#define GPIO79_LCD_D9		PIN_CFG(79, ALT_A)
+#define GPIO79_KP_I6		PIN_CFG(79, ALT_B)
+#define GPIO79_IP_GPIO3		PIN_CFG(79, ALT_C)
+
+#define GPIO80_GPIO		PIN_CFG(80, GPIO)
+#define GPIO80_LCD_D10		PIN_CFG(80, ALT_A)
+#define GPIO80_KP_SKA0		PIN_CFG(80, ALT_B)
+#define GPIO80_IP_GPIO4		PIN_CFG(80, ALT_C)
+
+#define GPIO81_GPIO		PIN_CFG(81, GPIO)
+#define GPIO81_LCD_D11		PIN_CFG(81, ALT_A)
+#define GPIO81_KP_SKB0		PIN_CFG(81, ALT_B)
+#define GPIO81_IP_GPIO5		PIN_CFG(81, ALT_C)
+
+#define GPIO82_GPIO		PIN_CFG(82, GPIO)
+#define GPIO82_LCD_D12		PIN_CFG(82, ALT_A)
+#define GPIO82_KP_O5		PIN_CFG(82, ALT_B)
+
+#define GPIO83_GPIO		PIN_CFG(83, GPIO)
+#define GPIO83_LCD_D13		PIN_CFG(83, ALT_A)
+#define GPIO83_KP_O4		PIN_CFG(83, ALT_B)
+
+#define GPIO84_GPIO		PIN_CFG(84, GPIO)
+#define GPIO84_LCD_D14		PIN_CFG(84, ALT_A)
+#define GPIO84_KP_I5		PIN_CFG(84, ALT_B)
+
+#define GPIO85_GPIO		PIN_CFG(85, GPIO)
+#define GPIO85_LCD_D15		PIN_CFG(85, ALT_A)
+#define GPIO85_KP_I4		PIN_CFG(85, ALT_B)
+
+#define GPIO86_GPIO		PIN_CFG(86, GPIO)
+#define GPIO86_LCD_D16		PIN_CFG(86, ALT_A)
+#define GPIO86_SM_ADQ0		PIN_CFG(86, ALT_B)
+#define GPIO86_MC5_DAT0		PIN_CFG(86, ALT_C)
+
+#define GPIO87_GPIO		PIN_CFG(87, GPIO)
+#define GPIO87_LCD_D17		PIN_CFG(87, ALT_A)
+#define GPIO87_SM_ADQ1		PIN_CFG(87, ALT_B)
+#define GPIO87_MC5_DAT1		PIN_CFG(87, ALT_C)
+
+#define GPIO88_GPIO		PIN_CFG(88, GPIO)
+#define GPIO88_LCD_D18		PIN_CFG(88, ALT_A)
+#define GPIO88_SM_ADQ2		PIN_CFG(88, ALT_B)
+#define GPIO88_MC5_DAT2		PIN_CFG(88, ALT_C)
+
+#define GPIO89_GPIO		PIN_CFG(89, GPIO)
+#define GPIO89_LCD_D19		PIN_CFG(89, ALT_A)
+#define GPIO89_SM_ADQ3		PIN_CFG(89, ALT_B)
+#define GPIO89_MC5_DAT3		PIN_CFG(89, ALT_C)
+
+#define GPIO90_GPIO		PIN_CFG(90, GPIO)
+#define GPIO90_LCD_D20		PIN_CFG(90, ALT_A)
+#define GPIO90_SM_ADQ4		PIN_CFG(90, ALT_B)
+#define GPIO90_MC5_CMD		PIN_CFG(90, ALT_C)
+
+#define GPIO91_GPIO		PIN_CFG(91, GPIO)
+#define GPIO91_LCD_D21		PIN_CFG(91, ALT_A)
+#define GPIO91_SM_ADQ5		PIN_CFG(91, ALT_B)
+#define GPIO91_MC5_FBCLK	PIN_CFG(91, ALT_C)
+
+#define GPIO92_GPIO		PIN_CFG(92, GPIO)
+#define GPIO92_LCD_D22		PIN_CFG(92, ALT_A)
+#define GPIO92_SM_ADQ6		PIN_CFG(92, ALT_B)
+#define GPIO92_MC5_CLK		PIN_CFG(92, ALT_C)
+
+#define GPIO93_GPIO		PIN_CFG(93, GPIO)
+#define GPIO93_LCD_D23		PIN_CFG(93, ALT_A)
+#define GPIO93_SM_ADQ7		PIN_CFG(93, ALT_B)
+#define GPIO93_MC5_DAT4		PIN_CFG(93, ALT_C)
+
+#define GPIO94_GPIO		PIN_CFG(94, GPIO)
+#define GPIO94_KP_O7		PIN_CFG(94, ALT_A)
+#define GPIO94_SM_ADVn		PIN_CFG(94, ALT_B)
+#define GPIO94_MC5_DAT5		PIN_CFG(94, ALT_C)
+
+#define GPIO95_GPIO		PIN_CFG(95, GPIO)
+#define GPIO95_KP_I7		PIN_CFG(95, ALT_A)
+#define GPIO95_SM_CS0n		PIN_CFG(95, ALT_B)
+#define GPIO95_SM_PS0n		PIN_CFG(95, ALT_C)
+
+#define GPIO96_GPIO		PIN_CFG(96, GPIO)
+#define GPIO96_KP_O6		PIN_CFG(96, ALT_A)
+#define GPIO96_SM_OEn		PIN_CFG(96, ALT_B)
+#define GPIO96_MC5_DAT6		PIN_CFG(96, ALT_C)
+
+#define GPIO97_GPIO		PIN_CFG(97, GPIO)
+#define GPIO97_KP_I6		PIN_CFG(97, ALT_A)
+#define GPIO97_SM_WEn		PIN_CFG(97, ALT_B)
+#define GPIO97_MC5_DAT7		PIN_CFG(97, ALT_C)
+
+#define GPIO128_GPIO		PIN_CFG(128, GPIO)
+#define GPIO128_MC2_CLK		PIN_CFG(128, ALT_A)
+#define GPIO128_SM_CKO		PIN_CFG(128, ALT_B)
+
+#define GPIO129_GPIO		PIN_CFG(129, GPIO)
+#define GPIO129_MC2_CMD		PIN_CFG(129, ALT_A)
+#define GPIO129_SM_WAIT0n	PIN_CFG(129, ALT_B)
+
+#define GPIO130_GPIO		PIN_CFG(130, GPIO)
+#define GPIO130_MC2_FBCLK	PIN_CFG(130, ALT_A)
+#define GPIO130_SM_FBCLK	PIN_CFG(130, ALT_B)
+#define GPIO130_MC2_RSTN	PIN_CFG(130, ALT_C)
+
+#define GPIO131_GPIO		PIN_CFG(131, GPIO)
+#define GPIO131_MC2_DAT0	PIN_CFG(131, ALT_A)
+#define GPIO131_SM_ADQ8		PIN_CFG(131, ALT_B)
+
+#define GPIO132_GPIO		PIN_CFG(132, GPIO)
+#define GPIO132_MC2_DAT1	PIN_CFG(132, ALT_A)
+#define GPIO132_SM_ADQ9		PIN_CFG(132, ALT_B)
+
+#define GPIO133_GPIO		PIN_CFG(133, GPIO)
+#define GPIO133_MC2_DAT2	PIN_CFG(133, ALT_A)
+#define GPIO133_SM_ADQ10	PIN_CFG(133, ALT_B)
+
+#define GPIO134_GPIO		PIN_CFG(134, GPIO)
+#define GPIO134_MC2_DAT3	PIN_CFG(134, ALT_A)
+#define GPIO134_SM_ADQ11	PIN_CFG(134, ALT_B)
+
+#define GPIO135_GPIO		PIN_CFG(135, GPIO)
+#define GPIO135_MC2_DAT4	PIN_CFG(135, ALT_A)
+#define GPIO135_SM_ADQ12	PIN_CFG(135, ALT_B)
+
+#define GPIO136_GPIO		PIN_CFG(136, GPIO)
+#define GPIO136_MC2_DAT5	PIN_CFG(136, ALT_A)
+#define GPIO136_SM_ADQ13	PIN_CFG(136, ALT_B)
+
+#define GPIO137_GPIO		PIN_CFG(137, GPIO)
+#define GPIO137_MC2_DAT6	PIN_CFG(137, ALT_A)
+#define GPIO137_SM_ADQ14	PIN_CFG(137, ALT_B)
+
+#define GPIO138_GPIO		PIN_CFG(138, GPIO)
+#define GPIO138_MC2_DAT7	PIN_CFG(138, ALT_A)
+#define GPIO138_SM_ADQ15	PIN_CFG(138, ALT_B)
+
+#define GPIO139_GPIO		PIN_CFG(139, GPIO)
+#define GPIO139_SSP1_RXD	PIN_CFG(139, ALT_A)
+#define GPIO139_SM_WAIT1n	PIN_CFG(139, ALT_B)
+#define GPIO139_KP_O8		PIN_CFG(139, ALT_C)
+
+#define GPIO140_GPIO		PIN_CFG(140, GPIO)
+#define GPIO140_SSP1_TXD	PIN_CFG(140, ALT_A)
+#define GPIO140_IP_GPIO7	PIN_CFG(140, ALT_B)
+#define GPIO140_KP_SKA1		PIN_CFG(140, ALT_C)
+
+#define GPIO141_GPIO		PIN_CFG(141, GPIO)
+#define GPIO141_SSP1_CLK	PIN_CFG(141, ALT_A)
+#define GPIO141_IP_GPIO2	PIN_CFG(141, ALT_B)
+#define GPIO141_KP_O9		PIN_CFG(141, ALT_C)
+
+#define GPIO142_GPIO		PIN_CFG(142, GPIO)
+#define GPIO142_SSP1_FRM	PIN_CFG(142, ALT_A)
+#define GPIO142_IP_GPIO3	PIN_CFG(142, ALT_B)
+#define GPIO142_KP_SKB1		PIN_CFG(142, ALT_C)
+
+#define GPIO143_GPIO		PIN_CFG(143, GPIO)
+#define GPIO143_SSP0_CLK	PIN_CFG(143, ALT_A)
+
+#define GPIO144_GPIO		PIN_CFG(144, GPIO)
+#define GPIO144_SSP0_FRM	PIN_CFG(144, ALT_A)
+
+#define GPIO145_GPIO		PIN_CFG(145, GPIO)
+#define GPIO145_SSP0_RXD	PIN_CFG(145, ALT_A)
+
+#define GPIO146_GPIO		PIN_CFG(146, GPIO)
+#define GPIO146_SSP0_TXD	PIN_CFG(146, ALT_A)
+
+#define GPIO147_GPIO		PIN_CFG(147, GPIO)
+#define GPIO147_I2C0_SCL	PIN_CFG_PULL(147, ALT_A, UP)
+
+#define GPIO148_GPIO		PIN_CFG(148, GPIO)
+#define GPIO148_I2C0_SDA	PIN_CFG_PULL(148, ALT_A, UP)
+
+#define GPIO149_GPIO		PIN_CFG(149, GPIO)
+#define GPIO149_IP_GPIO0	PIN_CFG(149, ALT_A)
+#define GPIO149_SM_CS1n		PIN_CFG(149, ALT_B)
+#define GPIO149_SM_PS1n		PIN_CFG(149, ALT_C)
+
+#define GPIO150_GPIO		PIN_CFG(150, GPIO)
+#define GPIO150_IP_GPIO1	PIN_CFG(150, ALT_A)
+#define GPIO150_LCDA_CLK	PIN_CFG(150, ALT_B)
+
+#define GPIO151_GPIO		PIN_CFG(151, GPIO)
+#define GPIO151_KP_SKA0		PIN_CFG(151, ALT_A)
+#define GPIO151_LCD_VSI0	PIN_CFG(151, ALT_B)
+#define GPIO151_KP_O8		PIN_CFG(151, ALT_C)
+
+#define GPIO152_GPIO		PIN_CFG(152, GPIO)
+#define GPIO152_KP_SKB0		PIN_CFG(152, ALT_A)
+#define GPIO152_LCD_VSI1	PIN_CFG(152, ALT_B)
+#define GPIO152_KP_O9		PIN_CFG(152, ALT_C)
+
+#define GPIO153_GPIO		PIN_CFG(153, GPIO)
+#define GPIO153_KP_I7		PIN_CFG(153, ALT_A)
+#define GPIO153_LCD_D24		PIN_CFG(153, ALT_B)
+#define GPIO153_U2_RXD		PIN_CFG(153, ALT_C)
+
+#define GPIO154_GPIO		PIN_CFG(154, GPIO)
+#define GPIO154_KP_I6		PIN_CFG(154, ALT_A)
+#define GPIO154_LCD_D25		PIN_CFG(154, ALT_B)
+#define GPIO154_U2_TXD		PIN_CFG(154, ALT_C)
+
+#define GPIO155_GPIO		PIN_CFG(155, GPIO)
+#define GPIO155_KP_I5		PIN_CFG(155, ALT_A)
+#define GPIO155_LCD_D26		PIN_CFG(155, ALT_B)
+#define GPIO155_STMAPE_CLK	PIN_CFG(155, ALT_C)
+
+#define GPIO156_GPIO		PIN_CFG(156, GPIO)
+#define GPIO156_KP_I4		PIN_CFG(156, ALT_A)
+#define GPIO156_LCD_D27		PIN_CFG(156, ALT_B)
+#define GPIO156_STMAPE_DAT3	PIN_CFG(156, ALT_C)
+
+#define GPIO157_GPIO		PIN_CFG(157, GPIO)
+#define GPIO157_KP_O7		PIN_CFG(157, ALT_A)
+#define GPIO157_LCD_D28		PIN_CFG(157, ALT_B)
+#define GPIO157_STMAPE_DAT2	PIN_CFG(157, ALT_C)
+
+#define GPIO158_GPIO		PIN_CFG(158, GPIO)
+#define GPIO158_KP_O6		PIN_CFG(158, ALT_A)
+#define GPIO158_LCD_D29		PIN_CFG(158, ALT_B)
+#define GPIO158_STMAPE_DAT1	PIN_CFG(158, ALT_C)
+
+#define GPIO159_GPIO		PIN_CFG(159, GPIO)
+#define GPIO159_KP_O5		PIN_CFG(159, ALT_A)
+#define GPIO159_LCD_D30		PIN_CFG(159, ALT_B)
+#define GPIO159_STMAPE_DAT0	PIN_CFG(159, ALT_C)
+
+#define GPIO160_GPIO		PIN_CFG(160, GPIO)
+#define GPIO160_KP_O4		PIN_CFG(160, ALT_A)
+#define GPIO160_LCD_D31		PIN_CFG(160, ALT_B)
+#define GPIO160_NONE		PIN_CFG(160, ALT_C)
+
+#define GPIO161_GPIO		PIN_CFG(161, GPIO)
+#define GPIO161_KP_I3		PIN_CFG(161, ALT_A)
+#define GPIO161_LCD_D32		PIN_CFG(161, ALT_B)
+#define GPIO161_UARTMOD_RXD	PIN_CFG(161, ALT_C)
+
+#define GPIO162_GPIO		PIN_CFG(162, GPIO)
+#define GPIO162_KP_I2		PIN_CFG(162, ALT_A)
+#define GPIO162_LCD_D33		PIN_CFG(162, ALT_B)
+#define GPIO162_UARTMOD_TXD	PIN_CFG(162, ALT_C)
+
+#define GPIO163_GPIO		PIN_CFG(163, GPIO)
+#define GPIO163_KP_I1		PIN_CFG(163, ALT_A)
+#define GPIO163_LCD_D34		PIN_CFG(163, ALT_B)
+#define GPIO163_STMMOD_CLK	PIN_CFG(163, ALT_C)
+
+#define GPIO164_GPIO		PIN_CFG(164, GPIO)
+#define GPIO164_KP_I0		PIN_CFG(164, ALT_A)
+#define GPIO164_LCD_D35		PIN_CFG(164, ALT_B)
+#define GPIO164_STMMOD_DAT3	PIN_CFG(164, ALT_C)
+
+#define GPIO165_GPIO		PIN_CFG(165, GPIO)
+#define GPIO165_KP_O3		PIN_CFG(165, ALT_A)
+#define GPIO165_LCD_D36		PIN_CFG(165, ALT_B)
+#define GPIO165_STMMOD_DAT2	PIN_CFG(165, ALT_C)
+
+#define GPIO166_GPIO		PIN_CFG(166, GPIO)
+#define GPIO166_KP_O2		PIN_CFG(166, ALT_A)
+#define GPIO166_LCD_D37		PIN_CFG(166, ALT_B)
+#define GPIO166_STMMOD_DAT1	PIN_CFG(166, ALT_C)
+
+#define GPIO167_GPIO		PIN_CFG(167, GPIO)
+#define GPIO167_KP_O1		PIN_CFG(167, ALT_A)
+#define GPIO167_LCD_D38		PIN_CFG(167, ALT_B)
+#define GPIO167_STMMOD_DAT0	PIN_CFG(167, ALT_C)
+
+#define GPIO168_GPIO		PIN_CFG(168, GPIO)
+#define GPIO168_KP_O0		PIN_CFG(168, ALT_A)
+#define GPIO168_LCD_D39		PIN_CFG(168, ALT_B)
+#define GPIO168_NONE		PIN_CFG(168, ALT_C)
+
+#define GPIO169_GPIO		PIN_CFG(169, GPIO)
+#define GPIO169_RF_PURn		PIN_CFG(169, ALT_A)
+#define GPIO169_LCDA_DE		PIN_CFG(169, ALT_B)
+#define GPIO169_USBSIM_PDC	PIN_CFG(169, ALT_C)
+
+#define GPIO170_GPIO		PIN_CFG(170, GPIO)
+#define GPIO170_MODEM_STATE	PIN_CFG(170, ALT_A)
+#define GPIO170_LCDA_VSO	PIN_CFG(170, ALT_B)
+#define GPIO170_KP_SKA1		PIN_CFG(170, ALT_C)
+
+#define GPIO171_GPIO		PIN_CFG(171, GPIO)
+#define GPIO171_MODEM_PWREN	PIN_CFG(171, ALT_A)
+#define GPIO171_LCDA_HSO	PIN_CFG(171, ALT_B)
+#define GPIO171_KP_SKB1		PIN_CFG(171, ALT_C)
+
+#define GPIO192_GPIO		PIN_CFG(192, GPIO)
+#define GPIO192_MSP2_SCK	PIN_CFG(192, ALT_A)
+
+#define GPIO193_GPIO		PIN_CFG(193, GPIO)
+#define GPIO193_MSP2_TXD	PIN_CFG(193, ALT_A)
+
+#define GPIO194_GPIO		PIN_CFG(194, GPIO)
+#define GPIO194_MSP2_TCK	PIN_CFG(194, ALT_A)
+
+#define GPIO195_GPIO		PIN_CFG(195, GPIO)
+#define GPIO195_MSP2_TFS	PIN_CFG(195, ALT_A)
+
+#define GPIO196_GPIO		PIN_CFG(196, GPIO)
+#define GPIO196_MSP2_RXD	PIN_CFG(196, ALT_A)
+
+#define GPIO197_GPIO		PIN_CFG(197, GPIO)
+#define GPIO197_MC4_DAT3	PIN_CFG(197, ALT_A)
+
+#define GPIO198_GPIO		PIN_CFG(198, GPIO)
+#define GPIO198_MC4_DAT2	PIN_CFG(198, ALT_A)
+
+#define GPIO199_GPIO		PIN_CFG(199, GPIO)
+#define GPIO199_MC4_DAT1	PIN_CFG(199, ALT_A)
+
+#define GPIO200_GPIO		PIN_CFG(200, GPIO)
+#define GPIO200_MC4_DAT0	PIN_CFG(200, ALT_A)
+
+#define GPIO201_GPIO		PIN_CFG(201, GPIO)
+#define GPIO201_MC4_CMD		PIN_CFG(201, ALT_A)
+
+#define GPIO202_GPIO		PIN_CFG(202, GPIO)
+#define GPIO202_MC4_FBCLK	PIN_CFG(202, ALT_A)
+#define GPIO202_PWL		PIN_CFG(202, ALT_B)
+#define GPIO202_MC4_RSTN	PIN_CFG(202, ALT_C)
+
+#define GPIO203_GPIO		PIN_CFG(203, GPIO)
+#define GPIO203_MC4_CLK		PIN_CFG(203, ALT_A)
+
+#define GPIO204_GPIO		PIN_CFG(204, GPIO)
+#define GPIO204_MC4_DAT7	PIN_CFG(204, ALT_A)
+
+#define GPIO205_GPIO		PIN_CFG(205, GPIO)
+#define GPIO205_MC4_DAT6	PIN_CFG(205, ALT_A)
+
+#define GPIO206_GPIO		PIN_CFG(206, GPIO)
+#define GPIO206_MC4_DAT5	PIN_CFG(206, ALT_A)
+
+#define GPIO207_GPIO		PIN_CFG(207, GPIO)
+#define GPIO207_MC4_DAT4	PIN_CFG(207, ALT_A)
+
+#define GPIO208_GPIO		PIN_CFG(208, GPIO)
+#define GPIO208_MC1_CLK		PIN_CFG(208, ALT_A)
+
+#define GPIO209_GPIO		PIN_CFG(209, GPIO)
+#define GPIO209_MC1_FBCLK	PIN_CFG(209, ALT_A)
+#define GPIO209_SPI1_CLK	PIN_CFG(209, ALT_B)
+
+#define GPIO210_GPIO		PIN_CFG(210, GPIO)
+#define GPIO210_MC1_CMD		PIN_CFG(210, ALT_A)
+
+#define GPIO211_GPIO		PIN_CFG(211, GPIO)
+#define GPIO211_MC1_DAT0	PIN_CFG(211, ALT_A)
+
+#define GPIO212_GPIO		PIN_CFG(212, GPIO)
+#define GPIO212_MC1_DAT1	PIN_CFG(212, ALT_A)
+#define GPIO212_SPI1_FRM	PIN_CFG(212, ALT_B)
+
+#define GPIO213_GPIO		PIN_CFG(213, GPIO)
+#define GPIO213_MC1_DAT2	PIN_CFG(213, ALT_A)
+#define GPIO213_SPI1_TXD	PIN_CFG(213, ALT_B)
+
+#define GPIO214_GPIO		PIN_CFG(214, GPIO)
+#define GPIO214_MC1_DAT3	PIN_CFG(214, ALT_A)
+#define GPIO214_SPI1_RXD	PIN_CFG(214, ALT_B)
+
+#define GPIO215_GPIO		PIN_CFG(215, GPIO)
+#define GPIO215_MC1_CMDDIR	PIN_CFG(215, ALT_A)
+#define GPIO215_MC3_DAT2DIR	PIN_CFG(215, ALT_B)
+#define GPIO215_CLKOUT1		PIN_CFG(215, ALT_C)
+
+#define GPIO216_GPIO		PIN_CFG(216, GPIO)
+#define GPIO216_MC1_DAT2DIR	PIN_CFG(216, ALT_A)
+#define GPIO216_MC3_CMDDIR	PIN_CFG(216, ALT_B)
+#define GPIO216_I2C3_SDA	PIN_CFG_PULL(216, ALT_C, UP)
+
+#define GPIO217_GPIO		PIN_CFG(217, GPIO)
+#define GPIO217_MC1_DAT0DIR	PIN_CFG(217, ALT_A)
+#define GPIO217_MC3_DAT31DIR	PIN_CFG(217, ALT_B)
+#define GPIO217_CLKOUT2		PIN_CFG(217, ALT_C)
+
+#define GPIO218_GPIO		PIN_CFG(218, GPIO)
+#define GPIO218_MC1_DAT31DIR	PIN_CFG(218, ALT_A)
+#define GPIO218_MC3_DAT0DIR	PIN_CFG(218, ALT_B)
+#define GPIO218_I2C3_SCL	PIN_CFG_PULL(218, ALT_C, UP)
+
+#define GPIO219_GPIO		PIN_CFG(219, GPIO)
+#define GPIO219_HSIR_FLA0	PIN_CFG(219, ALT_A)
+#define GPIO219_MC3_CLK		PIN_CFG(219, ALT_B)
+
+#define GPIO220_GPIO		PIN_CFG(220, GPIO)
+#define GPIO220_HSIR_DAT0	PIN_CFG(220, ALT_A)
+#define GPIO220_MC3_FBCLK	PIN_CFG(220, ALT_B)
+#define GPIO220_SPI0_CLK	PIN_CFG(220, ALT_C)
+
+#define GPIO221_GPIO		PIN_CFG(221, GPIO)
+#define GPIO221_HSIR_RDY0	PIN_CFG(221, ALT_A)
+#define GPIO221_MC3_CMD		PIN_CFG(221, ALT_B)
+
+#define GPIO222_GPIO		PIN_CFG(222, GPIO)
+#define GPIO222_HSIT_FLA0	PIN_CFG(222, ALT_A)
+#define GPIO222_MC3_DAT0	PIN_CFG(222, ALT_B)
+
+#define GPIO223_GPIO		PIN_CFG(223, GPIO)
+#define GPIO223_HSIT_DAT0	PIN_CFG(223, ALT_A)
+#define GPIO223_MC3_DAT1	PIN_CFG(223, ALT_B)
+#define GPIO223_SPI0_FRM	PIN_CFG(223, ALT_C)
+
+#define GPIO224_GPIO		PIN_CFG(224, GPIO)
+#define GPIO224_HSIT_RDY0	PIN_CFG(224, ALT_A)
+#define GPIO224_MC3_DAT2	PIN_CFG(224, ALT_B)
+#define GPIO224_SPI0_TXD	PIN_CFG(224, ALT_C)
+
+#define GPIO225_GPIO		PIN_CFG(225, GPIO)
+#define GPIO225_HSIT_CAWAKE0	PIN_CFG(225, ALT_A)
+#define GPIO225_MC3_DAT3	PIN_CFG(225, ALT_B)
+#define GPIO225_SPI0_RXD	PIN_CFG(225, ALT_C)
+
+#define GPIO226_GPIO		PIN_CFG(226, GPIO)
+#define GPIO226_HSIT_ACWAKE0	PIN_CFG(226, ALT_A)
+#define GPIO226_PWL		PIN_CFG(226, ALT_B)
+#define GPIO226_USBSIM_PDC	PIN_CFG(226, ALT_C)
+
+#define GPIO227_GPIO		PIN_CFG(227, GPIO)
+#define GPIO227_CLKOUT1		PIN_CFG(227, ALT_A)
+
+#define GPIO228_GPIO		PIN_CFG(228, GPIO)
+#define GPIO228_CLKOUT2		PIN_CFG(228, ALT_A)
+
+#define GPIO229_GPIO		PIN_CFG(229, GPIO)
+#define GPIO229_CLKOUT1		PIN_CFG(229, ALT_A)
+#define GPIO229_PWL		PIN_CFG(229, ALT_B)
+#define GPIO229_I2C3_SDA	PIN_CFG_PULL(229, ALT_C, UP)
+
+#define GPIO230_GPIO		PIN_CFG(230, GPIO)
+#define GPIO230_CLKOUT2		PIN_CFG(230, ALT_A)
+#define GPIO230_PWL		PIN_CFG(230, ALT_B)
+#define GPIO230_I2C3_SCL	PIN_CFG_PULL(230, ALT_C, UP)
+
+#define GPIO256_GPIO		PIN_CFG(256, GPIO)
+#define GPIO256_USB_NXT		PIN_CFG(256, ALT_A)
+
+#define GPIO257_GPIO		PIN_CFG(257, GPIO)
+#define GPIO257_USB_STP		PIN_CFG(257, ALT_A)
+
+#define GPIO258_GPIO		PIN_CFG(258, GPIO)
+#define GPIO258_USB_XCLK	PIN_CFG(258, ALT_A)
+#define GPIO258_NONE		PIN_CFG(258, ALT_B)
+#define GPIO258_DDR_TRIG	PIN_CFG(258, ALT_C)
+
+#define GPIO259_GPIO		PIN_CFG(259, GPIO)
+#define GPIO259_USB_DIR		PIN_CFG(259, ALT_A)
+
+#define GPIO260_GPIO		PIN_CFG(260, GPIO)
+#define GPIO260_USB_DAT7	PIN_CFG(260, ALT_A)
+
+#define GPIO261_GPIO		PIN_CFG(261, GPIO)
+#define GPIO261_USB_DAT6	PIN_CFG(261, ALT_A)
+
+#define GPIO262_GPIO		PIN_CFG(262, GPIO)
+#define GPIO262_USB_DAT5	PIN_CFG(262, ALT_A)
+
+#define GPIO263_GPIO		PIN_CFG(263, GPIO)
+#define GPIO263_USB_DAT4	PIN_CFG(263, ALT_A)
+
+#define GPIO264_GPIO		PIN_CFG(264, GPIO)
+#define GPIO264_USB_DAT3	PIN_CFG(264, ALT_A)
+
+#define GPIO265_GPIO		PIN_CFG(265, GPIO)
+#define GPIO265_USB_DAT2	PIN_CFG(265, ALT_A)
+
+#define GPIO266_GPIO		PIN_CFG(266, GPIO)
+#define GPIO266_USB_DAT1	PIN_CFG(266, ALT_A)
+
+#define GPIO267_GPIO		PIN_CFG(267, GPIO)
+#define GPIO267_USB_DAT0	PIN_CFG(267, ALT_A)
+
+#endif
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 3dff864..e38acb0 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -28,6 +28,7 @@
 #include <linux/amba/clcd.h>
 #include <linux/amba/pl061.h>
 #include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
 #include <linux/io.h>
 #include <linux/gfp.h>
 
@@ -354,6 +355,21 @@
 	.gpio_cd	= -1,
 };
 
+static struct resource char_lcd_resources[] = {
+	{
+		.start = VERSATILE_CHAR_LCD_BASE,
+		.end   = (VERSATILE_CHAR_LCD_BASE + SZ_4K - 1),
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device char_lcd_device = {
+	.name           =       "arm-charlcd",
+	.id             =       -1,
+	.num_resources  =       ARRAY_SIZE(char_lcd_resources),
+	.resource       =       char_lcd_resources,
+};
+
 /*
  * Clock handling
  */
@@ -400,8 +416,13 @@
 	.rate	= 24000000,
 };
 
+static struct clk dummy_apb_pclk;
+
 static struct clk_lookup lookups[] = {
-	{	/* UART0 */
+	{	/* AMBA bus clock */
+		.con_id		= "apb_pclk",
+		.clk		= &dummy_apb_pclk,
+	}, {	/* UART0 */
 		.dev_id		= "dev:f1",
 		.clk		= &ref24_clk,
 	}, {	/* UART1 */
@@ -425,6 +446,9 @@
 	}, {	/* MMC1 */
 		.dev_id		= "fpga:0b",
 		.clk		= &ref24_clk,
+	}, {	/* SSP */
+		.dev_id		= "dev:f4",
+		.clk		= &ref24_clk,
 	}, {	/* CLCD */
 		.dev_id		= "dev:20",
 		.clk		= &osc4_clk,
@@ -703,6 +727,12 @@
 	.irq_base	= IRQ_GPIO1_START,
 };
 
+static struct pl022_ssp_controller ssp0_plat_data = {
+	.bus_id = 0,
+	.enable_dma = 0,
+	.num_chipselect = 1,
+};
+
 #define AACI_IRQ	{ IRQ_AACI, NO_IRQ }
 #define AACI_DMA	{ 0x80, 0x81 }
 #define MMCI0_IRQ	{ IRQ_MMCI0A,IRQ_SIC_MMCI0B }
@@ -772,7 +802,7 @@
 AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL);
 AMBA_DEVICE(uart1, "dev:f2",  UART1,    NULL);
 AMBA_DEVICE(uart2, "dev:f3",  UART2,    NULL);
-AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      NULL);
+AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      &ssp0_plat_data);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&dmac_device,
@@ -843,6 +873,7 @@
 	platform_device_register(&versatile_flash_device);
 	platform_device_register(&versatile_i2c_device);
 	platform_device_register(&smc91x_device);
+	platform_device_register(&char_lcd_device);
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
index 334f0df..13c7e5f 100644
--- a/arch/arm/mach-versatile/pci.c
+++ b/arch/arm/mach-versatile/pci.c
@@ -304,7 +304,7 @@
 }
 
 
-struct pci_bus *pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
+struct pci_bus * __init pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
 {
 	return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
 }
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 6353459..577df6c 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -16,6 +16,7 @@
 #include <asm/hardware/gic.h>
 #include <asm/mach-types.h>
 #include <asm/pmu.h>
+#include <asm/smp_twd.h>
 
 #include <mach/clkdev.h>
 #include <mach/ct-ca9x4.h>
@@ -53,6 +54,7 @@
 
 static void __init ct_ca9x4_map_io(void)
 {
+	twd_base = MMIO_P2V(A9_MPCORE_TWD);
 	v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
 }
 
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
index 8650f04..f9e2f8d 100644
--- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
+++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
@@ -28,6 +28,7 @@
 #define A9_MPCORE_SCU		(CT_CA9X4_MPIC + 0x0000)
 #define A9_MPCORE_GIC_CPU	(CT_CA9X4_MPIC + 0x0100)
 #define A9_MPCORE_GIT		(CT_CA9X4_MPIC + 0x0200)
+#define A9_MPCORE_TWD		(CT_CA9X4_MPIC + 0x0600)
 #define A9_MPCORE_GIC_DIST	(CT_CA9X4_MPIC + 0x1000)
 
 /*
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index d250711..d6db345 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -298,8 +298,13 @@
 	.rate	= 24000000,
 };
 
+static struct clk dummy_apb_pclk;
+
 static struct clk_lookup v2m_lookups[] = {
-	{	/* UART0 */
+	{	/* AMBA bus clock */
+		.con_id		= "apb_pclk",
+		.clk		= &dummy_apb_pclk,
+	}, {	/* UART0 */
 		.dev_id		= "mb:uart0",
 		.clk		= &osc2_clk,
 	}, {	/* UART1 */
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c
index b2eda4d..7a1fa6a 100644
--- a/arch/arm/mach-w90x900/dev.c
+++ b/arch/arm/mach-w90x900/dev.c
@@ -36,6 +36,8 @@
 #include <mach/nuc900_spi.h>
 #include <mach/map.h>
 #include <mach/fb.h>
+#include <mach/regs-ldm.h>
+#include <mach/w90p910_keypad.h>
 
 #include "cpu.h"
 
@@ -207,7 +209,7 @@
 	.divider	= 24,
 	.sleep		= 0,
 	.txnum		= 0,
-	.txbitlen	= 1,
+	.txbitlen	= 8,
 	.bus_num	= 0,
 };
 
@@ -256,7 +258,7 @@
 		.modalias = "m25p80",
 		.max_speed_hz = 20000000,
 		.bus_num = 0,
-		.chip_select = 1,
+		.chip_select = 0,
 		.platform_data = &nuc900_spi_flash_data,
 		.mode = SPI_MODE_0,
 	},
@@ -361,6 +363,39 @@
 
 /* KPI controller*/
 
+static int nuc900_keymap[] = {
+	KEY(0, 0, KEY_A),
+	KEY(0, 1, KEY_B),
+	KEY(0, 2, KEY_C),
+	KEY(0, 3, KEY_D),
+
+	KEY(1, 0, KEY_E),
+	KEY(1, 1, KEY_F),
+	KEY(1, 2, KEY_G),
+	KEY(1, 3, KEY_H),
+
+	KEY(2, 0, KEY_I),
+	KEY(2, 1, KEY_J),
+	KEY(2, 2, KEY_K),
+	KEY(2, 3, KEY_L),
+
+	KEY(3, 0, KEY_M),
+	KEY(3, 1, KEY_N),
+	KEY(3, 2, KEY_O),
+	KEY(3, 3, KEY_P),
+};
+
+static struct matrix_keymap_data nuc900_map_data = {
+	.keymap			= nuc900_keymap,
+	.keymap_size		= ARRAY_SIZE(nuc900_keymap),
+};
+
+struct w90p910_keypad_platform_data nuc900_keypad_info = {
+	.keymap_data	= &nuc900_map_data,
+	.prescale	= 0xfa,
+	.debounce	= 0x50,
+};
+
 static struct resource nuc900_kpi_resource[] = {
 	[0] = {
 		.start = W90X900_PA_KPI,
@@ -380,9 +415,49 @@
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(nuc900_kpi_resource),
 	.resource	= nuc900_kpi_resource,
+	.dev		= {
+				.platform_data = &nuc900_keypad_info,
+			}
 };
 
-#ifdef CONFIG_FB_NUC900
+/* LCD controller*/
+
+static struct nuc900fb_display __initdata nuc900_lcd_info[] = {
+	/* Giantplus Technology GPM1040A0 320x240 Color TFT LCD */
+	[0] = {
+		.type		= LCM_DCCS_VA_SRC_RGB565,
+		.width		= 320,
+		.height		= 240,
+		.xres		= 320,
+		.yres		= 240,
+		.bpp		= 16,
+		.pixclock	= 200000,
+		.left_margin	= 34,
+		.right_margin   = 54,
+		.hsync_len	= 10,
+		.upper_margin	= 18,
+		.lower_margin	= 4,
+		.vsync_len	= 1,
+		.dccs		= 0x8e00041a,
+		.devctl		= 0x060800c0,
+		.fbctrl		= 0x00a000a0,
+		.scale		= 0x04000400,
+	},
+};
+
+static struct nuc900fb_mach_info nuc900_fb_info __initdata = {
+#if defined(CONFIG_GPM1040A0_320X240)
+	.displays		= &nuc900_lcd_info[0],
+#else
+	.displays		= nuc900_lcd_info,
+#endif
+	.num_displays		= ARRAY_SIZE(nuc900_lcd_info),
+	.default_display	= 0,
+	.gpio_dir		= 0x00000004,
+	.gpio_dir_mask		= 0xFFFFFFFD,
+	.gpio_data		= 0x00000004,
+	.gpio_data_mask		= 0xFFFFFFFD,
+};
 
 static struct resource nuc900_lcd_resource[] = {
 	[0] = {
@@ -406,23 +481,10 @@
 	.dev              = {
 		.dma_mask               = &nuc900_device_lcd_dmamask,
 		.coherent_dma_mask      = -1,
+		.platform_data = &nuc900_fb_info,
 	}
 };
 
-void  nuc900_fb_set_platdata(struct nuc900fb_mach_info *pd)
-{
-	struct nuc900fb_mach_info *npd;
-
-	npd = kmalloc(sizeof(*npd), GFP_KERNEL);
-	if (npd) {
-		memcpy(npd, pd, sizeof(*npd));
-		nuc900_device_lcd.dev.platform_data = npd;
-	} else {
-		printk(KERN_ERR "no memory for LCD platform data\n");
-	}
-}
-#endif
-
 /* AUDIO controller*/
 static u64 nuc900_device_audio_dmamask = -1;
 static struct resource nuc900_ac97_resource[] = {
diff --git a/arch/arm/mach-w90x900/include/mach/regs-gcr.h b/arch/arm/mach-w90x900/include/mach/regs-gcr.h
new file mode 100644
index 0000000..6087abd
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-gcr.h
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-gcr.h
+ *
+ * Copyright (c) 2010 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_GCR_H
+#define __ASM_ARCH_REGS_GCR_H
+
+/* Global control registers */
+
+#define GCR_BA		W90X900_VA_GCR
+#define REG_PDID	(GCR_BA+0x000)
+#define REG_PWRON	(GCR_BA+0x004)
+#define REG_ARBCON	(GCR_BA+0x008)
+#define REG_MFSEL	(GCR_BA+0x00C)
+#define REG_EBIDPE	(GCR_BA+0x010)
+#define REG_LCDDPE	(GCR_BA+0x014)
+#define REG_GPIOCPE	(GCR_BA+0x018)
+#define REG_GPIODPE	(GCR_BA+0x01C)
+#define REG_GPIOEPE	(GCR_BA+0x020)
+#define REG_GPIOFPE	(GCR_BA+0x024)
+#define REG_GPIOGPE	(GCR_BA+0x028)
+#define REG_GPIOHPE	(GCR_BA+0x02C)
+#define REG_GPIOIPE	(GCR_BA+0x030)
+#define REG_GTMP1	(GCR_BA+0x034)
+#define REG_GTMP2	(GCR_BA+0x038)
+#define REG_GTMP3	(GCR_BA+0x03C)
+
+#endif /*  __ASM_ARCH_REGS_GCR_H */
diff --git a/arch/arm/mach-w90x900/mach-nuc950evb.c b/arch/arm/mach-w90x900/mach-nuc950evb.c
index b3edc3c..04d295f 100644
--- a/arch/arm/mach-w90x900/mach-nuc950evb.c
+++ b/arch/arm/mach-w90x900/mach-nuc950evb.c
@@ -20,51 +20,10 @@
 #include <asm/mach/map.h>
 #include <asm/mach-types.h>
 #include <mach/map.h>
-#include <mach/regs-ldm.h>
 #include <mach/fb.h>
 
 #include "nuc950.h"
 
-#ifdef CONFIG_FB_NUC900
-/* LCD Controller */
-static struct nuc900fb_display __initdata nuc950_lcd_info[] = {
-	/* Giantplus Technology GPM1040A0 320x240 Color TFT LCD */
-	[0] = {
-		.type		= LCM_DCCS_VA_SRC_RGB565,
-		.width 		= 320,
-		.height		= 240,
-		.xres		= 320,
-		.yres		= 240,
-		.bpp		= 16,
-		.pixclock	= 200000,
-		.left_margin	= 34,
-		.right_margin   = 54,
-		.hsync_len	= 10,
-		.upper_margin	= 18,
-		.lower_margin	= 4,
-		.vsync_len	= 1,
-		.dccs		= 0x8e00041a,
-		.devctl		= 0x060800c0,
-		.fbctrl		= 0x00a000a0,
-		.scale		= 0x04000400,
-	},
-};
-
-static struct nuc900fb_mach_info nuc950_fb_info __initdata = {
-#if defined(CONFIG_GPM1040A0_320X240)
-	.displays		= &nuc950_lcd_info[0],
-#else
-	.displays		= nuc950_lcd_info,
-#endif
-	.num_displays 		= ARRAY_SIZE(nuc950_lcd_info),
-	.default_display	= 0,
-	.gpio_dir		= 0x00000004,
-	.gpio_dir_mask		= 0xFFFFFFFD,
-	.gpio_data		= 0x00000004,
-	.gpio_data_mask		= 0xFFFFFFFD,
-};
-#endif
-
 static void __init nuc950evb_map_io(void)
 {
 	nuc950_map_io();
@@ -74,9 +33,6 @@
 static void __init nuc950evb_init(void)
 {
 	nuc950_board_init();
-#ifdef CONFIG_FB_NUC900
-	nuc900_fb_set_platdata(&nuc950_fb_info);
-#endif
 }
 
 MACHINE_START(W90P950EVB, "W90P950EVB")
diff --git a/arch/arm/mach-w90x900/nuc910.c b/arch/arm/mach-w90x900/nuc910.c
index 656f03b..1523f41 100644
--- a/arch/arm/mach-w90x900/nuc910.c
+++ b/arch/arm/mach-w90x900/nuc910.c
@@ -26,6 +26,8 @@
 static struct platform_device *nuc910_dev[] __initdata = {
 	&nuc900_device_ts,
 	&nuc900_device_rtc,
+	&nuc900_device_lcd,
+	&nuc900_device_kpi,
 };
 
 /* define specific CPU platform io map */
diff --git a/arch/arm/mach-w90x900/nuc950.c b/arch/arm/mach-w90x900/nuc950.c
index 4d1f1ab..5704f74 100644
--- a/arch/arm/mach-w90x900/nuc950.c
+++ b/arch/arm/mach-w90x900/nuc950.c
@@ -26,9 +26,7 @@
 static struct platform_device *nuc950_dev[] __initdata = {
 	&nuc900_device_kpi,
 	&nuc900_device_fmi,
-#ifdef CONFIG_FB_NUC900
 	&nuc900_device_lcd,
-#endif
 };
 
 /* define specific CPU platform io map */
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 101105e..87ec141 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -717,17 +717,6 @@
 	  a few prototypes like that in existence) and therefore access to
 	  that required register must be emulated.
 
-config HAS_TLS_REG
-	bool
-	depends on !TLS_REG_EMUL
-	default y if SMP || CPU_32v7
-	help
-	  This selects support for the CP15 thread register.
-	  It is defined to be available on some ARMv6 processors (including
-	  all SMP capable ARMv6's) or later processors.  User space may
-	  assume directly accessing that register and always obtain the
-	  expected value only on ARMv7 and above.
-
 config NEEDS_SYSCALL_FOR_CMPXCHG
 	bool
 	help
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index e8d34a80..d63b6c4 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -15,7 +15,6 @@
 obj-$(CONFIG_MODULES)		+= proc-syms.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)	+= alignment.o
-obj-$(CONFIG_DISCONTIGMEM)	+= discontig.o
 obj-$(CONFIG_HIGHMEM)		+= highmem.o
 
 obj-$(CONFIG_CPU_ABRT_NOMMU)	+= abort-nommu.o
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 6f98c35..d073b64 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -924,8 +924,20 @@
 		ai_usermode = UM_FIXUP;
 	}
 
-	hook_fault_code(1, do_alignment, SIGILL, "alignment exception");
-	hook_fault_code(3, do_alignment, SIGILL, "alignment exception");
+	hook_fault_code(1, do_alignment, SIGBUS, BUS_ADRALN,
+			"alignment exception");
+
+	/*
+	 * ARMv6K and ARMv7 use fault status 3 (0b00011) as Access Flag section
+	 * fault, not as alignment error.
+	 *
+	 * TODO: handle ARMv6K properly. Runtime check for 'K' extension is
+	 * needed.
+	 */
+	if (cpu_architecture() <= CPU_ARCH_ARMv6) {
+		hook_fault_code(3, do_alignment, SIGBUS, BUS_ADRALN,
+				"alignment exception");
+	}
 
 	return 0;
 }
diff --git a/arch/arm/mm/discontig.c b/arch/arm/mm/discontig.c
deleted file mode 100644
index c8c0c4b..0000000
--- a/arch/arm/mm/discontig.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * linux/arch/arm/mm/discontig.c
- *
- * Discontiguous memory support.
- *
- * Initial code: Copyright (C) 1999-2000 Nicolas Pitre
- *
- * 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/module.h>
-#include <linux/mmzone.h>
-#include <linux/bootmem.h>
-
-#if MAX_NUMNODES != 4 && MAX_NUMNODES != 16
-# error Fix Me Please
-#endif
-
-/*
- * Our node_data structure for discontiguous memory.
- */
-
-pg_data_t discontig_node_data[MAX_NUMNODES] = {
-  { .bdata = &bootmem_node_data[0] },
-  { .bdata = &bootmem_node_data[1] },
-  { .bdata = &bootmem_node_data[2] },
-  { .bdata = &bootmem_node_data[3] },
-#if MAX_NUMNODES == 16
-  { .bdata = &bootmem_node_data[4] },
-  { .bdata = &bootmem_node_data[5] },
-  { .bdata = &bootmem_node_data[6] },
-  { .bdata = &bootmem_node_data[7] },
-  { .bdata = &bootmem_node_data[8] },
-  { .bdata = &bootmem_node_data[9] },
-  { .bdata = &bootmem_node_data[10] },
-  { .bdata = &bootmem_node_data[11] },
-  { .bdata = &bootmem_node_data[12] },
-  { .bdata = &bootmem_node_data[13] },
-  { .bdata = &bootmem_node_data[14] },
-  { .bdata = &bootmem_node_data[15] },
-#endif
-};
-
-EXPORT_SYMBOL(discontig_node_data);
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 9e7742f..c704eed 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -183,6 +183,8 @@
 __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
 {
 	struct arm_vmregion *c;
+	size_t align;
+	int bit;
 
 	if (!consistent_pte[0]) {
 		printk(KERN_ERR "%s: not initialised\n", __func__);
@@ -191,9 +193,20 @@
 	}
 
 	/*
+	 * Align the virtual region allocation - maximum alignment is
+	 * a section size, minimum is a page size.  This helps reduce
+	 * fragmentation of the DMA space, and also prevents allocations
+	 * smaller than a section from crossing a section boundary.
+	 */
+	bit = fls(size - 1) + 1;
+	if (bit > SECTION_SHIFT)
+		bit = SECTION_SHIFT;
+	align = 1 << bit;
+
+	/*
 	 * Allocate a virtual address in the consistent mapping region.
 	 */
-	c = arm_vmregion_alloc(&consistent_head, size,
+	c = arm_vmregion_alloc(&consistent_head, align, size,
 			    gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
 	if (c) {
 		pte_t *pte;
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index cbfb2ed..23b0b03 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -413,7 +413,16 @@
 	pmd_k = pmd_offset(pgd_k, addr);
 	pmd   = pmd_offset(pgd, addr);
 
-	if (pmd_none(*pmd_k))
+	/*
+	 * On ARM one Linux PGD entry contains two hardware entries (see page
+	 * tables layout in pgtable.h). We normally guarantee that we always
+	 * fill both L1 entries. But create_mapping() doesn't follow the rule.
+	 * It can create inidividual L1 entries, so here we have to call
+	 * pmd_none() check for the entry really corresponded to address, not
+	 * for the first of pair.
+	 */
+	index = (addr >> SECTION_SHIFT) & 1;
+	if (pmd_none(pmd_k[index]))
 		goto bad_area;
 
 	copy_pmd(pmd, pmd_k);
@@ -463,15 +472,10 @@
 	 * defines these to be "precise" aborts.
 	 */
 	{ do_bad,		SIGSEGV, 0,		"vector exception"		   },
-	{ do_bad,		SIGILL,	 BUS_ADRALN,	"alignment exception"		   },
+	{ do_bad,		SIGBUS,	 BUS_ADRALN,	"alignment exception"		   },
 	{ do_bad,		SIGKILL, 0,		"terminal exception"		   },
-	{ do_bad,		SIGILL,	 BUS_ADRALN,	"alignment exception"		   },
-/* Do we need runtime check ? */
-#if __LINUX_ARM_ARCH__ < 6
+	{ do_bad,		SIGBUS,	 BUS_ADRALN,	"alignment exception"		   },
 	{ do_bad,		SIGBUS,	 0,		"external abort on linefetch"	   },
-#else
-	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"I-cache maintenance fault"	   },
-#endif
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"section translation fault"	   },
 	{ do_bad,		SIGBUS,	 0,		"external abort on linefetch"	   },
 	{ do_page_fault,	SIGSEGV, SEGV_MAPERR,	"page translation fault"	   },
@@ -508,13 +512,15 @@
 
 void __init
 hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
-		int sig, const char *name)
+		int sig, int code, const char *name)
 {
-	if (nr >= 0 && nr < ARRAY_SIZE(fsr_info)) {
-		fsr_info[nr].fn   = fn;
-		fsr_info[nr].sig  = sig;
-		fsr_info[nr].name = name;
-	}
+	if (nr < 0 || nr >= ARRAY_SIZE(fsr_info))
+		BUG();
+
+	fsr_info[nr].fn   = fn;
+	fsr_info[nr].sig  = sig;
+	fsr_info[nr].code = code;
+	fsr_info[nr].name = name;
 }
 
 /*
@@ -594,3 +600,25 @@
 	arm_notify_die("", regs, &info, ifsr, 0);
 }
 
+static int __init exceptions_init(void)
+{
+	if (cpu_architecture() >= CPU_ARCH_ARMv6) {
+		hook_fault_code(4, do_translation_fault, SIGSEGV, SEGV_MAPERR,
+				"I-cache maintenance fault");
+	}
+
+	if (cpu_architecture() >= CPU_ARCH_ARMv7) {
+		/*
+		 * TODO: Access flag faults introduced in ARMv6K.
+		 * Runtime check for 'K' extension is needed
+		 */
+		hook_fault_code(3, do_bad, SIGSEGV, SEGV_MAPERR,
+				"section access flag fault");
+		hook_fault_code(6, do_bad, SIGSEGV, SEGV_MAPERR,
+				"section access flag fault");
+	}
+
+	return 0;
+}
+
+arch_initcall(exceptions_init);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index e18c7ced..7185b00 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -17,6 +17,7 @@
 #include <linux/initrd.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
+#include <linux/memblock.h>
 
 #include <asm/mach-types.h>
 #include <asm/sections.h>
@@ -79,38 +80,37 @@
 void show_mem(void)
 {
 	int free = 0, total = 0, reserved = 0;
-	int shared = 0, cached = 0, slab = 0, node, i;
+	int shared = 0, cached = 0, slab = 0, i;
 	struct meminfo * mi = &meminfo;
 
 	printk("Mem-info:\n");
 	show_free_areas();
-	for_each_online_node(node) {
-		for_each_nodebank (i,mi,node) {
-			struct membank *bank = &mi->bank[i];
-			unsigned int pfn1, pfn2;
-			struct page *page, *end;
 
-			pfn1 = bank_pfn_start(bank);
-			pfn2 = bank_pfn_end(bank);
+	for_each_bank (i, mi) {
+		struct membank *bank = &mi->bank[i];
+		unsigned int pfn1, pfn2;
+		struct page *page, *end;
 
-			page = pfn_to_page(pfn1);
-			end  = pfn_to_page(pfn2 - 1) + 1;
+		pfn1 = bank_pfn_start(bank);
+		pfn2 = bank_pfn_end(bank);
 
-			do {
-				total++;
-				if (PageReserved(page))
-					reserved++;
-				else if (PageSwapCache(page))
-					cached++;
-				else if (PageSlab(page))
-					slab++;
-				else if (!page_count(page))
-					free++;
-				else
-					shared += page_count(page) - 1;
-				page++;
-			} while (page < end);
-		}
+		page = pfn_to_page(pfn1);
+		end  = pfn_to_page(pfn2 - 1) + 1;
+
+		do {
+			total++;
+			if (PageReserved(page))
+				reserved++;
+			else if (PageSwapCache(page))
+				cached++;
+			else if (PageSlab(page))
+				slab++;
+			else if (!page_count(page))
+				free++;
+			else
+				shared += page_count(page) - 1;
+			page++;
+		} while (page < end);
 	}
 
 	printk("%d pages of RAM\n", total);
@@ -121,7 +121,7 @@
 	printk("%d pages swap cached\n", cached);
 }
 
-static void __init find_node_limits(int node, struct meminfo *mi,
+static void __init find_limits(struct meminfo *mi,
 	unsigned long *min, unsigned long *max_low, unsigned long *max_high)
 {
 	int i;
@@ -129,7 +129,7 @@
 	*min = -1UL;
 	*max_low = *max_high = 0;
 
-	for_each_nodebank(i, mi, node) {
+	for_each_bank (i, mi) {
 		struct membank *bank = &mi->bank[i];
 		unsigned long start, end;
 
@@ -147,155 +147,64 @@
 	}
 }
 
-/*
- * FIXME: We really want to avoid allocating the bootmap bitmap
- * over the top of the initrd.  Hopefully, this is located towards
- * the start of a bank, so if we allocate the bootmap bitmap at
- * the end, we won't clash.
- */
-static unsigned int __init
-find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
-{
-	unsigned int start_pfn, i, bootmap_pfn;
-
-	start_pfn   = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT;
-	bootmap_pfn = 0;
-
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-		unsigned int start, end;
-
-		start = bank_pfn_start(bank);
-		end   = bank_pfn_end(bank);
-
-		if (end < start_pfn)
-			continue;
-
-		if (start < start_pfn)
-			start = start_pfn;
-
-		if (end <= start)
-			continue;
-
-		if (end - start >= bootmap_pages) {
-			bootmap_pfn = start;
-			break;
-		}
-	}
-
-	if (bootmap_pfn == 0)
-		BUG();
-
-	return bootmap_pfn;
-}
-
-static int __init check_initrd(struct meminfo *mi)
-{
-	int initrd_node = -2;
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long end = phys_initrd_start + phys_initrd_size;
-
-	/*
-	 * Make sure that the initrd is within a valid area of
-	 * memory.
-	 */
-	if (phys_initrd_size) {
-		unsigned int i;
-
-		initrd_node = -1;
-
-		for (i = 0; i < mi->nr_banks; i++) {
-			struct membank *bank = &mi->bank[i];
-			if (bank_phys_start(bank) <= phys_initrd_start &&
-			    end <= bank_phys_end(bank))
-				initrd_node = bank->node;
-		}
-	}
-
-	if (initrd_node == -1) {
-		printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond "
-		       "physical memory - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
-		phys_initrd_start = phys_initrd_size = 0;
-	}
-#endif
-
-	return initrd_node;
-}
-
-static void __init bootmem_init_node(int node, struct meminfo *mi,
+static void __init arm_bootmem_init(struct meminfo *mi,
 	unsigned long start_pfn, unsigned long end_pfn)
 {
-	unsigned long boot_pfn;
 	unsigned int boot_pages;
+	phys_addr_t bitmap;
 	pg_data_t *pgdat;
 	int i;
 
 	/*
-	 * Allocate the bootmem bitmap page.
+	 * Allocate the bootmem bitmap page.  This must be in a region
+	 * of memory which has already been mapped.
 	 */
 	boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
-	boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
+	bitmap = memblock_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES,
+				__pfn_to_phys(end_pfn));
 
 	/*
-	 * Initialise the bootmem allocator for this node, handing the
+	 * Initialise the bootmem allocator, handing the
 	 * memory banks over to bootmem.
 	 */
-	node_set_online(node);
-	pgdat = NODE_DATA(node);
-	init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
+	node_set_online(0);
+	pgdat = NODE_DATA(0);
+	init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
 
-	for_each_nodebank(i, mi, node) {
+	for_each_bank(i, mi) {
 		struct membank *bank = &mi->bank[i];
 		if (!bank->highmem)
-			free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
+			free_bootmem(bank_phys_start(bank), bank_phys_size(bank));
 	}
 
 	/*
-	 * Reserve the bootmem bitmap for this node.
+	 * Reserve the memblock reserved regions in bootmem.
 	 */
-	reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
-			     boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
-}
-
-static void __init bootmem_reserve_initrd(int node)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	pg_data_t *pgdat = NODE_DATA(node);
-	int res;
-
-	res = reserve_bootmem_node(pgdat, phys_initrd_start,
-			     phys_initrd_size, BOOTMEM_EXCLUSIVE);
-
-	if (res == 0) {
-		initrd_start = __phys_to_virt(phys_initrd_start);
-		initrd_end = initrd_start + phys_initrd_size;
-	} else {
-		printk(KERN_ERR
-			"INITRD: 0x%08lx+0x%08lx overlaps in-use "
-			"memory region - disabling initrd\n",
-			phys_initrd_start, phys_initrd_size);
+	for (i = 0; i < memblock.reserved.cnt; i++) {
+		phys_addr_t start = memblock_start_pfn(&memblock.reserved, i);
+		if (start >= start_pfn &&
+		    memblock_end_pfn(&memblock.reserved, i) <= end_pfn)
+			reserve_bootmem_node(pgdat, __pfn_to_phys(start),
+				memblock_size_bytes(&memblock.reserved, i),
+				BOOTMEM_DEFAULT);
 	}
-#endif
 }
 
-static void __init bootmem_free_node(int node, struct meminfo *mi)
+static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,
+	unsigned long max_low, unsigned long max_high)
 {
 	unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
-	unsigned long min, max_low, max_high;
 	int i;
 
-	find_node_limits(node, mi, &min, &max_low, &max_high);
-
 	/*
-	 * initialise the zones within this node.
+	 * initialise the zones.
 	 */
 	memset(zone_size, 0, sizeof(zone_size));
 
 	/*
-	 * The size of this node has already been determined.  If we need
-	 * to do anything fancy with the allocation of this memory to the
-	 * zones, now is the time to do it.
+	 * The memory size has already been determined.  If we need
+	 * to do anything fancy with the allocation of this memory
+	 * to the zones, now is the time to do it.
 	 */
 	zone_size[0] = max_low - min;
 #ifdef CONFIG_HIGHMEM
@@ -303,11 +212,11 @@
 #endif
 
 	/*
-	 * For each bank in this node, calculate the size of the holes.
-	 *  holes = node_size - sum(bank_sizes_in_node)
+	 * Calculate the size of the holes.
+	 *  holes = node_size - sum(bank_sizes)
 	 */
 	memcpy(zhole_size, zone_size, sizeof(zhole_size));
-	for_each_nodebank(i, mi, node) {
+	for_each_bank(i, mi) {
 		int idx = 0;
 #ifdef CONFIG_HIGHMEM
 		if (mi->bank[i].highmem)
@@ -320,24 +229,23 @@
 	 * Adjust the sizes according to any special requirements for
 	 * this machine type.
 	 */
-	arch_adjust_zones(node, zone_size, zhole_size);
+	arch_adjust_zones(zone_size, zhole_size);
 
-	free_area_init_node(node, zone_size, min, zhole_size);
+	free_area_init_node(0, zone_size, min, zhole_size);
 }
 
 #ifndef CONFIG_SPARSEMEM
 int pfn_valid(unsigned long pfn)
 {
-	struct meminfo *mi = &meminfo;
-	unsigned int left = 0, right = mi->nr_banks;
+	struct memblock_region *mem = &memblock.memory;
+	unsigned int left = 0, right = mem->cnt;
 
 	do {
 		unsigned int mid = (right + left) / 2;
-		struct membank *bank = &mi->bank[mid];
 
-		if (pfn < bank_pfn_start(bank))
+		if (pfn < memblock_start_pfn(mem, mid))
 			right = mid;
-		else if (pfn >= bank_pfn_end(bank))
+		else if (pfn >= memblock_end_pfn(mem, mid))
 			left = mid + 1;
 		else
 			return 1;
@@ -346,73 +254,69 @@
 }
 EXPORT_SYMBOL(pfn_valid);
 
-static void arm_memory_present(struct meminfo *mi, int node)
+static void arm_memory_present(void)
 {
 }
 #else
-static void arm_memory_present(struct meminfo *mi, int node)
+static void arm_memory_present(void)
 {
 	int i;
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-		memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
-	}
+	for (i = 0; i < memblock.memory.cnt; i++)
+		memory_present(0, memblock_start_pfn(&memblock.memory, i),
+				  memblock_end_pfn(&memblock.memory, i));
 }
 #endif
 
+void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
+{
+	int i;
+
+	memblock_init();
+	for (i = 0; i < mi->nr_banks; i++)
+		memblock_add(mi->bank[i].start, mi->bank[i].size);
+
+	/* Register the kernel text, kernel data and initrd with memblock. */
+#ifdef CONFIG_XIP_KERNEL
+	memblock_reserve(__pa(_data), _end - _data);
+#else
+	memblock_reserve(__pa(_stext), _end - _stext);
+#endif
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (phys_initrd_size) {
+		memblock_reserve(phys_initrd_start, phys_initrd_size);
+
+		/* Now convert initrd to virtual addresses */
+		initrd_start = __phys_to_virt(phys_initrd_start);
+		initrd_end = initrd_start + phys_initrd_size;
+	}
+#endif
+
+	arm_mm_memblock_reserve();
+
+	/* reserve any platform specific memblock areas */
+	if (mdesc->reserve)
+		mdesc->reserve();
+
+	memblock_analyze();
+	memblock_dump_all();
+}
+
 void __init bootmem_init(void)
 {
 	struct meminfo *mi = &meminfo;
 	unsigned long min, max_low, max_high;
-	int node, initrd_node;
-
-	/*
-	 * Locate which node contains the ramdisk image, if any.
-	 */
-	initrd_node = check_initrd(mi);
 
 	max_low = max_high = 0;
 
+	find_limits(mi, &min, &max_low, &max_high);
+
+	arm_bootmem_init(mi, min, max_low);
+
 	/*
-	 * Run through each node initialising the bootmem allocator.
+	 * Sparsemem tries to allocate bootmem in memory_present(),
+	 * so must be done after the fixed reservations
 	 */
-	for_each_node(node) {
-		unsigned long node_low, node_high;
-
-		find_node_limits(node, mi, &min, &node_low, &node_high);
-
-		if (node_low > max_low)
-			max_low = node_low;
-		if (node_high > max_high)
-			max_high = node_high;
-
-		/*
-		 * If there is no memory in this node, ignore it.
-		 * (We can't have nodes which have no lowmem)
-		 */
-		if (node_low == 0)
-			continue;
-
-		bootmem_init_node(node, mi, min, node_low);
-
-		/*
-		 * Reserve any special node zero regions.
-		 */
-		if (node == 0)
-			reserve_node_zero(NODE_DATA(node));
-
-		/*
-		 * If the initrd is in this node, reserve its memory.
-		 */
-		if (node == initrd_node)
-			bootmem_reserve_initrd(node);
-
-		/*
-		 * Sparsemem tries to allocate bootmem in memory_present(),
-		 * so must be done after the fixed reservations
-		 */
-		arm_memory_present(mi, node);
-	}
+	arm_memory_present();
 
 	/*
 	 * sparse_init() needs the bootmem allocator up and running.
@@ -420,12 +324,11 @@
 	sparse_init();
 
 	/*
-	 * Now free memory in each node - free_area_init_node needs
+	 * Now free the memory - free_area_init_node needs
 	 * the sparse mem_map arrays initialized by sparse_init()
 	 * for memmap_init_zone(), otherwise all PFNs are invalid.
 	 */
-	for_each_node(node)
-		bootmem_free_node(node, mi);
+	arm_bootmem_free(mi, min, max_low, max_high);
 
 	high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1;
 
@@ -460,7 +363,7 @@
 }
 
 static inline void
-free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn)
+free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 {
 	struct page *start_pg, *end_pg;
 	unsigned long pg, pgend;
@@ -483,13 +386,13 @@
 	 * free the section of the memmap array.
 	 */
 	if (pg < pgend)
-		free_bootmem_node(NODE_DATA(node), pg, pgend - pg);
+		free_bootmem(pg, pgend - pg);
 }
 
 /*
  * The mem_map array can get very big.  Free the unused area of the memory map.
  */
-static void __init free_unused_memmap_node(int node, struct meminfo *mi)
+static void __init free_unused_memmap(struct meminfo *mi)
 {
 	unsigned long bank_start, prev_bank_end = 0;
 	unsigned int i;
@@ -498,7 +401,7 @@
 	 * This relies on each bank being in address order.
 	 * The banks are sorted previously in bootmem_init().
 	 */
-	for_each_nodebank(i, mi, node) {
+	for_each_bank(i, mi) {
 		struct membank *bank = &mi->bank[i];
 
 		bank_start = bank_pfn_start(bank);
@@ -508,7 +411,7 @@
 		 * between the current bank and the previous, free it.
 		 */
 		if (prev_bank_end && prev_bank_end < bank_start)
-			free_memmap(node, prev_bank_end, bank_start);
+			free_memmap(prev_bank_end, bank_start);
 
 		/*
 		 * Align up here since the VM subsystem insists that the
@@ -527,21 +430,19 @@
 void __init mem_init(void)
 {
 	unsigned long reserved_pages, free_pages;
-	int i, node;
-
-#ifndef CONFIG_DISCONTIGMEM
-	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
+	int i;
+#ifdef CONFIG_HAVE_TCM
+	/* These pointers are filled in on TCM detection */
+	extern u32 dtcm_end;
+	extern u32 itcm_end;
 #endif
 
+	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
+
 	/* this will put all unused low memory onto the freelists */
-	for_each_online_node(node) {
-		pg_data_t *pgdat = NODE_DATA(node);
+	free_unused_memmap(&meminfo);
 
-		free_unused_memmap_node(node, &meminfo);
-
-		if (pgdat->node_spanned_pages != 0)
-			totalram_pages += free_all_bootmem_node(pgdat);
-	}
+	totalram_pages += free_all_bootmem();
 
 #ifdef CONFIG_SA1111
 	/* now that our DMA memory is actually so designated, we can free it */
@@ -551,39 +452,35 @@
 
 #ifdef CONFIG_HIGHMEM
 	/* set highmem page free */
-	for_each_online_node(node) {
-		for_each_nodebank (i, &meminfo, node) {
-			unsigned long start = bank_pfn_start(&meminfo.bank[i]);
-			unsigned long end = bank_pfn_end(&meminfo.bank[i]);
-			if (start >= max_low_pfn + PHYS_PFN_OFFSET)
-				totalhigh_pages += free_area(start, end, NULL);
-		}
+	for_each_bank (i, &meminfo) {
+		unsigned long start = bank_pfn_start(&meminfo.bank[i]);
+		unsigned long end = bank_pfn_end(&meminfo.bank[i]);
+		if (start >= max_low_pfn + PHYS_PFN_OFFSET)
+			totalhigh_pages += free_area(start, end, NULL);
 	}
 	totalram_pages += totalhigh_pages;
 #endif
 
 	reserved_pages = free_pages = 0;
 
-	for_each_online_node(node) {
-		for_each_nodebank(i, &meminfo, node) {
-			struct membank *bank = &meminfo.bank[i];
-			unsigned int pfn1, pfn2;
-			struct page *page, *end;
+	for_each_bank(i, &meminfo) {
+		struct membank *bank = &meminfo.bank[i];
+		unsigned int pfn1, pfn2;
+		struct page *page, *end;
 
-			pfn1 = bank_pfn_start(bank);
-			pfn2 = bank_pfn_end(bank);
+		pfn1 = bank_pfn_start(bank);
+		pfn2 = bank_pfn_end(bank);
 
-			page = pfn_to_page(pfn1);
-			end  = pfn_to_page(pfn2 - 1) + 1;
+		page = pfn_to_page(pfn1);
+		end  = pfn_to_page(pfn2 - 1) + 1;
 
-			do {
-				if (PageReserved(page))
-					reserved_pages++;
-				else if (!page_count(page))
-					free_pages++;
-				page++;
-			} while (page < end);
-		}
+		do {
+			if (PageReserved(page))
+				reserved_pages++;
+			else if (!page_count(page))
+				free_pages++;
+			page++;
+		} while (page < end);
 	}
 
 	/*
@@ -610,6 +507,10 @@
 
 	printk(KERN_NOTICE "Virtual kernel memory layout:\n"
 			"    vector  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+#ifdef CONFIG_HAVE_TCM
+			"    DTCM    : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+			"    ITCM    : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+#endif
 			"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
 #ifdef CONFIG_MMU
 			"    DMA     : 0x%08lx - 0x%08lx   (%4ld MB)\n"
@@ -626,6 +527,10 @@
 
 			MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
 				(PAGE_SIZE)),
+#ifdef CONFIG_HAVE_TCM
+			MLK(DTCM_OFFSET, (unsigned long) dtcm_end),
+			MLK(ITCM_OFFSET, (unsigned long) itcm_end),
+#endif
 			MLK(FIXADDR_START, FIXADDR_TOP),
 #ifdef CONFIG_MMU
 			MLM(CONSISTENT_BASE, CONSISTENT_END),
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 28c8b95..ab50627 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -42,78 +42,11 @@
  */
 #define VM_ARM_SECTION_MAPPING	0x80000000
 
-static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end,
-			  unsigned long phys_addr, const struct mem_type *type)
-{
-	pgprot_t prot = __pgprot(type->prot_pte);
-	pte_t *pte;
-
-	pte = pte_alloc_kernel(pmd, addr);
-	if (!pte)
-		return -ENOMEM;
-
-	do {
-		if (!pte_none(*pte))
-			goto bad;
-
-		set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0);
-		phys_addr += PAGE_SIZE;
-	} while (pte++, addr += PAGE_SIZE, addr != end);
-	return 0;
-
- bad:
-	printk(KERN_CRIT "remap_area_pte: page already exists\n");
-	BUG();
-}
-
-static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr,
-				 unsigned long end, unsigned long phys_addr,
-				 const struct mem_type *type)
-{
-	unsigned long next;
-	pmd_t *pmd;
-	int ret = 0;
-
-	pmd = pmd_alloc(&init_mm, pgd, addr);
-	if (!pmd)
-		return -ENOMEM;
-
-	do {
-		next = pmd_addr_end(addr, end);
-		ret = remap_area_pte(pmd, addr, next, phys_addr, type);
-		if (ret)
-			return ret;
-		phys_addr += next - addr;
-	} while (pmd++, addr = next, addr != end);
-	return ret;
-}
-
-static int remap_area_pages(unsigned long start, unsigned long pfn,
-			    size_t size, const struct mem_type *type)
-{
-	unsigned long addr = start;
-	unsigned long next, end = start + size;
-	unsigned long phys_addr = __pfn_to_phys(pfn);
-	pgd_t *pgd;
-	int err = 0;
-
-	BUG_ON(addr >= end);
-	pgd = pgd_offset_k(addr);
-	do {
-		next = pgd_addr_end(addr, end);
-		err = remap_area_pmd(pgd, addr, next, phys_addr, type);
-		if (err)
-			break;
-		phys_addr += next - addr;
-	} while (pgd++, addr = next, addr != end);
-
-	return err;
-}
-
 int ioremap_page(unsigned long virt, unsigned long phys,
 		 const struct mem_type *mtype)
 {
-	return remap_area_pages(virt, __phys_to_pfn(phys), PAGE_SIZE, mtype);
+	return ioremap_page_range(virt, virt + PAGE_SIZE, phys,
+				  __pgprot(mtype->prot_pte));
 }
 EXPORT_SYMBOL(ioremap_page);
 
@@ -268,6 +201,12 @@
 	if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
 		return NULL;
 
+	/*
+	 * Don't allow RAM to be mapped - this causes problems with ARMv6+
+	 */
+	if (WARN_ON(pfn_valid(pfn)))
+		return NULL;
+
 	type = get_mem_type(mtype);
 	if (!type)
 		return NULL;
@@ -294,7 +233,8 @@
 		err = remap_area_sections(addr, pfn, size, type);
 	} else
 #endif
-		err = remap_area_pages(addr, pfn, size, type);
+		err = ioremap_page_range(addr, addr + size, __pfn_to_phys(pfn),
+					 __pgprot(type->prot_pte));
 
 	if (err) {
  		vunmap((void *)addr);
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 815d08e..6630620 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -28,7 +28,5 @@
 
 #endif
 
-struct pglist_data;
-
 void __init bootmem_init(void);
-void reserve_node_zero(struct pglist_data *pgdat);
+void arm_mm_memblock_reserve(void);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 2858941..6e1c4f6 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -11,13 +11,12 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
+#include <linux/memblock.h>
 #include <linux/sort.h>
 
 #include <asm/cputype.h>
-#include <asm/mach-types.h>
 #include <asm/sections.h>
 #include <asm/cachetype.h>
 #include <asm/setup.h>
@@ -258,6 +257,19 @@
 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_KERNEL,
 	},
+	[MT_MEMORY_DTCM] = {
+		.prot_pte	= L_PTE_PRESENT | L_PTE_YOUNG |
+		                  L_PTE_DIRTY | L_PTE_WRITE,
+		.prot_l1	= PMD_TYPE_TABLE,
+		.prot_sect	= PMD_TYPE_SECT | PMD_SECT_XN,
+		.domain		= DOMAIN_KERNEL,
+	},
+	[MT_MEMORY_ITCM] = {
+		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+				L_PTE_USER | L_PTE_EXEC,
+		.prot_l1   = PMD_TYPE_TABLE,
+		.domain    = DOMAIN_IO,
+	},
 };
 
 const struct mem_type *get_mem_type(unsigned int type)
@@ -488,18 +500,28 @@
 
 #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
 
+static void __init *early_alloc(unsigned long sz)
+{
+	void *ptr = __va(memblock_alloc(sz, sz));
+	memset(ptr, 0, sz);
+	return ptr;
+}
+
+static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
+{
+	if (pmd_none(*pmd)) {
+		pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
+		__pmd_populate(pmd, __pa(pte) | prot);
+	}
+	BUG_ON(pmd_bad(*pmd));
+	return pte_offset_kernel(pmd, addr);
+}
+
 static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
 				  unsigned long end, unsigned long pfn,
 				  const struct mem_type *type)
 {
-	pte_t *pte;
-
-	if (pmd_none(*pmd)) {
-		pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
-		__pmd_populate(pmd, __pa(pte) | type->prot_l1);
-	}
-
-	pte = pte_offset_kernel(pmd, addr);
+	pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1);
 	do {
 		set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
 		pfn++;
@@ -668,7 +690,7 @@
 		create_mapping(io_desc + i);
 }
 
-static unsigned long __initdata vmalloc_reserve = SZ_128M;
+static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M);
 
 /*
  * vmalloc=size forces the vmalloc area to be exactly 'size'
@@ -677,7 +699,7 @@
  */
 static int __init early_vmalloc(char *arg)
 {
-	vmalloc_reserve = memparse(arg, NULL);
+	unsigned long vmalloc_reserve = memparse(arg, NULL);
 
 	if (vmalloc_reserve < SZ_16M) {
 		vmalloc_reserve = SZ_16M;
@@ -692,22 +714,26 @@
 			"vmalloc area is too big, limiting to %luMB\n",
 			vmalloc_reserve >> 20);
 	}
+
+	vmalloc_min = (void *)(VMALLOC_END - vmalloc_reserve);
 	return 0;
 }
 early_param("vmalloc", early_vmalloc);
 
-#define VMALLOC_MIN	(void *)(VMALLOC_END - vmalloc_reserve)
+phys_addr_t lowmem_end_addr;
 
 static void __init sanity_check_meminfo(void)
 {
 	int i, j, highmem = 0;
 
+	lowmem_end_addr = __pa(vmalloc_min - 1) + 1;
+
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
 		*bank = meminfo.bank[i];
 
 #ifdef CONFIG_HIGHMEM
-		if (__va(bank->start) > VMALLOC_MIN ||
+		if (__va(bank->start) > vmalloc_min ||
 		    __va(bank->start) < (void *)PAGE_OFFSET)
 			highmem = 1;
 
@@ -717,8 +743,8 @@
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
 		 */
-		if (__va(bank->start) < VMALLOC_MIN &&
-		    bank->size > VMALLOC_MIN - __va(bank->start)) {
+		if (__va(bank->start) < vmalloc_min &&
+		    bank->size > vmalloc_min - __va(bank->start)) {
 			if (meminfo.nr_banks >= NR_BANKS) {
 				printk(KERN_CRIT "NR_BANKS too low, "
 						 "ignoring high memory\n");
@@ -727,12 +753,12 @@
 					(meminfo.nr_banks - i) * sizeof(*bank));
 				meminfo.nr_banks++;
 				i++;
-				bank[1].size -= VMALLOC_MIN - __va(bank->start);
-				bank[1].start = __pa(VMALLOC_MIN - 1) + 1;
+				bank[1].size -= vmalloc_min - __va(bank->start);
+				bank[1].start = __pa(vmalloc_min - 1) + 1;
 				bank[1].highmem = highmem = 1;
 				j++;
 			}
-			bank->size = VMALLOC_MIN - __va(bank->start);
+			bank->size = vmalloc_min - __va(bank->start);
 		}
 #else
 		bank->highmem = highmem;
@@ -741,7 +767,7 @@
 		 * Check whether this memory bank would entirely overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start) >= VMALLOC_MIN ||
+		if (__va(bank->start) >= vmalloc_min ||
 		    __va(bank->start) < (void *)PAGE_OFFSET) {
 			printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
 			       "(vmalloc region overlap).\n",
@@ -753,9 +779,9 @@
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start + bank->size) > VMALLOC_MIN ||
+		if (__va(bank->start + bank->size) > vmalloc_min ||
 		    __va(bank->start + bank->size) < __va(bank->start)) {
-			unsigned long newsize = VMALLOC_MIN - __va(bank->start);
+			unsigned long newsize = vmalloc_min - __va(bank->start);
 			printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
 			       "to -%.8lx (vmalloc region overlap).\n",
 			       bank->start, bank->start + bank->size - 1,
@@ -827,101 +853,23 @@
 }
 
 /*
- * Reserve the various regions of node 0
+ * Reserve the special regions of memory
  */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_memblock_reserve(void)
 {
-	unsigned long res_size = 0;
-
-	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
 	/*
 	 * Reserve the page tables.  These are already in use,
 	 * and can only be in node 0.
 	 */
-	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
-			     PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT);
-
-	/*
-	 * Hmm... This should go elsewhere, but we really really need to
-	 * stop things allocating the low memory; ideally we need a better
-	 * implementation of GFP_DMA which does not assume that DMA-able
-	 * memory starts at zero.
-	 */
-	if (machine_is_integrator() || machine_is_cintegrator())
-		res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
-
-	/*
-	 * These should likewise go elsewhere.  They pre-reserve the
-	 * screen memory region at the start of main system memory.
-	 */
-	if (machine_is_edb7211())
-		res_size = 0x00020000;
-	if (machine_is_p720t())
-		res_size = 0x00014000;
-
-	/* H1940, RX3715 and RX1950 need to reserve this for suspend */
-
-	if (machine_is_h1940() || machine_is_rx3715()
-		|| machine_is_rx1950()) {
-		reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
-				BOOTMEM_DEFAULT);
-		reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
-				BOOTMEM_DEFAULT);
-	}
-
-	if (machine_is_palmld() || machine_is_palmtx()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_treo680() || machine_is_centro()) {
-		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-		reserve_bootmem_node(pgdat, 0xa2000000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-	}
-
-	if (machine_is_palmt5())
-		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
-				BOOTMEM_EXCLUSIVE);
-
-	/*
-	 * U300 - This platform family can share physical memory
-	 * between two ARM cpus, one running Linux and the other
-	 * running another OS.
-	 */
-	if (machine_is_u300()) {
-#ifdef CONFIG_MACH_U300_SINGLE_RAM
-#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) &&	\
-	CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
-		res_size = 0x00100000;
-#endif
-#endif
-	}
+	memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
 
 #ifdef CONFIG_SA1111
 	/*
 	 * Because of the SA1111 DMA bug, we want to preserve our
 	 * precious DMA-able memory...
 	 */
-	res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+	memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
 #endif
-	if (res_size)
-		reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size,
-				BOOTMEM_DEFAULT);
 }
 
 /*
@@ -940,7 +888,7 @@
 	/*
 	 * Allocate the vector page early.
 	 */
-	vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+	vectors = early_alloc(PAGE_SIZE);
 
 	for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
 		pmd_clear(pmd_off_k(addr));
@@ -1011,11 +959,8 @@
 static void __init kmap_init(void)
 {
 #ifdef CONFIG_HIGHMEM
-	pmd_t *pmd = pmd_off_k(PKMAP_BASE);
-	pte_t *pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
-	BUG_ON(!pmd_none(*pmd) || !pte);
-	__pmd_populate(pmd, __pa(pte) | _PAGE_KERNEL_TABLE);
-	pkmap_page_table = pte + PTRS_PER_PTE;
+	pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
+		PKMAP_BASE, _PAGE_KERNEL_TABLE);
 #endif
 }
 
@@ -1066,17 +1011,16 @@
 	sanity_check_meminfo();
 	prepare_page_table();
 	map_lowmem();
-	bootmem_init();
 	devicemaps_init(mdesc);
 	kmap_init();
 
 	top_pmd = pmd_off_k(0xffff0000);
 
-	/*
-	 * allocate the zero page.  Note that this always succeeds and
-	 * returns a zeroed result.
-	 */
-	zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+	/* allocate the zero page. */
+	zero_page = early_alloc(PAGE_SIZE);
+
+	bootmem_init();
+
 	empty_zero_page = virt_to_page(zero_page);
 	__flush_dcache_page(NULL, empty_zero_page);
 }
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 33b3273..687d023 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -6,8 +6,8 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
+#include <linux/memblock.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
@@ -17,30 +17,14 @@
 
 #include "mm.h"
 
-/*
- * Reserve the various regions of node 0
- */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_memblock_reserve(void)
 {
 	/*
-	 * Register the kernel text and data with bootmem.
-	 * Note that this can only be in node 0.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
-			BOOTMEM_DEFAULT);
-#else
-	reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
-			BOOTMEM_DEFAULT);
-#endif
-
-	/*
 	 * Register the exception vector page.
 	 * some architectures which the DRAM is the exception vector to trap,
 	 * alloc_page breaks with error, although it is not NULL, but "0."
 	 */
-	reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE,
-			BOOTMEM_DEFAULT);
+	memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
 }
 
 /*
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 72507c6..203a4e9 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -79,15 +79,11 @@
  * cpu_arm1020_proc_fin()
  */
 ENTRY(cpu_arm1020_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	arm1020_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000 		@ ...i............
 	bic	r0, r0, #0x000e 		@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm1020_reset(loc)
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index d278298..1a511e7 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -79,15 +79,11 @@
  * cpu_arm1020e_proc_fin()
  */
 ENTRY(cpu_arm1020e_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	arm1020e_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000 		@ ...i............
 	bic	r0, r0, #0x000e 		@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm1020e_reset(loc)
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index ce13e4a..1ffa4eb 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -68,15 +68,11 @@
  * cpu_arm1022_proc_fin()
  */
 ENTRY(cpu_arm1022_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	arm1022_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000 		@ ...i............
 	bic	r0, r0, #0x000e 		@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm1022_reset(loc)
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 636672a..5697c34 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -68,15 +68,11 @@
  * cpu_arm1026_proc_fin()
  */
 ENTRY(cpu_arm1026_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	arm1026_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000 		@ ...i............
 	bic	r0, r0, #0x000e 		@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm1026_reset(loc)
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 795dc61..64e0b32 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -184,8 +184,6 @@
 
 ENTRY(cpu_arm6_proc_fin)
 ENTRY(cpu_arm7_proc_fin)
-		mov	r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-		msr	cpsr_c, r0
 		mov	r0, #0x31			@ ....S..DP...M
 		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
 		mov	pc, lr
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 0b62de2..9d96824 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -54,15 +54,11 @@
 		mov	pc, lr
 
 ENTRY(cpu_arm720_proc_fin)
-		stmfd	sp!, {lr}
-		mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-		msr	cpsr_c, ip
 		mrc	p15, 0, r0, c1, c0, 0
 		bic	r0, r0, #0x1000			@ ...i............
 		bic	r0, r0, #0x000e			@ ............wca.
 		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-		mcr	p15, 0, r1, c7, c7, 0		@ invalidate cache
-		ldmfd	sp!, {pc}
+		mov	pc, lr
 
 /*
  * Function: arm720_proc_do_idle(void)
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 01860cd..6c1a9ab 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -36,15 +36,11 @@
  * cpu_arm740_proc_fin()
  */
 ENTRY(cpu_arm740_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
 	mrc	p15, 0, r0, c1, c0, 0
 	bic	r0, r0, #0x3f000000		@ bank/f/lock/s
 	bic	r0, r0, #0x0000000c		@ w-buffer/cache
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	mcr	p15, 0, r0, c7, c0, 0		@ invalidate cache
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm740_reset(loc)
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 1201b98..6a850db 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -36,8 +36,6 @@
  * cpu_arm7tdmi_proc_fin()
  */
 ENTRY(cpu_arm7tdmi_proc_fin)
-		mov	r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-		msr	cpsr_c, r0
 		mov	pc, lr
 
 /*
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 8be8199..86f80aa 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -69,19 +69,11 @@
  * cpu_arm920_proc_fin()
  */
 ENTRY(cpu_arm920_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
-	bl	arm920_flush_kern_cache_all
-#else
-	bl	v4wt_flush_kern_cache_all
-#endif
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x000e			@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm920_reset(loc)
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index c0ff8e4..f76ce9b 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -71,19 +71,11 @@
  * cpu_arm922_proc_fin()
  */
 ENTRY(cpu_arm922_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
-	bl	arm922_flush_kern_cache_all
-#else
-	bl	v4wt_flush_kern_cache_all
-#endif
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x000e			@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm922_reset(loc)
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 3c6cffe..657bd3f 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -92,15 +92,11 @@
  * cpu_arm925_proc_fin()
  */
 ENTRY(cpu_arm925_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	arm925_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x000e			@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm925_reset(loc)
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 75b707c..73f1f3c 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -61,15 +61,11 @@
  * cpu_arm926_proc_fin()
  */
 ENTRY(cpu_arm926_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	arm926_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x000e			@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm926_reset(loc)
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 1af1657..fffb061 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -37,15 +37,11 @@
  * cpu_arm940_proc_fin()
  */
 ENTRY(cpu_arm940_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	arm940_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x00001000		@ i-cache
 	bic	r0, r0, #0x00000004		@ d-cache
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm940_reset(loc)
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 1664b6a..249a605 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -44,15 +44,11 @@
  * cpu_arm946_proc_fin()
  */
 ENTRY(cpu_arm946_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	arm946_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x00001000		@ i-cache
 	bic	r0, r0, #0x00000004		@ d-cache
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_arm946_reset(loc)
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index 28545c2..db47566 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -36,8 +36,6 @@
  * cpu_arm9tdmi_proc_fin()
  */
 ENTRY(cpu_arm9tdmi_proc_fin)
-		mov	r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-		msr	cpsr_c, r0
 		mov	pc, lr
 
 /*
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 08f5ac2..7803fdf 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -39,17 +39,13 @@
  * cpu_fa526_proc_fin()
  */
 ENTRY(cpu_fa526_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	fa_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x000e			@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
 	nop
 	nop
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_fa526_reset(loc)
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 53e6323..b304d01 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -75,11 +75,6 @@
  * cpu_feroceon_proc_fin()
  */
 ENTRY(cpu_feroceon_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	feroceon_flush_kern_cache_all
-
 #if defined(CONFIG_CACHE_FEROCEON_L2) && \
 	!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
 	mov	r0, #0
@@ -91,7 +86,7 @@
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x000e			@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_feroceon_reset(loc)
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index caa3115..5f6892f 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -51,15 +51,11 @@
  * cpu_mohawk_proc_fin()
  */
 ENTRY(cpu_mohawk_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	mohawk_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1800			@ ...iz...........
 	bic	r0, r0, #0x0006			@ .............ca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_mohawk_reset(loc)
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 7b706b3..a201eb0 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -44,17 +44,13 @@
  * cpu_sa110_proc_fin()
  */
 ENTRY(cpu_sa110_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	v4wb_flush_kern_cache_all	@ clean caches
-1:	mov	r0, #0
+	mov	r0, #0
 	mcr	p15, 0, r0, c15, c2, 2		@ Disable clock switching
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x000e			@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_sa110_reset(loc)
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 5c47760..7ddc480 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -55,16 +55,12 @@
  *  - Clean and turn off caches.
  */
 ENTRY(cpu_sa1100_proc_fin)
-	stmfd	sp!, {lr}
-	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-	msr	cpsr_c, ip
-	bl	v4wb_flush_kern_cache_all
 	mcr	p15, 0, ip, c15, c2, 2		@ Disable clock switching
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x000e			@ ............wca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  * cpu_sa1100_reset(loc)
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 7a5337e..22aac851 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -42,14 +42,11 @@
 	mov	pc, lr
 
 ENTRY(cpu_v6_proc_fin)
-	stmfd	sp!, {lr}
-	cpsid	if				@ disable interrupts
-	bl	v6_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x0006			@ .............ca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 
 /*
  *	cpu_v6_reset(loc)
@@ -239,7 +236,8 @@
 	b	__v6_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
+	/* See also feat_v6_fixup() for HWCAP_TLS */
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA|HWCAP_TLS
 	.long	cpu_v6_name
 	.long	v6_processor_functions
 	.long	v6wbi_tlb_fns
@@ -262,7 +260,7 @@
 	b	__v6_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
 	.long	cpu_pj4_name
 	.long	v6_processor_functions
 	.long	v6wbi_tlb_fns
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 7aaf88a..6a8506d 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -45,14 +45,11 @@
 ENDPROC(cpu_v7_proc_init)
 
 ENTRY(cpu_v7_proc_fin)
-	stmfd	sp!, {lr}
-	cpsid	if				@ disable interrupts
-	bl	v7_flush_kern_cache_all
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1000			@ ...i............
 	bic	r0, r0, #0x0006			@ .............ca.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldmfd	sp!, {pc}
+	mov	pc, lr
 ENDPROC(cpu_v7_proc_fin)
 
 /*
@@ -344,7 +341,7 @@
 	b	__v7_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
 	.long	cpu_v7_name
 	.long	v7_processor_functions
 	.long	v7wbi_tlb_fns
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index e5797f1..361a51e 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -90,15 +90,11 @@
  * cpu_xsc3_proc_fin()
  */
 ENTRY(cpu_xsc3_proc_fin)
-	str	lr, [sp, #-4]!
-	mov	r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
-	msr	cpsr_c, r0
-	bl	xsc3_flush_kern_cache_all	@ clean caches
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1800			@ ...IZ...........
 	bic	r0, r0, #0x0006			@ .............CA.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldr	pc, [sp], #4
+	mov	pc, lr
 
 /*
  * cpu_xsc3_reset(loc)
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 63037e2..1407597 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -124,15 +124,11 @@
  * cpu_xscale_proc_fin()
  */
 ENTRY(cpu_xscale_proc_fin)
-	str	lr, [sp, #-4]!
-	mov	r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
-	msr	cpsr_c, r0
-	bl	xscale_flush_kern_cache_all	@ clean caches
 	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
 	bic	r0, r0, #0x1800			@ ...IZ...........
 	bic	r0, r0, #0x0006			@ .............CA.
 	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
-	ldr	pc, [sp], #4
+	mov	pc, lr
 
 /*
  * cpu_xscale_reset(loc)
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
index 19e09bdb..935993e 100644
--- a/arch/arm/mm/vmregion.c
+++ b/arch/arm/mm/vmregion.c
@@ -35,7 +35,8 @@
  */
 
 struct arm_vmregion *
-arm_vmregion_alloc(struct arm_vmregion_head *head, size_t size, gfp_t gfp)
+arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
+		   size_t size, gfp_t gfp)
 {
 	unsigned long addr = head->vm_start, end = head->vm_end - size;
 	unsigned long flags;
@@ -58,7 +59,7 @@
 			goto nospc;
 		if ((addr + size) <= c->vm_start)
 			goto found;
-		addr = c->vm_end;
+		addr = ALIGN(c->vm_end, align);
 		if (addr > end)
 			goto nospc;
 	}
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
index 6b2cdbd..15e9f04 100644
--- a/arch/arm/mm/vmregion.h
+++ b/arch/arm/mm/vmregion.h
@@ -21,7 +21,7 @@
 	int			vm_active;
 };
 
-struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, gfp_t);
+struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t);
 struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
 struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
 void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
index ce31f31..43f2b15 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/plat-iop/pci.c
@@ -359,7 +359,7 @@
 	DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD);
 	DBG("ATU: IOP3XX_ATUCR=0x%08x\n", *IOP3XX_ATUCR);
 
-	hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort");
+	hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, 0, "imprecise external abort");
 }
 
 /* for platforms that might be host-bus-adapters */
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index 6c8a02a..85d3e55 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -29,6 +29,11 @@
 #include <mach/time.h>
 
 /*
+ * Minimum clocksource/clockevent timer range in seconds
+ */
+#define IOP_MIN_RANGE 4
+
+/*
  * IOP clocksource (free-running timer 1).
  */
 static cycle_t iop_clocksource_read(struct clocksource *unused)
@@ -44,27 +49,6 @@
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static void __init iop_clocksource_set_hz(struct clocksource *cs, unsigned int hz)
-{
-	u64 temp;
-	u32 shift;
-
-	/* Find shift and mult values for hz. */
-	shift = 32;
-	do {
-		temp = (u64) NSEC_PER_SEC << shift;
-		do_div(temp, hz);
-		if ((temp >> 32) == 0)
-			break;
-	} while (--shift != 0);
-
-	cs->shift = shift;
-	cs->mult = (u32) temp;
-
-	printk(KERN_INFO "clocksource: %s uses shift %u mult %#x\n",
-	       cs->name, cs->shift, cs->mult);
-}
-
 /*
  * IOP sched_clock() implementation via its clocksource.
  */
@@ -130,27 +114,6 @@
 	.set_mode	= iop_set_mode,
 };
 
-static void __init iop_clockevent_set_hz(struct clock_event_device *ce, unsigned int hz)
-{
-	u64 temp;
-	u32 shift;
-
-	/* Find shift and mult values for hz. */
-	shift = 32;
-	do {
-		temp = (u64) hz << shift;
-		do_div(temp, NSEC_PER_SEC);
-		if ((temp >> 32) == 0)
-			break;
-	} while (--shift != 0);
-
-	ce->shift = shift;
-	ce->mult = (u32) temp;
-
-	printk(KERN_INFO "clockevent: %s uses shift %u mult %#lx\n",
-	       ce->name, ce->shift, ce->mult);
-}
-
 static irqreturn_t
 iop_timer_interrupt(int irq, void *dev_id)
 {
@@ -190,7 +153,8 @@
 	 */
 	write_tmr0(timer_ctl & ~IOP_TMR_EN);
 	setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
-	iop_clockevent_set_hz(&iop_clockevent, tick_rate);
+	clockevents_calc_mult_shift(&iop_clockevent,
+				    tick_rate, IOP_MIN_RANGE);
 	iop_clockevent.max_delta_ns =
 		clockevent_delta2ns(0xfffffffe, &iop_clockevent);
 	iop_clockevent.min_delta_ns =
@@ -207,6 +171,7 @@
 	write_trr1(0xffffffff);
 	write_tcr1(0xffffffff);
 	write_tmr1(timer_ctl);
-	iop_clocksource_set_hz(&iop_clocksource, tick_rate);
+	clocksource_calc_mult_shift(&iop_clocksource, tick_rate,
+				    IOP_MIN_RANGE);
 	clocksource_register(&iop_clocksource);
 }
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
index 5a6ef25..977c8f9 100644
--- a/arch/arm/plat-nomadik/gpio.c
+++ b/arch/arm/plat-nomadik/gpio.c
@@ -23,6 +23,7 @@
 #include <linux/irq.h>
 #include <linux/slab.h>
 
+#include <plat/pincfg.h>
 #include <mach/hardware.h>
 #include <mach/gpio.h>
 
@@ -46,20 +47,12 @@
 	u32 edge_falling;
 };
 
-/* Mode functions */
-int nmk_gpio_set_mode(int gpio, int gpio_mode)
+static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
+				unsigned offset, int gpio_mode)
 {
-	struct nmk_gpio_chip *nmk_chip;
-	unsigned long flags;
-	u32 afunc, bfunc, bit;
+	u32 bit = 1 << offset;
+	u32 afunc, bfunc;
 
-	nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
-	if (!nmk_chip)
-		return -EINVAL;
-
-	bit = 1 << (gpio - nmk_chip->chip.base);
-
-	spin_lock_irqsave(&nmk_chip->lock, flags);
 	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
 	bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
 	if (gpio_mode & NMK_GPIO_ALT_A)
@@ -68,6 +61,203 @@
 		bfunc |= bit;
 	writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
 	writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
+}
+
+static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
+				unsigned offset, enum nmk_gpio_slpm mode)
+{
+	u32 bit = 1 << offset;
+	u32 slpm;
+
+	slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
+	if (mode == NMK_GPIO_SLPM_NOCHANGE)
+		slpm |= bit;
+	else
+		slpm &= ~bit;
+	writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
+}
+
+static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
+				unsigned offset, enum nmk_gpio_pull pull)
+{
+	u32 bit = 1 << offset;
+	u32 pdis;
+
+	pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
+	if (pull == NMK_GPIO_PULL_NONE)
+		pdis |= bit;
+	else
+		pdis &= ~bit;
+	writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
+
+	if (pull == NMK_GPIO_PULL_UP)
+		writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
+	else if (pull == NMK_GPIO_PULL_DOWN)
+		writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
+}
+
+static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
+				  unsigned offset)
+{
+	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+}
+
+static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
+			     pin_cfg_t cfg)
+{
+	static const char *afnames[] = {
+		[NMK_GPIO_ALT_GPIO]	= "GPIO",
+		[NMK_GPIO_ALT_A]	= "A",
+		[NMK_GPIO_ALT_B]	= "B",
+		[NMK_GPIO_ALT_C]	= "C"
+	};
+	static const char *pullnames[] = {
+		[NMK_GPIO_PULL_NONE]	= "none",
+		[NMK_GPIO_PULL_UP]	= "up",
+		[NMK_GPIO_PULL_DOWN]	= "down",
+		[3] /* illegal */	= "??"
+	};
+	static const char *slpmnames[] = {
+		[NMK_GPIO_SLPM_INPUT]		= "input",
+		[NMK_GPIO_SLPM_NOCHANGE]	= "no-change",
+	};
+
+	int pin = PIN_NUM(cfg);
+	int pull = PIN_PULL(cfg);
+	int af = PIN_ALT(cfg);
+	int slpm = PIN_SLPM(cfg);
+
+	dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s\n",
+		pin, afnames[af], pullnames[pull], slpmnames[slpm]);
+
+	__nmk_gpio_make_input(nmk_chip, offset);
+	__nmk_gpio_set_pull(nmk_chip, offset, pull);
+	__nmk_gpio_set_slpm(nmk_chip, offset, slpm);
+	__nmk_gpio_set_mode(nmk_chip, offset, af);
+}
+
+/**
+ * nmk_config_pin - configure a pin's mux attributes
+ * @cfg: pin confguration
+ *
+ * Configures a pin's mode (alternate function or GPIO), its pull up status,
+ * and its sleep mode based on the specified configuration.  The @cfg is
+ * usually one of the SoC specific macros defined in mach/<soc>-pins.h.  These
+ * are constructed using, and can be further enhanced with, the macros in
+ * plat/pincfg.h.
+ *
+ * If a pin's mode is set to GPIO, it is configured as an input to avoid
+ * side-effects.  The gpio can be manipulated later using standard GPIO API
+ * calls.
+ */
+int nmk_config_pin(pin_cfg_t cfg)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	int gpio = PIN_NUM(cfg);
+	unsigned long flags;
+
+	nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+	__nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg);
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(nmk_config_pin);
+
+/**
+ * nmk_config_pins - configure several pins at once
+ * @cfgs: array of pin configurations
+ * @num: number of elments in the array
+ *
+ * Configures several pins using nmk_config_pin().  Refer to that function for
+ * further information.
+ */
+int nmk_config_pins(pin_cfg_t *cfgs, int num)
+{
+	int ret = 0;
+	int i;
+
+	for (i = 0; i < num; i++) {
+		int ret = nmk_config_pin(cfgs[i]);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(nmk_config_pins);
+
+/**
+ * nmk_gpio_set_slpm() - configure the sleep mode of a pin
+ * @gpio: pin number
+ * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE,
+ *
+ * Sets the sleep mode of a pin.  If @mode is NMK_GPIO_SLPM_INPUT, the pin is
+ * changed to an input (with pullup/down enabled) in sleep and deep sleep.  If
+ * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was
+ * configured even when in sleep and deep sleep.
+ */
+int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+
+	nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+	__nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode);
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+	return 0;
+}
+
+/**
+ * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio
+ * @gpio: pin number
+ * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE
+ *
+ * Enables/disables pull up/down on a specified pin.  This only takes effect if
+ * the pin is configured as an input (either explicitly or by the alternate
+ * function).
+ *
+ * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is
+ * configured as an input.  Otherwise, due to the way the controller registers
+ * work, this function will change the value output on the pin.
+ */
+int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+
+	nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+	__nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull);
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+	return 0;
+}
+
+/* Mode functions */
+int nmk_gpio_set_mode(int gpio, int gpio_mode)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+
+	nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+	__nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode);
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
 
 	return 0;
@@ -111,32 +301,41 @@
 	writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
 }
 
+enum nmk_gpio_irq_type {
+	NORMAL,
+	WAKE,
+};
+
 static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
-				  int gpio, bool enable)
+				  int gpio, enum nmk_gpio_irq_type which,
+				  bool enable)
 {
+	u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC;
+	u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC;
 	u32 bitmask = nmk_gpio_get_bitmask(gpio);
 	u32 reg;
 
 	/* we must individually set/clear the two edges */
 	if (nmk_chip->edge_rising & bitmask) {
-		reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC);
+		reg = readl(nmk_chip->addr + rimsc);
 		if (enable)
 			reg |= bitmask;
 		else
 			reg &= ~bitmask;
-		writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC);
+		writel(reg, nmk_chip->addr + rimsc);
 	}
 	if (nmk_chip->edge_falling & bitmask) {
-		reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC);
+		reg = readl(nmk_chip->addr + fimsc);
 		if (enable)
 			reg |= bitmask;
 		else
 			reg &= ~bitmask;
-		writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC);
+		writel(reg, nmk_chip->addr + fimsc);
 	}
 }
 
-static void nmk_gpio_irq_modify(unsigned int irq, bool enable)
+static int nmk_gpio_irq_modify(unsigned int irq, enum nmk_gpio_irq_type which,
+			       bool enable)
 {
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
@@ -147,26 +346,35 @@
 	nmk_chip = get_irq_chip_data(irq);
 	bitmask = nmk_gpio_get_bitmask(gpio);
 	if (!nmk_chip)
-		return;
+		return -EINVAL;
 
 	spin_lock_irqsave(&nmk_chip->lock, flags);
-	__nmk_gpio_irq_modify(nmk_chip, gpio, enable);
+	__nmk_gpio_irq_modify(nmk_chip, gpio, which, enable);
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+	return 0;
 }
 
 static void nmk_gpio_irq_mask(unsigned int irq)
 {
-	nmk_gpio_irq_modify(irq, false);
-};
+	nmk_gpio_irq_modify(irq, NORMAL, false);
+}
 
 static void nmk_gpio_irq_unmask(unsigned int irq)
 {
-	nmk_gpio_irq_modify(irq, true);
+	nmk_gpio_irq_modify(irq, NORMAL, true);
+}
+
+static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+	return nmk_gpio_irq_modify(irq, WAKE, on);
 }
 
 static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
 {
-	bool enabled = !(irq_to_desc(irq)->status & IRQ_DISABLED);
+	struct irq_desc *desc = irq_to_desc(irq);
+	bool enabled = !(desc->status & IRQ_DISABLED);
+	bool wake = desc->wake_depth;
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 	unsigned long flags;
@@ -186,7 +394,10 @@
 	spin_lock_irqsave(&nmk_chip->lock, flags);
 
 	if (enabled)
-		__nmk_gpio_irq_modify(nmk_chip, gpio, false);
+		__nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false);
+
+	if (wake)
+		__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false);
 
 	nmk_chip->edge_rising &= ~bitmask;
 	if (type & IRQ_TYPE_EDGE_RISING)
@@ -197,7 +408,10 @@
 		nmk_chip->edge_falling |= bitmask;
 
 	if (enabled)
-		__nmk_gpio_irq_modify(nmk_chip, gpio, true);
+		__nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true);
+
+	if (wake)
+		__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true);
 
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
 
@@ -210,6 +424,7 @@
 	.mask		= nmk_gpio_irq_mask,
 	.unmask		= nmk_gpio_irq_unmask,
 	.set_type	= nmk_gpio_irq_set_type,
+	.set_wake	= nmk_gpio_irq_set_wake,
 };
 
 static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
@@ -266,16 +481,6 @@
 	return 0;
 }
 
-static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
-				int val)
-{
-	struct nmk_gpio_chip *nmk_chip =
-		container_of(chip, struct nmk_gpio_chip, chip);
-
-	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
-	return 0;
-}
-
 static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
 {
 	struct nmk_gpio_chip *nmk_chip =
@@ -298,12 +503,33 @@
 		writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
 }
 
+static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
+				int val)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+
+	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
+	nmk_gpio_set_output(chip, offset, val);
+
+	return 0;
+}
+
+static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+
+	return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset;
+}
+
 /* This structure is replicated for each GPIO block allocated at probe time */
 static struct gpio_chip nmk_gpio_template = {
 	.direction_input	= nmk_gpio_make_input,
 	.get			= nmk_gpio_get_input,
 	.direction_output	= nmk_gpio_make_output,
 	.set			= nmk_gpio_set_output,
+	.to_irq			= nmk_gpio_to_irq,
 	.ngpio			= NMK_GPIO_PER_CHIP,
 	.can_sleep		= 0,
 };
@@ -393,30 +619,12 @@
 	return ret;
 }
 
-static int __exit nmk_gpio_remove(struct platform_device *dev)
-{
-	struct nmk_gpio_chip *nmk_chip;
-	struct resource *res;
-
-	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-
-	nmk_chip = platform_get_drvdata(dev);
-	gpiochip_remove(&nmk_chip->chip);
-	clk_disable(nmk_chip->clk);
-	clk_put(nmk_chip->clk);
-	kfree(nmk_chip);
-	release_mem_region(res->start, resource_size(res));
-	return 0;
-}
-
-
 static struct platform_driver nmk_gpio_driver = {
 	.driver = {
 		.owner = THIS_MODULE,
 		.name = "gpio",
 		},
 	.probe = nmk_gpio_probe,
-	.remove = __exit_p(nmk_gpio_remove),
 	.suspend = NULL, /* to be done */
 	.resume = NULL,
 };
@@ -426,7 +634,7 @@
 	return platform_driver_register(&nmk_gpio_driver);
 }
 
-arch_initcall(nmk_gpio_init);
+core_initcall(nmk_gpio_init);
 
 MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
 MODULE_DESCRIPTION("Nomadik GPIO Driver");
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h
index 4200811..aba3551 100644
--- a/arch/arm/plat-nomadik/include/plat/gpio.h
+++ b/arch/arm/plat-nomadik/include/plat/gpio.h
@@ -55,6 +55,21 @@
 #define NMK_GPIO_ALT_B	2
 #define NMK_GPIO_ALT_C	(NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
 
+/* Pull up/down values */
+enum nmk_gpio_pull {
+	NMK_GPIO_PULL_NONE,
+	NMK_GPIO_PULL_UP,
+	NMK_GPIO_PULL_DOWN,
+};
+
+/* Sleep mode */
+enum nmk_gpio_slpm {
+	NMK_GPIO_SLPM_INPUT,
+	NMK_GPIO_SLPM_NOCHANGE,
+};
+
+extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
+extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
 extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
 extern int nmk_gpio_get_mode(int gpio);
 
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
index 42c9072..65704a3 100644
--- a/arch/arm/plat-nomadik/include/plat/mtu.h
+++ b/arch/arm/plat-nomadik/include/plat/mtu.h
@@ -1,6 +1,12 @@
 #ifndef __PLAT_MTU_H
 #define __PLAT_MTU_H
 
+/*
+ * Guaranteed runtime conversion range in seconds for
+ * the clocksource and clockevent.
+ */
+#define MTU_MIN_RANGE 4
+
 /* should be set by the platform code */
 extern void __iomem *mtu_base;
 
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
new file mode 100644
index 0000000..7eed11c
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ *
+ * Based on arch/arm/mach-pxa/include/mach/mfp.h:
+ *   Copyright (C) 2007 Marvell International Ltd.
+ *   eric miao <eric.miao@marvell.com>
+ */
+
+#ifndef __PLAT_PINCFG_H
+#define __PLAT_PINCFG_H
+
+/*
+ * pin configurations are represented by 32-bit integers:
+ *
+ *	bit  0.. 8 - Pin Number (512 Pins Maximum)
+ *	bit  9..10 - Alternate Function Selection
+ *	bit 11..12 - Pull up/down state
+ *	bit     13 - Sleep mode behaviour
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * PIN_CFG_DEFAULT - default config (0):
+ *		     pull up/down = disabled
+ *		     sleep mode = input
+ *
+ * PIN_CFG	   - default config with alternate function
+ * PIN_CFG_PULL	   - default config with alternate function and pull up/down
+ */
+
+typedef unsigned long pin_cfg_t;
+
+#define PIN_NUM_MASK		0x1ff
+#define PIN_NUM(x)		((x) & PIN_NUM_MASK)
+
+#define PIN_ALT_SHIFT		9
+#define PIN_ALT_MASK		(0x3 << PIN_ALT_SHIFT)
+#define PIN_ALT(x)		(((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT)
+#define PIN_GPIO		(NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT)
+#define PIN_ALT_A		(NMK_GPIO_ALT_A << PIN_ALT_SHIFT)
+#define PIN_ALT_B		(NMK_GPIO_ALT_B << PIN_ALT_SHIFT)
+#define PIN_ALT_C		(NMK_GPIO_ALT_C << PIN_ALT_SHIFT)
+
+#define PIN_PULL_SHIFT		11
+#define PIN_PULL_MASK		(0x3 << PIN_PULL_SHIFT)
+#define PIN_PULL(x)		(((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT)
+#define PIN_PULL_NONE		(NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT)
+#define PIN_PULL_UP		(NMK_GPIO_PULL_UP << PIN_PULL_SHIFT)
+#define PIN_PULL_DOWN		(NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT)
+
+#define PIN_SLPM_SHIFT		13
+#define PIN_SLPM_MASK		(0x1 << PIN_SLPM_SHIFT)
+#define PIN_SLPM(x)		(((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
+#define PIN_SLPM_INPUT		(NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
+#define PIN_SLPM_NOCHANGE	(NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
+
+#define PIN_CFG_DEFAULT		(PIN_PULL_NONE | PIN_SLPM_INPUT)
+
+#define PIN_CFG(num, alt)		\
+	(PIN_CFG_DEFAULT |\
+	 (PIN_NUM(num) | PIN_##alt))
+
+#define PIN_CFG_PULL(num, alt, pull)	\
+	((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\
+	 (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull))
+
+extern int nmk_config_pin(pin_cfg_t cfg);
+extern int nmk_config_pins(pin_cfg_t *cfgs, int num);
+
+#endif
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index 08aaa4a..ea3ca86 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -42,7 +42,6 @@
 	.rating		= 200,
 	.read		= nmdk_read_timer_dummy,
 	.mask		= CLOCKSOURCE_MASK(32),
-	.shift		= 20,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -82,6 +81,12 @@
 	case CLOCK_EVT_MODE_UNUSED:
 		/* disable irq */
 		writel(0, mtu_base + MTU_IMSC);
+		/* disable timer */
+		cr = readl(mtu_base + MTU_CR(1));
+		cr &= ~MTU_CRn_ENA;
+		writel(cr, mtu_base + MTU_CR(1));
+		/* load some high default value */
+		writel(0xffffffff, mtu_base + MTU_LR(1));
 		break;
 	case CLOCK_EVT_MODE_RESUME:
 		break;
@@ -98,7 +103,6 @@
 static struct clock_event_device nmdk_clkevt = {
 	.name		= "mtu_1",
 	.features	= CLOCK_EVT_FEAT_ONESHOT,
-	.shift		= 32,
 	.rating		= 200,
 	.set_mode	= nmdk_clkevt_mode,
 	.set_next_event	= nmdk_clkevt_next,
@@ -151,6 +155,7 @@
 	} else {
 		cr |= MTU_CRn_PRESCALE_1;
 	}
+	clocksource_calc_mult_shift(&nmdk_clksrc, rate, MTU_MIN_RANGE);
 
 	/* Timer 0 is the free running clocksource */
 	writel(cr, mtu_base + MTU_CR(0));
@@ -158,7 +163,6 @@
 	writel(0, mtu_base + MTU_BGLR(0));
 	writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
 
-	nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
 	/* Now the scheduling clock is ready */
 	nmdk_clksrc.read = nmdk_read_timer;
 
@@ -175,8 +179,10 @@
 	} else {
 		cr |= MTU_CRn_PRESCALE_1;
 	}
+	clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
+
 	writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */
-	nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
+
 	nmdk_clkevt.max_delta_ns =
 		clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
 	nmdk_clkevt.min_delta_ns =
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 219c01e..ebed826 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -22,6 +22,7 @@
 #include <linux/serial_reg.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/omapfb.h>
 
 #include <mach/hardware.h>
 #include <asm/system.h>
@@ -35,6 +36,7 @@
 #include <plat/mux.h>
 #include <plat/fpga.h>
 #include <plat/serial.h>
+#include <plat/vram.h>
 
 #include <plat/clock.h>
 
@@ -81,6 +83,12 @@
 }
 EXPORT_SYMBOL(omap_get_var_config);
 
+void __init omap_reserve(void)
+{
+	omapfb_reserve_sdram_memblock();
+	omap_vram_reserve_sdram_memblock();
+}
+
 /*
  * 32KHz clocksource ... always available, on pretty most chips except
  * OMAP 730 and 1510.  Other timers could be used as clocksources, with
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index d3eea4f..0054b95 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -26,7 +26,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/io.h>
 #include <linux/omapfb.h>
 
@@ -171,49 +171,78 @@
 	return 0;
 }
 
+static int valid_sdram(unsigned long addr, unsigned long size)
+{
+	struct memblock_property res;
+
+	res.base = addr;
+	res.size = size;
+	return !memblock_find(&res) && res.base == addr && res.size == size;
+}
+
+static int reserve_sdram(unsigned long addr, unsigned long size)
+{
+	if (memblock_is_region_reserved(addr, size))
+		return -EBUSY;
+	if (memblock_reserve(addr, size))
+		return -ENOMEM;
+	return 0;
+}
+
 /*
  * Called from map_io. We need to call to this early enough so that we
  * can reserve the fixed SDRAM regions before VM could get hold of them.
  */
-void __init omapfb_reserve_sdram(void)
+void __init omapfb_reserve_sdram_memblock(void)
 {
-	struct bootmem_data	*bdata;
-	unsigned long		sdram_start, sdram_size;
-	unsigned long		reserved;
-	int			i;
+	unsigned long reserved = 0;
+	int i;
 
 	if (config_invalid)
 		return;
 
-	bdata = NODE_DATA(0)->bdata;
-	sdram_start = bdata->node_min_pfn << PAGE_SHIFT;
-	sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start;
-	reserved = 0;
 	for (i = 0; ; i++) {
-		struct omapfb_mem_region	rg;
+		struct omapfb_mem_region rg;
 
 		if (get_fbmem_region(i, &rg) < 0)
 			break;
+
 		if (i == OMAPFB_PLANE_NUM) {
-			printk(KERN_ERR
-				"Extraneous FB mem configuration entries\n");
+			pr_err("Extraneous FB mem configuration entries\n");
 			config_invalid = 1;
 			return;
 		}
+
 		/* Check if it's our memory type. */
-		if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SDRAM,
-				          sdram_start, sdram_size) < 0 ||
-		    (rg.type != OMAPFB_MEMTYPE_SDRAM))
+		if (rg.type != OMAPFB_MEMTYPE_SDRAM)
 			continue;
-		BUG_ON(omapfb_config.mem_desc.region[i].size);
-		if (check_fbmem_region(i, &rg, sdram_start, sdram_size) < 0) {
+
+		/* Check if the region falls within SDRAM */
+		if (rg.paddr && !valid_sdram(rg.paddr, rg.size))
+			continue;
+
+		if (rg.size == 0) {
+			pr_err("Zero size for FB region %d\n", i);
 			config_invalid = 1;
 			return;
 		}
+
 		if (rg.paddr) {
-			reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT);
+			if (reserve_sdram(rg.paddr, rg.size)) {
+				pr_err("Trying to use reserved memory for FB region %d\n",
+					i);
+				config_invalid = 1;
+				return;
+			}
 			reserved += rg.size;
 		}
+
+		if (omapfb_config.mem_desc.region[i].size) {
+			pr_err("FB region %d already set\n", i);
+			config_invalid = 1;
+			return;
+		}
+
 		omapfb_config.mem_desc.region[i] = rg;
 		configured_regions++;
 	}
@@ -359,7 +388,10 @@
 
 arch_initcall(omap_init_fb);
 
-void omapfb_reserve_sdram(void) {}
+void omapfb_reserve_sdram_memblock(void)
+{
+}
+
 unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
 				  unsigned long sram_vstart,
 				  unsigned long sram_size,
@@ -375,7 +407,10 @@
 {
 }
 
-void omapfb_reserve_sdram(void) {}
+void omapfb_reserve_sdram_memblock(void)
+{
+}
+
 unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
 				  unsigned long sram_vstart,
 				  unsigned long sram_size,
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index d265018..5e4afbe 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -34,6 +34,8 @@
 extern void omap_map_common_io(void);
 extern struct sys_timer omap_timer;
 
+extern void omap_reserve(void);
+
 /*
  * IO bases for various OMAP processors
  * Except the tap base, rest all the io bases
diff --git a/arch/arm/plat-omap/include/plat/vram.h b/arch/arm/plat-omap/include/plat/vram.h
index edd4987..0aa4ecd 100644
--- a/arch/arm/plat-omap/include/plat/vram.h
+++ b/arch/arm/plat-omap/include/plat/vram.h
@@ -38,7 +38,7 @@
 extern void omap_vram_set_sdram_vram(u32 size, u32 start);
 extern void omap_vram_set_sram_vram(u32 size, u32 start);
 
-extern void omap_vram_reserve_sdram(void);
+extern void omap_vram_reserve_sdram_memblock(void);
 extern unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
 					    unsigned long sram_vstart,
 					    unsigned long sram_size,
@@ -48,7 +48,7 @@
 static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
 static inline void omap_vram_set_sram_vram(u32 size, u32 start) { }
 
-static inline void omap_vram_reserve_sdram(void) { }
+static inline void omap_vram_reserve_sdram_memblock(void) { }
 static inline unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
 					    unsigned long sram_vstart,
 					    unsigned long sram_size,
diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
index a1025d3..ab21165 100644
--- a/arch/arm/plat-spear/time.c
+++ b/arch/arm/plat-spear/time.c
@@ -58,6 +58,11 @@
 
 #define INT_STATUS		0x1
 
+/*
+ * Minimum clocksource/clockevent timer range in seconds
+ */
+#define SPEAR_MIN_RANGE 4
+
 static __iomem void *gpt_base;
 static struct clk *gpt_clk;
 
@@ -66,44 +71,6 @@
 static int clockevent_next_event(unsigned long evt,
 				 struct clock_event_device *clk_event_dev);
 
-/*
- * Following clocksource_set_clock and clockevent_set_clock picked
- * from arch/mips/kernel/time.c
- */
-
-void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
-{
-	u64 temp;
-	u32 shift;
-
-	/* Find a shift value */
-	for (shift = 32; shift > 0; shift--) {
-		temp = (u64) NSEC_PER_SEC << shift;
-		do_div(temp, clock);
-		if ((temp >> 32) == 0)
-			break;
-	}
-	cs->shift = shift;
-	cs->mult = (u32) temp;
-}
-
-void __init clockevent_set_clock(struct clock_event_device *cd,
-	unsigned int clock)
-{
-	u64 temp;
-	u32 shift;
-
-	/* Find a shift value */
-	for (shift = 32; shift > 0; shift--) {
-		temp = (u64) clock << shift;
-		do_div(temp, NSEC_PER_SEC);
-		if ((temp >> 32) == 0)
-			break;
-	}
-	cd->shift = shift;
-	cd->mult = (u32) temp;
-}
-
 static cycle_t clocksource_read_cycles(struct clocksource *cs)
 {
 	return (cycle_t) readw(gpt_base + COUNT(CLKSRC));
@@ -138,7 +105,7 @@
 	val |= CTRL_ENABLE ;
 	writew(val, gpt_base + CR(CLKSRC));
 
-	clocksource_set_clock(&clksrc, tick_rate);
+	clocksource_calc_mult_shift(&clksrc, tick_rate, SPEAR_MIN_RANGE);
 
 	/* register the clocksource */
 	clocksource_register(&clksrc);
@@ -233,7 +200,7 @@
 	tick_rate = clk_get_rate(gpt_clk);
 	tick_rate >>= CTRL_PRESCALER16;
 
-	clockevent_set_clock(&clkevt, tick_rate);
+	clockevents_calc_mult_shift(&clkevt, tick_rate, SPEAR_MIN_RANGE);
 
 	clkevt.max_delta_ns = clockevent_delta2ns(0xfff0,
 			&clkevt);
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
index 9b1a668..5cf88e8 100644
--- a/arch/arm/plat-versatile/Makefile
+++ b/arch/arm/plat-versatile/Makefile
@@ -2,3 +2,7 @@
 obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
 obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o
 obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o
+ifeq ($(CONFIG_LEDS_CLASS),y)
+obj-$(CONFIG_ARCH_REALVIEW) += leds.o
+obj-$(CONFIG_ARCH_VERSATILE) += leds.o
+endif
diff --git a/arch/arm/plat-versatile/leds.c b/arch/arm/plat-versatile/leds.c
new file mode 100644
index 0000000..3169fa5
--- /dev/null
+++ b/arch/arm/plat-versatile/leds.c
@@ -0,0 +1,103 @@
+/*
+ * Driver for the 8 user LEDs found on the RealViews and Versatiles
+ * Based on DaVinci's DM365 board code
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ * Author: Linus Walleij <triad@df.lth.se>
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+#ifdef VERSATILE_SYS_BASE
+#define LEDREG	(__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
+#endif
+
+#ifdef REALVIEW_SYS_BASE
+#define LEDREG	(__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
+#endif
+
+struct versatile_led {
+	struct led_classdev	cdev;
+	u8			mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+	const char *name;
+	const char *trigger;
+} versatile_leds[] = {
+	{ "versatile:0", "heartbeat", },
+	{ "versatile:1", "mmc0", },
+	{ "versatile:2", },
+	{ "versatile:3", },
+	{ "versatile:4", },
+	{ "versatile:5", },
+	{ "versatile:6", },
+	{ "versatile:7", },
+};
+
+static void versatile_led_set(struct led_classdev *cdev,
+			      enum led_brightness b)
+{
+	struct versatile_led *led = container_of(cdev,
+						 struct versatile_led, cdev);
+	u32 reg = readl(LEDREG);
+
+	if (b != LED_OFF)
+		reg |= led->mask;
+	else
+		reg &= ~led->mask;
+	writel(reg, LEDREG);
+}
+
+static enum led_brightness versatile_led_get(struct led_classdev *cdev)
+{
+	struct versatile_led *led = container_of(cdev,
+						 struct versatile_led, cdev);
+	u32 reg = readl(LEDREG);
+
+	return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
+
+static int __init versatile_leds_init(void)
+{
+	int i;
+
+	/* All ON */
+	writel(0xff, LEDREG);
+	for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) {
+		struct versatile_led *led;
+
+		led = kzalloc(sizeof(*led), GFP_KERNEL);
+		if (!led)
+			break;
+
+		led->cdev.name = versatile_leds[i].name;
+		led->cdev.brightness_set = versatile_led_set;
+		led->cdev.brightness_get = versatile_led_get;
+		led->cdev.default_trigger = versatile_leds[i].trigger;
+		led->mask = BIT(i);
+
+		if (led_classdev_register(NULL, &led->cdev) < 0) {
+			kfree(led);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(versatile_leds_init);
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 315a540..8063a32 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -15,6 +15,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 
+#include <asm/cputype.h>
 #include <asm/thread_notify.h>
 #include <asm/vfp.h>
 
@@ -549,10 +550,13 @@
 		/*
 		 * Check for the presence of the Advanced SIMD
 		 * load/store instructions, integer and single
-		 * precision floating point operations.
+		 * precision floating point operations. Only check
+		 * for NEON if the hardware has the MVFR registers.
 		 */
-		if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
-			elf_hwcap |= HWCAP_NEON;
+		if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+			if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
+				elf_hwcap |= HWCAP_NEON;
+		}
 #endif
 	}
 	return 0;
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 4f4af75..01ab17a 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -572,7 +572,6 @@
 	return NOTIFY_STOP;
 }
 
-#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
 int kgdb_ll_trap(int cmd, const char *str,
 		 struct pt_regs *regs, long err, int trap, int sig)
 {
@@ -590,7 +589,6 @@
 
 	return __kgdb_notify(&args, cmd);
 }
-#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
 
 static int
 kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
@@ -625,6 +623,12 @@
 	return register_die_notifier(&kgdb_notifier);
 }
 
+static void kgdb_hw_overflow_handler(struct perf_event *event, int nmi,
+		struct perf_sample_data *data, struct pt_regs *regs)
+{
+	kgdb_ll_trap(DIE_DEBUG, "debug", regs, 0, 0, SIGTRAP);
+}
+
 void kgdb_arch_late(void)
 {
 	int i, cpu;
@@ -655,6 +659,7 @@
 		for_each_online_cpu(cpu) {
 			pevent = per_cpu_ptr(breakinfo[i].pev, cpu);
 			pevent[0]->hw.sample_period = 1;
+			pevent[0]->overflow_handler = kgdb_hw_overflow_handler;
 			if (pevent[0]->destroy != NULL) {
 				pevent[0]->destroy = NULL;
 				release_bp_slot(*pevent);
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index f60b2b6..d31590e 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -122,6 +122,31 @@
 
 postcore_initcall(amba_init);
 
+static int amba_get_enable_pclk(struct amba_device *pcdev)
+{
+	struct clk *pclk = clk_get(&pcdev->dev, "apb_pclk");
+	int ret;
+
+	pcdev->pclk = pclk;
+
+	if (IS_ERR(pclk))
+		return PTR_ERR(pclk);
+
+	ret = clk_enable(pclk);
+	if (ret)
+		clk_put(pclk);
+
+	return ret;
+}
+
+static void amba_put_disable_pclk(struct amba_device *pcdev)
+{
+	struct clk *pclk = pcdev->pclk;
+
+	clk_disable(pclk);
+	clk_put(pclk);
+}
+
 /*
  * These are the device model conversion veneers; they convert the
  * device model structures to our more specific structures.
@@ -130,17 +155,33 @@
 {
 	struct amba_device *pcdev = to_amba_device(dev);
 	struct amba_driver *pcdrv = to_amba_driver(dev->driver);
-	struct amba_id *id;
+	struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev);
+	int ret;
 
-	id = amba_lookup(pcdrv->id_table, pcdev);
+	do {
+		ret = amba_get_enable_pclk(pcdev);
+		if (ret)
+			break;
 
-	return pcdrv->probe(pcdev, id);
+		ret = pcdrv->probe(pcdev, id);
+		if (ret == 0)
+			break;
+
+		amba_put_disable_pclk(pcdev);
+	} while (0);
+
+	return ret;
 }
 
 static int amba_remove(struct device *dev)
 {
+	struct amba_device *pcdev = to_amba_device(dev);
 	struct amba_driver *drv = to_amba_driver(dev->driver);
-	return drv->remove(to_amba_device(dev));
+	int ret = drv->remove(pcdev);
+
+	amba_put_disable_pclk(pcdev);
+
+	return ret;
 }
 
 static void amba_shutdown(struct device *dev)
@@ -203,7 +244,6 @@
  */
 int amba_device_register(struct amba_device *dev, struct resource *parent)
 {
-	u32 pid, cid;
 	u32 size;
 	void __iomem *tmp;
 	int i, ret;
@@ -241,24 +281,34 @@
 		goto err_release;
 	}
 
-	/*
-	 * Read pid and cid based on size of resource
-	 * they are located at end of region
-	 */
-	for (pid = 0, i = 0; i < 4; i++)
-		pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << (i * 8);
-	for (cid = 0, i = 0; i < 4; i++)
-		cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << (i * 8);
+	ret = amba_get_enable_pclk(dev);
+	if (ret == 0) {
+		u32 pid, cid;
+
+		/*
+		 * Read pid and cid based on size of resource
+		 * they are located at end of region
+		 */
+		for (pid = 0, i = 0; i < 4; i++)
+			pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) <<
+				(i * 8);
+		for (cid = 0, i = 0; i < 4; i++)
+			cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) <<
+				(i * 8);
+
+		amba_put_disable_pclk(dev);
+
+		if (cid == 0xb105f00d)
+			dev->periphid = pid;
+
+		if (!dev->periphid)
+			ret = -ENODEV;
+	}
 
 	iounmap(tmp);
 
-	if (cid == 0xb105f00d)
-		dev->periphid = pid;
-
-	if (!dev->periphid) {
-		ret = -ENODEV;
+	if (ret)
 		goto err_release;
-	}
 
 	ret = device_add(&dev->dev);
 	if (ret)
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c
index ee568c8..5005990 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/pl061.c
@@ -232,7 +232,7 @@
 	desc->chip->unmask(irq);
 }
 
-static int __init pl061_probe(struct amba_device *dev, struct amba_id *id)
+static int pl061_probe(struct amba_device *dev, struct amba_id *id)
 {
 	struct pl061_platform_data *pdata;
 	struct pl061_gpio *chip;
@@ -333,7 +333,7 @@
 	return ret;
 }
 
-static struct amba_id pl061_ids[] __initdata = {
+static struct amba_id pl061_ids[] = {
 	{
 		.id	= 0x00041061,
 		.mask	= 0x000fffff,
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 26386a9..9b089df 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -353,6 +353,16 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called vmware_balloon.
 
+config ARM_CHARLCD
+	bool "ARM Ltd. Character LCD Driver"
+	depends on PLAT_VERSATILE
+	help
+	  This is a driver for the character LCD found on the ARM Ltd.
+	  Versatile and RealView Platform Baseboards. It doesn't do
+	  very much more than display the text "ARM Linux" on the first
+	  line and the Linux version on the second line, but that's
+	  still useful.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 6ed06a1..67552d6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -31,3 +31,4 @@
 obj-y				+= eeprom/
 obj-y				+= cb710/
 obj-$(CONFIG_VMWARE_BALLOON)	+= vmware_balloon.o
+obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
diff --git a/drivers/misc/arm-charlcd.c b/drivers/misc/arm-charlcd.c
new file mode 100644
index 0000000..9e3879e
--- /dev/null
+++ b/drivers/misc/arm-charlcd.c
@@ -0,0 +1,396 @@
+/*
+ * Driver for the on-board character LCD found on some ARM reference boards
+ * This is basically an Hitachi HD44780 LCD with a custom IP block to drive it
+ * http://en.wikipedia.org/wiki/HD44780_Character_LCD
+ * Currently it will just display the text "ARM Linux" and the linux version
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ * Author: Linus Walleij <triad@df.lth.se>
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <generated/utsrelease.h>
+
+#define DRIVERNAME "arm-charlcd"
+#define CHARLCD_TIMEOUT (msecs_to_jiffies(1000))
+
+/* Offsets to registers */
+#define CHAR_COM	0x00U
+#define CHAR_DAT	0x04U
+#define CHAR_RD		0x08U
+#define CHAR_RAW	0x0CU
+#define CHAR_MASK	0x10U
+#define CHAR_STAT	0x14U
+
+#define CHAR_RAW_CLEAR	0x00000000U
+#define CHAR_RAW_VALID	0x00000100U
+
+/* Hitachi HD44780 display commands */
+#define HD_CLEAR			0x01U
+#define HD_HOME				0x02U
+#define HD_ENTRYMODE			0x04U
+#define HD_ENTRYMODE_INCREMENT		0x02U
+#define HD_ENTRYMODE_SHIFT		0x01U
+#define HD_DISPCTRL			0x08U
+#define HD_DISPCTRL_ON			0x04U
+#define HD_DISPCTRL_CURSOR_ON		0x02U
+#define HD_DISPCTRL_CURSOR_BLINK	0x01U
+#define HD_CRSR_SHIFT			0x10U
+#define HD_CRSR_SHIFT_DISPLAY		0x08U
+#define HD_CRSR_SHIFT_DISPLAY_RIGHT	0x04U
+#define HD_FUNCSET			0x20U
+#define HD_FUNCSET_8BIT			0x10U
+#define HD_FUNCSET_2_LINES		0x08U
+#define HD_FUNCSET_FONT_5X10		0x04U
+#define HD_SET_CGRAM			0x40U
+#define HD_SET_DDRAM			0x80U
+#define HD_BUSY_FLAG			0x80U
+
+/**
+ * @dev: a pointer back to containing device
+ * @phybase: the offset to the controller in physical memory
+ * @physize: the size of the physical page
+ * @virtbase: the offset to the controller in virtual memory
+ * @irq: reserved interrupt number
+ * @complete: completion structure for the last LCD command
+ */
+struct charlcd {
+	struct device *dev;
+	u32 phybase;
+	u32 physize;
+	void __iomem *virtbase;
+	int irq;
+	struct completion complete;
+	struct delayed_work init_work;
+};
+
+static irqreturn_t charlcd_interrupt(int irq, void *data)
+{
+	struct charlcd *lcd = data;
+	u8 status;
+
+	status = readl(lcd->virtbase + CHAR_STAT) & 0x01;
+	/* Clear IRQ */
+	writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW);
+	if (status)
+		complete(&lcd->complete);
+	else
+		dev_info(lcd->dev, "Spurious IRQ (%02x)\n", status);
+	return IRQ_HANDLED;
+}
+
+
+static void charlcd_wait_complete_irq(struct charlcd *lcd)
+{
+	int ret;
+
+	ret = wait_for_completion_interruptible_timeout(&lcd->complete,
+							CHARLCD_TIMEOUT);
+	/* Disable IRQ after completion */
+	writel(0x00, lcd->virtbase + CHAR_MASK);
+
+	if (ret < 0) {
+		dev_err(lcd->dev,
+			"wait_for_completion_interruptible_timeout() "
+			"returned %d waiting for ready\n", ret);
+		return;
+	}
+
+	if (ret == 0) {
+		dev_err(lcd->dev, "charlcd controller timed out "
+			"waiting for ready\n");
+		return;
+	}
+}
+
+static u8 charlcd_4bit_read_char(struct charlcd *lcd)
+{
+	u8 data;
+	u32 val;
+	int i;
+
+	/* If we can, use an IRQ to wait for the data, else poll */
+	if (lcd->irq >= 0)
+		charlcd_wait_complete_irq(lcd);
+	else {
+		i = 0;
+		val = 0;
+		while (!(val & CHAR_RAW_VALID) && i < 10) {
+			udelay(100);
+			val = readl(lcd->virtbase + CHAR_RAW);
+			i++;
+		}
+
+		writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW);
+	}
+	msleep(1);
+
+	/* Read the 4 high bits of the data */
+	data = readl(lcd->virtbase + CHAR_RD) & 0xf0;
+
+	/*
+	 * The second read for the low bits does not trigger an IRQ
+	 * so in this case we have to poll for the 4 lower bits
+	 */
+	i = 0;
+	val = 0;
+	while (!(val & CHAR_RAW_VALID) && i < 10) {
+		udelay(100);
+		val = readl(lcd->virtbase + CHAR_RAW);
+		i++;
+	}
+	writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW);
+	msleep(1);
+
+	/* Read the 4 low bits of the data */
+	data |= (readl(lcd->virtbase + CHAR_RD) >> 4) & 0x0f;
+
+	return data;
+}
+
+static bool charlcd_4bit_read_bf(struct charlcd *lcd)
+{
+	if (lcd->irq >= 0) {
+		/*
+		 * If we'll use IRQs to wait for the busyflag, clear any
+		 * pending flag and enable IRQ
+		 */
+		writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW);
+		init_completion(&lcd->complete);
+		writel(0x01, lcd->virtbase + CHAR_MASK);
+	}
+	readl(lcd->virtbase + CHAR_COM);
+	return charlcd_4bit_read_char(lcd) & HD_BUSY_FLAG ? true : false;
+}
+
+static void charlcd_4bit_wait_busy(struct charlcd *lcd)
+{
+	int retries = 50;
+
+	udelay(100);
+	while (charlcd_4bit_read_bf(lcd) && retries)
+		retries--;
+	if (!retries)
+		dev_err(lcd->dev, "timeout waiting for busyflag\n");
+}
+
+static void charlcd_4bit_command(struct charlcd *lcd, u8 cmd)
+{
+	u32 cmdlo = (cmd << 4) & 0xf0;
+	u32 cmdhi = (cmd & 0xf0);
+
+	writel(cmdhi, lcd->virtbase + CHAR_COM);
+	udelay(10);
+	writel(cmdlo, lcd->virtbase + CHAR_COM);
+	charlcd_4bit_wait_busy(lcd);
+}
+
+static void charlcd_4bit_char(struct charlcd *lcd, u8 ch)
+{
+	u32 chlo = (ch << 4) & 0xf0;
+	u32 chhi = (ch & 0xf0);
+
+	writel(chhi, lcd->virtbase + CHAR_DAT);
+	udelay(10);
+	writel(chlo, lcd->virtbase + CHAR_DAT);
+	charlcd_4bit_wait_busy(lcd);
+}
+
+static void charlcd_4bit_print(struct charlcd *lcd, int line, const char *str)
+{
+	u8 offset;
+	int i;
+
+	/*
+	 * We support line 0, 1
+	 * Line 1 runs from 0x00..0x27
+	 * Line 2 runs from 0x28..0x4f
+	 */
+	if (line == 0)
+		offset = 0;
+	else if (line == 1)
+		offset = 0x28;
+	else
+		return;
+
+	/* Set offset */
+	charlcd_4bit_command(lcd, HD_SET_DDRAM | offset);
+
+	/* Send string */
+	for (i = 0; i < strlen(str) && i < 0x28; i++)
+		charlcd_4bit_char(lcd, str[i]);
+}
+
+static void charlcd_4bit_init(struct charlcd *lcd)
+{
+	/* These commands cannot be checked with the busy flag */
+	writel(HD_FUNCSET | HD_FUNCSET_8BIT, lcd->virtbase + CHAR_COM);
+	msleep(5);
+	writel(HD_FUNCSET | HD_FUNCSET_8BIT, lcd->virtbase + CHAR_COM);
+	udelay(100);
+	writel(HD_FUNCSET | HD_FUNCSET_8BIT, lcd->virtbase + CHAR_COM);
+	udelay(100);
+	/* Go to 4bit mode */
+	writel(HD_FUNCSET, lcd->virtbase + CHAR_COM);
+	udelay(100);
+	/*
+	 * 4bit mode, 2 lines, 5x8 font, after this the number of lines
+	 * and the font cannot be changed until the next initialization sequence
+	 */
+	charlcd_4bit_command(lcd, HD_FUNCSET | HD_FUNCSET_2_LINES);
+	charlcd_4bit_command(lcd, HD_DISPCTRL | HD_DISPCTRL_ON);
+	charlcd_4bit_command(lcd, HD_ENTRYMODE | HD_ENTRYMODE_INCREMENT);
+	charlcd_4bit_command(lcd, HD_CLEAR);
+	charlcd_4bit_command(lcd, HD_HOME);
+	/* Put something useful in the display */
+	charlcd_4bit_print(lcd, 0, "ARM Linux");
+	charlcd_4bit_print(lcd, 1, UTS_RELEASE);
+}
+
+static void charlcd_init_work(struct work_struct *work)
+{
+	struct charlcd *lcd =
+		container_of(work, struct charlcd, init_work.work);
+
+	charlcd_4bit_init(lcd);
+}
+
+static int __init charlcd_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct charlcd *lcd;
+	struct resource *res;
+
+	lcd = kzalloc(sizeof(struct charlcd), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	lcd->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENOENT;
+		goto out_no_resource;
+	}
+	lcd->phybase = res->start;
+	lcd->physize = resource_size(res);
+
+	if (request_mem_region(lcd->phybase, lcd->physize,
+			       DRIVERNAME) == NULL) {
+		ret = -EBUSY;
+		goto out_no_memregion;
+	}
+
+	lcd->virtbase = ioremap(lcd->phybase, lcd->physize);
+	if (!lcd->virtbase) {
+		ret = -ENOMEM;
+		goto out_no_remap;
+	}
+
+	lcd->irq = platform_get_irq(pdev, 0);
+	/* If no IRQ is supplied, we'll survive without it */
+	if (lcd->irq >= 0) {
+		if (request_irq(lcd->irq, charlcd_interrupt, IRQF_DISABLED,
+				DRIVERNAME, lcd)) {
+			ret = -EIO;
+			goto out_no_irq;
+		}
+	}
+
+	platform_set_drvdata(pdev, lcd);
+
+	/*
+	 * Initialize the display in a delayed work, because
+	 * it is VERY slow and would slow down the boot of the system.
+	 */
+	INIT_DELAYED_WORK(&lcd->init_work, charlcd_init_work);
+	schedule_delayed_work(&lcd->init_work, 0);
+
+	dev_info(&pdev->dev, "initalized ARM character LCD at %08x\n",
+		lcd->phybase);
+
+	return 0;
+
+out_no_irq:
+	iounmap(lcd->virtbase);
+out_no_remap:
+	platform_set_drvdata(pdev, NULL);
+out_no_memregion:
+	release_mem_region(lcd->phybase, SZ_4K);
+out_no_resource:
+	kfree(lcd);
+	return ret;
+}
+
+static int __exit charlcd_remove(struct platform_device *pdev)
+{
+	struct charlcd *lcd = platform_get_drvdata(pdev);
+
+	if (lcd) {
+		free_irq(lcd->irq, lcd);
+		iounmap(lcd->virtbase);
+		release_mem_region(lcd->phybase, lcd->physize);
+		platform_set_drvdata(pdev, NULL);
+		kfree(lcd);
+	}
+
+	return 0;
+}
+
+static int charlcd_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct charlcd *lcd = platform_get_drvdata(pdev);
+
+	/* Power the display off */
+	charlcd_4bit_command(lcd, HD_DISPCTRL);
+	return 0;
+}
+
+static int charlcd_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct charlcd *lcd = platform_get_drvdata(pdev);
+
+	/* Turn the display back on */
+	charlcd_4bit_command(lcd, HD_DISPCTRL | HD_DISPCTRL_ON);
+	return 0;
+}
+
+static const struct dev_pm_ops charlcd_pm_ops = {
+	.suspend = charlcd_suspend,
+	.resume = charlcd_resume,
+};
+
+static struct platform_driver charlcd_driver = {
+	.driver = {
+		.name = DRIVERNAME,
+		.owner = THIS_MODULE,
+		.pm = &charlcd_pm_ops,
+	},
+	.remove = __exit_p(charlcd_remove),
+};
+
+static int __init charlcd_init(void)
+{
+	return platform_driver_probe(&charlcd_driver, charlcd_probe);
+}
+
+static void __exit charlcd_exit(void)
+{
+	platform_driver_unregister(&charlcd_driver);
+}
+
+module_init(charlcd_init);
+module_exit(charlcd_exit);
+
+MODULE_AUTHOR("Linus Walleij <triad@df.lth.se>");
+MODULE_DESCRIPTION("ARM Character LCD Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 4917af9..7edae83 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -26,7 +26,6 @@
 #include <linux/amba/mmci.h>
 #include <linux/regulator/consumer.h>
 
-#include <asm/cacheflush.h>
 #include <asm/div64.h>
 #include <asm/io.h>
 #include <asm/sizes.h>
@@ -37,12 +36,39 @@
 
 static unsigned int fmax = 515633;
 
+/**
+ * struct variant_data - MMCI variant-specific quirks
+ * @clkreg: default value for MCICLOCK register
+ * @clkreg_enable: enable value for MMCICLOCK register
+ * @datalength_bits: number of bits in the MMCIDATALENGTH register
+ */
+struct variant_data {
+	unsigned int		clkreg;
+	unsigned int		clkreg_enable;
+	unsigned int		datalength_bits;
+};
+
+static struct variant_data variant_arm = {
+	.datalength_bits	= 16,
+};
+
+static struct variant_data variant_u300 = {
+	.clkreg_enable		= 1 << 13, /* HWFCEN */
+	.datalength_bits	= 16,
+};
+
+static struct variant_data variant_ux500 = {
+	.clkreg			= MCI_CLK_ENABLE,
+	.clkreg_enable		= 1 << 14, /* HWFCEN */
+	.datalength_bits	= 24,
+};
 /*
  * This must be called with host->lock held
  */
 static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
 {
-	u32 clk = 0;
+	struct variant_data *variant = host->variant;
+	u32 clk = variant->clkreg;
 
 	if (desired) {
 		if (desired >= host->mclk) {
@@ -54,8 +80,8 @@
 				clk = 255;
 			host->cclk = host->mclk / (2 * (clk + 1));
 		}
-		if (host->hw_designer == AMBA_VENDOR_ST)
-			clk |= MCI_ST_FCEN; /* Bug fix in ST IP block */
+
+		clk |= variant->clkreg_enable;
 		clk |= MCI_CLK_ENABLE;
 		/* This hasn't proven to be worthwhile */
 		/* clk |= MCI_CLK_PWRSAVE; */
@@ -98,6 +124,18 @@
 	host->data = NULL;
 }
 
+static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
+{
+	unsigned int flags = SG_MITER_ATOMIC;
+
+	if (data->flags & MMC_DATA_READ)
+		flags |= SG_MITER_TO_SG;
+	else
+		flags |= SG_MITER_FROM_SG;
+
+	sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
+}
+
 static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
 {
 	unsigned int datactrl, timeout, irqmask;
@@ -109,7 +147,7 @@
 		data->blksz, data->blocks, data->flags);
 
 	host->data = data;
-	host->size = data->blksz;
+	host->size = data->blksz * data->blocks;
 	host->data_xfered = 0;
 
 	mmci_init_sg(host, data);
@@ -210,8 +248,17 @@
 		 * We hit an error condition.  Ensure that any data
 		 * partially written to a page is properly coherent.
 		 */
-		if (host->sg_len && data->flags & MMC_DATA_READ)
-			flush_dcache_page(sg_page(host->sg_ptr));
+		if (data->flags & MMC_DATA_READ) {
+			struct sg_mapping_iter *sg_miter = &host->sg_miter;
+			unsigned long flags;
+
+			local_irq_save(flags);
+			if (sg_miter_next(sg_miter)) {
+				flush_dcache_page(sg_miter->page);
+				sg_miter_stop(sg_miter);
+			}
+			local_irq_restore(flags);
+		}
 	}
 	if (status & MCI_DATAEND) {
 		mmci_stop_data(host);
@@ -314,15 +361,18 @@
 static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
 {
 	struct mmci_host *host = dev_id;
+	struct sg_mapping_iter *sg_miter = &host->sg_miter;
 	void __iomem *base = host->base;
+	unsigned long flags;
 	u32 status;
 
 	status = readl(base + MMCISTATUS);
 
 	dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status);
 
+	local_irq_save(flags);
+
 	do {
-		unsigned long flags;
 		unsigned int remain, len;
 		char *buffer;
 
@@ -336,11 +386,11 @@
 		if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL)))
 			break;
 
-		/*
-		 * Map the current scatter buffer.
-		 */
-		buffer = mmci_kmap_atomic(host, &flags) + host->sg_off;
-		remain = host->sg_ptr->length - host->sg_off;
+		if (!sg_miter_next(sg_miter))
+			break;
+
+		buffer = sg_miter->addr;
+		remain = sg_miter->length;
 
 		len = 0;
 		if (status & MCI_RXACTIVE)
@@ -348,31 +398,24 @@
 		if (status & MCI_TXACTIVE)
 			len = mmci_pio_write(host, buffer, remain, status);
 
-		/*
-		 * Unmap the buffer.
-		 */
-		mmci_kunmap_atomic(host, buffer, &flags);
+		sg_miter->consumed = len;
 
-		host->sg_off += len;
 		host->size -= len;
 		remain -= len;
 
 		if (remain)
 			break;
 
-		/*
-		 * If we were reading, and we have completed this
-		 * page, ensure that the data cache is coherent.
-		 */
 		if (status & MCI_RXACTIVE)
-			flush_dcache_page(sg_page(host->sg_ptr));
-
-		if (!mmci_next_sg(host))
-			break;
+			flush_dcache_page(sg_miter->page);
 
 		status = readl(base + MMCISTATUS);
 	} while (1);
 
+	sg_miter_stop(sg_miter);
+
+	local_irq_restore(flags);
+
 	/*
 	 * If we're nearing the end of the read, switch to
 	 * "any data available" mode.
@@ -477,16 +520,9 @@
 			/* This implicitly enables the regulator */
 			mmc_regulator_set_ocr(host->vcc, ios->vdd);
 #endif
-		/*
-		 * The translate_vdd function is not used if you have
-		 * an external regulator, or your design is really weird.
-		 * Using it would mean sending in power control BOTH using
-		 * a regulator AND the 4 MMCIPWR bits. If we don't have
-		 * a regulator, we might have some other platform specific
-		 * power control behind this translate function.
-		 */
-		if (!host->vcc && host->plat->translate_vdd)
-			pwr |= host->plat->translate_vdd(mmc_dev(mmc), ios->vdd);
+		if (host->plat->vdd_handler)
+			pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd,
+						       ios->power_mode);
 		/* The ST version does not have this, fall through to POWER_ON */
 		if (host->hw_designer != AMBA_VENDOR_ST) {
 			pwr |= MCI_PWR_UP;
@@ -551,21 +587,10 @@
 	.get_cd		= mmci_get_cd,
 };
 
-static void mmci_check_status(unsigned long data)
-{
-	struct mmci_host *host = (struct mmci_host *)data;
-	unsigned int status = mmci_get_cd(host->mmc);
-
-	if (status ^ host->oldstat)
-		mmc_detect_change(host->mmc, 0);
-
-	host->oldstat = status;
-	mod_timer(&host->timer, jiffies + HZ);
-}
-
 static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
 {
 	struct mmci_platform_data *plat = dev->dev.platform_data;
+	struct variant_data *variant = id->data;
 	struct mmci_host *host;
 	struct mmc_host *mmc;
 	int ret;
@@ -609,6 +634,7 @@
 		goto clk_free;
 
 	host->plat = plat;
+	host->variant = variant;
 	host->mclk = clk_get_rate(host->clk);
 	/*
 	 * According to the spec, mclk is max 100 MHz,
@@ -669,6 +695,7 @@
 	if (host->vcc == NULL)
 		mmc->ocr_avail = plat->ocr_mask;
 	mmc->caps = plat->capabilities;
+	mmc->caps |= MMC_CAP_NEEDS_POLL;
 
 	/*
 	 * We can do SGIO
@@ -677,10 +704,11 @@
 	mmc->max_phys_segs = NR_SG;
 
 	/*
-	 * Since we only have a 16-bit data length register, we must
-	 * ensure that we don't exceed 2^16-1 bytes in a single request.
+	 * Since only a certain number of bits are valid in the data length
+	 * register, we must ensure that we don't exceed 2^num-1 bytes in a
+	 * single request.
 	 */
-	mmc->max_req_size = 65535;
+	mmc->max_req_size = (1 << variant->datalength_bits) - 1;
 
 	/*
 	 * Set the maximum segment size.  Since we aren't doing DMA
@@ -734,7 +762,6 @@
 	writel(MCI_IRQENABLE, host->base + MMCIMASK0);
 
 	amba_set_drvdata(dev, mmc);
-	host->oldstat = mmci_get_cd(host->mmc);
 
 	mmc_add_host(mmc);
 
@@ -742,12 +769,6 @@
 		mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
 		(unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]);
 
-	init_timer(&host->timer);
-	host->timer.data = (unsigned long)host;
-	host->timer.function = mmci_check_status;
-	host->timer.expires = jiffies + HZ;
-	add_timer(&host->timer);
-
 	return 0;
 
  irq0_free:
@@ -781,8 +802,6 @@
 	if (mmc) {
 		struct mmci_host *host = mmc_priv(mmc);
 
-		del_timer_sync(&host->timer);
-
 		mmc_remove_host(mmc);
 
 		writel(0, host->base + MMCIMASK0);
@@ -856,19 +875,28 @@
 	{
 		.id	= 0x00041180,
 		.mask	= 0x000fffff,
+		.data	= &variant_arm,
 	},
 	{
 		.id	= 0x00041181,
 		.mask	= 0x000fffff,
+		.data	= &variant_arm,
 	},
 	/* ST Micro variants */
 	{
 		.id     = 0x00180180,
 		.mask   = 0x00ffffff,
+		.data	= &variant_u300,
 	},
 	{
 		.id     = 0x00280180,
 		.mask   = 0x00ffffff,
+		.data	= &variant_u300,
+	},
+	{
+		.id     = 0x00480180,
+		.mask   = 0x00ffffff,
+		.data	= &variant_ux500,
 	},
 	{ 0, 0 },
 };
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index d77062e..68970cf 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -28,8 +28,6 @@
 #define MCI_4BIT_BUS		(1 << 11)
 /* 8bit wide buses supported in ST Micro versions */
 #define MCI_ST_8BIT_BUS		(1 << 12)
-/* HW flow control on the ST Micro version */
-#define MCI_ST_FCEN		(1 << 13)
 
 #define MMCIARGUMENT		0x008
 #define MMCICOMMAND		0x00c
@@ -145,6 +143,7 @@
 #define NR_SG		16
 
 struct clk;
+struct variant_data;
 
 struct mmci_host {
 	void __iomem		*base;
@@ -164,6 +163,7 @@
 	unsigned int		cclk;
 	u32			pwr;
 	struct mmci_platform_data *plat;
+	struct variant_data	*variant;
 
 	u8			hw_designer;
 	u8			hw_revision:4;
@@ -171,42 +171,9 @@
 	struct timer_list	timer;
 	unsigned int		oldstat;
 
-	unsigned int		sg_len;
-
 	/* pio stuff */
-	struct scatterlist	*sg_ptr;
-	unsigned int		sg_off;
+	struct sg_mapping_iter	sg_miter;
 	unsigned int		size;
 	struct regulator	*vcc;
 };
 
-static inline void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
-{
-	/*
-	 * Ideally, we want the higher levels to pass us a scatter list.
-	 */
-	host->sg_len = data->sg_len;
-	host->sg_ptr = data->sg;
-	host->sg_off = 0;
-}
-
-static inline int mmci_next_sg(struct mmci_host *host)
-{
-	host->sg_ptr++;
-	host->sg_off = 0;
-	return --host->sg_len;
-}
-
-static inline char *mmci_kmap_atomic(struct mmci_host *host, unsigned long *flags)
-{
-	struct scatterlist *sg = host->sg_ptr;
-
-	local_irq_save(*flags);
-	return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
-}
-
-static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags)
-{
-	kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
-	local_irq_restore(*flags);
-}
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index 7b14a67..1179099 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -286,7 +286,7 @@
 {
 	struct ab3100_regulator *abreg = reg->reg_data;
 
-	if (selector > abreg->voltages_len)
+	if (selector >= abreg->voltages_len)
 		return -EINVAL;
 	return abreg->typ_voltages[selector];
 }
@@ -318,7 +318,7 @@
 	regval &= 0xE0;
 	regval >>= 5;
 
-	if (regval > abreg->voltages_len) {
+	if (regval >= abreg->voltages_len) {
 		dev_err(&reg->dev,
 			"regulator register %02x contains an illegal voltage setting\n",
 			abreg->regreg);
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c
index 14b45762..8152d65 100644
--- a/drivers/regulator/tps6507x-regulator.c
+++ b/drivers/regulator/tps6507x-regulator.c
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/tps6507x.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/mfd/tps6507x.h>
@@ -101,9 +102,12 @@
 	unsigned max_uV;
 	u8 table_len;
 	const u16 *table;
+
+	/* Does DCDC high or the low register defines output voltage? */
+	bool defdcdc_default;
 };
 
-static const struct tps_info tps6507x_pmic_regs[] = {
+static struct tps_info tps6507x_pmic_regs[] = {
 	{
 		.name = "VDCDC1",
 		.min_uV = 725000,
@@ -145,7 +149,7 @@
 	struct regulator_desc desc[TPS6507X_NUM_REGULATOR];
 	struct tps6507x_dev *mfd;
 	struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR];
-	const struct tps_info *info[TPS6507X_NUM_REGULATOR];
+	struct tps_info *info[TPS6507X_NUM_REGULATOR];
 	struct mutex io_lock;
 };
 static inline int tps6507x_pmic_read(struct tps6507x_pmic *tps, u8 reg)
@@ -341,10 +345,16 @@
 		reg = TPS6507X_REG_DEFDCDC1;
 		break;
 	case TPS6507X_DCDC_2:
-		reg = TPS6507X_REG_DEFDCDC2_LOW;
+		if (tps->info[dcdc]->defdcdc_default)
+			reg = TPS6507X_REG_DEFDCDC2_HIGH;
+		else
+			reg = TPS6507X_REG_DEFDCDC2_LOW;
 		break;
 	case TPS6507X_DCDC_3:
-		reg = TPS6507X_REG_DEFDCDC3_LOW;
+		if (tps->info[dcdc]->defdcdc_default)
+			reg = TPS6507X_REG_DEFDCDC3_HIGH;
+		else
+			reg = TPS6507X_REG_DEFDCDC3_LOW;
 		break;
 	default:
 		return -EINVAL;
@@ -370,10 +380,16 @@
 		reg = TPS6507X_REG_DEFDCDC1;
 		break;
 	case TPS6507X_DCDC_2:
-		reg = TPS6507X_REG_DEFDCDC2_LOW;
+		if (tps->info[dcdc]->defdcdc_default)
+			reg = TPS6507X_REG_DEFDCDC2_HIGH;
+		else
+			reg = TPS6507X_REG_DEFDCDC2_LOW;
 		break;
 	case TPS6507X_DCDC_3:
-		reg = TPS6507X_REG_DEFDCDC3_LOW;
+		if (tps->info[dcdc]->defdcdc_default)
+			reg = TPS6507X_REG_DEFDCDC3_HIGH;
+		else
+			reg = TPS6507X_REG_DEFDCDC3_LOW;
 		break;
 	default:
 		return -EINVAL;
@@ -532,7 +548,7 @@
 {
 	struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
 	static int desc_id;
-	const struct tps_info *info = &tps6507x_pmic_regs[0];
+	struct tps_info *info = &tps6507x_pmic_regs[0];
 	struct regulator_init_data *init_data;
 	struct regulator_dev *rdev;
 	struct tps6507x_pmic *tps;
@@ -569,6 +585,12 @@
 	for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) {
 		/* Register the regulators */
 		tps->info[i] = info;
+		if (init_data->driver_data) {
+			struct tps6507x_reg_platform_data *data =
+							init_data->driver_data;
+			tps->info[i]->defdcdc_default = data->defdcdc_default;
+		}
+
 		tps->desc[i].name = info->name;
 		tps->desc[i].id = desc_id++;
 		tps->desc[i].n_voltages = num_voltages[i];
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 723cd1f..0e6ed7d 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1495,7 +1495,7 @@
 	if (ret != 0) {
 		dev_err(wm8350->dev, "Failed to register regulator %d: %d\n",
 			reg, ret);
-		platform_device_del(pdev);
+		platform_device_put(pdev);
 		wm8350->pmic.pdev[reg] = NULL;
 	}
 
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index 3587d99..71bbefc 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -456,7 +456,7 @@
 	.irq_set_freq = pl031_irq_set_freq,
 };
 
-static struct amba_id pl031_ids[] __initdata = {
+static struct amba_id pl031_ids[] = {
 	{
 		.id = 0x00041031,
 		.mask = 0x000fffff,
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index e3dbeda..fd068bc 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -714,6 +714,14 @@
 	if (zfcp_erp_adapter_strategy_open_fsf_xport(act) == ZFCP_ERP_FAILED)
 		return ZFCP_ERP_FAILED;
 
+	if (mempool_resize(act->adapter->pool.status_read_data,
+			   act->adapter->stat_read_buf_num, GFP_KERNEL))
+		return ZFCP_ERP_FAILED;
+
+	if (mempool_resize(act->adapter->pool.status_read_req,
+			   act->adapter->stat_read_buf_num, GFP_KERNEL))
+		return ZFCP_ERP_FAILED;
+
 	atomic_set(&act->adapter->stat_miss, act->adapter->stat_read_buf_num);
 	if (zfcp_status_read_refill(act->adapter))
 		return ZFCP_ERP_FAILED;
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 9ac6a6e..71663fb 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -496,7 +496,8 @@
 
 	adapter->hydra_version = bottom->adapter_type;
 	adapter->timer_ticks = bottom->timer_interval;
-	adapter->stat_read_buf_num = max(bottom->status_read_buf_num, (u16)16);
+	adapter->stat_read_buf_num = max(bottom->status_read_buf_num,
+					 (u16)FSF_STATUS_READS_RECOM);
 
 	if (fc_host_permanent_port_name(shost) == -1)
 		fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
@@ -719,11 +720,6 @@
 	zfcp_qdio_req_init(adapter->qdio, &req->qdio_req, req->req_id, sbtype,
 			   req->qtcb, sizeof(struct fsf_qtcb));
 
-	if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) {
-		zfcp_fsf_req_free(req);
-		return ERR_PTR(-EIO);
-	}
-
 	return req;
 }
 
@@ -981,7 +977,7 @@
 	}
 
 	/* use single, unchained SBAL if it can hold the request */
-	if (zfcp_qdio_sg_one_sbale(sg_req) || zfcp_qdio_sg_one_sbale(sg_resp)) {
+	if (zfcp_qdio_sg_one_sbale(sg_req) && zfcp_qdio_sg_one_sbale(sg_resp)) {
 		zfcp_fsf_setup_ct_els_unchained(adapter->qdio, &req->qdio_req,
 						sg_req, sg_resp);
 		return 0;
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 28117e1..6fa5e04 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -251,7 +251,8 @@
 	struct zfcp_qdio_queue *req_q = &qdio->req_q;
 
 	spin_lock_bh(&qdio->req_q_lock);
-	if (atomic_read(&req_q->count))
+	if (atomic_read(&req_q->count) ||
+	    !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
 		return 1;
 	spin_unlock_bh(&qdio->req_q_lock);
 	return 0;
@@ -274,8 +275,13 @@
 	spin_unlock_bh(&qdio->req_q_lock);
 	ret = wait_event_interruptible_timeout(qdio->req_q_wq,
 			       zfcp_qdio_sbal_check(qdio), 5 * HZ);
+
+	if (!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
+		return -EIO;
+
 	if (ret > 0)
 		return 0;
+
 	if (!ret) {
 		atomic_inc(&qdio->req_q_full);
 		/* assume hanging outbound queue, try queue recovery */
@@ -375,6 +381,8 @@
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status);
 	spin_unlock_bh(&qdio->req_q_lock);
 
+	wake_up(&qdio->req_q_wq);
+
 	qdio_shutdown(qdio->adapter->ccw_device,
 		      QDIO_FLAG_CLEANUP_USING_CLEAR);
 
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index a864ccc..989b9a8 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -277,6 +277,12 @@
 		goto reg_crq_failed;
 	}
 
+	queue->cur = 0;
+	spin_lock_init(&queue->lock);
+
+	tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task,
+		     (unsigned long)hostdata);
+
 	if (request_irq(vdev->irq,
 			rpavscsi_handle_event,
 			0, "ibmvscsi", (void *)hostdata) != 0) {
@@ -291,15 +297,10 @@
 		goto req_irq_failed;
 	}
 
-	queue->cur = 0;
-	spin_lock_init(&queue->lock);
-
-	tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task,
-		     (unsigned long)hostdata);
-
 	return retrc;
 
       req_irq_failed:
+	tasklet_kill(&hostdata->srp_task);
 	do {
 		rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
 	} while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 82ea4a8..f820cff 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -1129,20 +1129,22 @@
 }
 
 /**
- * ipr_format_resource_path - Format the resource path for printing.
+ * ipr_format_res_path - Format the resource path for printing.
  * @res_path:	resource path
  * @buf:	buffer
  *
  * Return value:
  * 	pointer to buffer
  **/
-static char *ipr_format_resource_path(u8 *res_path, char *buffer)
+static char *ipr_format_res_path(u8 *res_path, char *buffer, int len)
 {
 	int i;
+	char *p = buffer;
 
-	sprintf(buffer, "%02X", res_path[0]);
-	for (i=1; res_path[i] != 0xff; i++)
-		sprintf(buffer, "%s-%02X", buffer, res_path[i]);
+	res_path[0] = '\0';
+	p += snprintf(p, buffer + len - p, "%02X", res_path[0]);
+	for (i = 1; res_path[i] != 0xff && ((i * 3) < len); i++)
+		p += snprintf(p, buffer + len - p, "-%02X", res_path[i]);
 
 	return buffer;
 }
@@ -1187,7 +1189,8 @@
 
 		if (res->sdev && new_path)
 			sdev_printk(KERN_INFO, res->sdev, "Resource path: %s\n",
-				    ipr_format_resource_path(&res->res_path[0], &buffer[0]));
+				    ipr_format_res_path(res->res_path, buffer,
+							sizeof(buffer)));
 	} else {
 		res->flags = cfgtew->u.cfgte->flags;
 		if (res->flags & IPR_IS_IOA_RESOURCE)
@@ -1573,7 +1576,8 @@
 		ipr_err_separator;
 
 		ipr_err("Device %d : %s", i + 1,
-			 ipr_format_resource_path(&dev_entry->res_path[0], &buffer[0]));
+			 ipr_format_res_path(dev_entry->res_path, buffer,
+					     sizeof(buffer)));
 		ipr_log_ext_vpd(&dev_entry->vpd);
 
 		ipr_err("-----New Device Information-----\n");
@@ -1919,13 +1923,14 @@
 
 			ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s\n",
 				     path_active_desc[i].desc, path_state_desc[j].desc,
-				     ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
+				     ipr_format_res_path(fabric->res_path, buffer,
+							 sizeof(buffer)));
 			return;
 		}
 	}
 
 	ipr_err("Path state=%02X Resource Path=%s\n", path_state,
-		ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
+		ipr_format_res_path(fabric->res_path, buffer, sizeof(buffer)));
 }
 
 static const struct {
@@ -2066,7 +2071,8 @@
 
 			ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s, Link rate=%s, WWN=%08X%08X\n",
 				     path_status_desc[j].desc, path_type_desc[i].desc,
-				     ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
+				     ipr_format_res_path(cfg->res_path, buffer,
+							 sizeof(buffer)),
 				     link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
 				     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
 			return;
@@ -2074,7 +2080,7 @@
 	}
 	ipr_hcam_err(hostrcb, "Path element=%02X: Resource Path=%s, Link rate=%s "
 		     "WWN=%08X%08X\n", cfg->type_status,
-		     ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
+		     ipr_format_res_path(cfg->res_path, buffer, sizeof(buffer)),
 		     link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
 		     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
 }
@@ -2139,7 +2145,7 @@
 
 	ipr_err("RAID %s Array Configuration: %s\n",
 		error->protection_level,
-		ipr_format_resource_path(&error->last_res_path[0], &buffer[0]));
+		ipr_format_res_path(error->last_res_path, buffer, sizeof(buffer)));
 
 	ipr_err_separator;
 
@@ -2160,9 +2166,11 @@
 		ipr_err("Array Member %d:\n", i);
 		ipr_log_ext_vpd(&array_entry->vpd);
 		ipr_err("Current Location: %s",
-			 ipr_format_resource_path(&array_entry->res_path[0], &buffer[0]));
+			 ipr_format_res_path(array_entry->res_path, buffer,
+					     sizeof(buffer)));
 		ipr_err("Expected Location: %s",
-			 ipr_format_resource_path(&array_entry->expected_res_path[0], &buffer[0]));
+			 ipr_format_res_path(array_entry->expected_res_path,
+					     buffer, sizeof(buffer)));
 
 		ipr_err_separator;
 	}
@@ -4079,7 +4087,8 @@
 };
 
 /**
- * ipr_show_resource_path - Show the resource path for this device.
+ * ipr_show_resource_path - Show the resource path or the resource address for
+ *			    this device.
  * @dev:	device struct
  * @buf:	buffer
  *
@@ -4097,9 +4106,14 @@
 
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 	res = (struct ipr_resource_entry *)sdev->hostdata;
-	if (res)
+	if (res && ioa_cfg->sis64)
 		len = snprintf(buf, PAGE_SIZE, "%s\n",
-			       ipr_format_resource_path(&res->res_path[0], &buffer[0]));
+			       ipr_format_res_path(res->res_path, buffer,
+						   sizeof(buffer)));
+	else if (res)
+		len = snprintf(buf, PAGE_SIZE, "%d:%d:%d:%d\n", ioa_cfg->host->host_no,
+			       res->bus, res->target, res->lun);
+
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 	return len;
 }
@@ -4351,7 +4365,8 @@
 			scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
 		if (ioa_cfg->sis64)
 			sdev_printk(KERN_INFO, sdev, "Resource path: %s\n",
-			            ipr_format_resource_path(&res->res_path[0], &buffer[0]));
+				    ipr_format_res_path(res->res_path, buffer,
+							sizeof(buffer)));
 		return 0;
 	}
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 9ecd225..b965f358 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1684,8 +1684,9 @@
 	if (ipr_is_device(hostrcb)) {					\
 		if ((hostrcb)->ioa_cfg->sis64) {			\
 			printk(KERN_ERR IPR_NAME ": %s: " fmt, 		\
-				ipr_format_resource_path(&hostrcb->hcam.u.error64.fd_res_path[0], \
-					&hostrcb->rp_buffer[0]),	\
+				ipr_format_res_path(hostrcb->hcam.u.error64.fd_res_path, \
+					hostrcb->rp_buffer,		\
+					sizeof(hostrcb->rp_buffer)),	\
 				__VA_ARGS__);				\
 		} else {						\
 			ipr_ra_err((hostrcb)->ioa_cfg,			\
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index b09a638..50441ff 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -782,7 +782,7 @@
 	return 0;
 }
 
-static struct amba_id pl010_ids[] __initdata = {
+static struct amba_id pl010_ids[] = {
 	{
 		.id	= 0x00041010,
 		.mask	= 0x000fffff,
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index eb4cb48..6ca7a44 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -69,9 +69,12 @@
 struct uart_amba_port {
 	struct uart_port	port;
 	struct clk		*clk;
-	unsigned int		im;	/* interrupt mask */
+	unsigned int		im;		/* interrupt mask */
 	unsigned int		old_status;
-	unsigned int		ifls;	/* vendor-specific */
+	unsigned int		ifls;		/* vendor-specific */
+	unsigned int		lcrh_tx;	/* vendor-specific */
+	unsigned int		lcrh_rx;	/* vendor-specific */
+	bool			oversampling;   /* vendor-specific */
 	bool			autorts;
 };
 
@@ -79,16 +82,25 @@
 struct vendor_data {
 	unsigned int		ifls;
 	unsigned int		fifosize;
+	unsigned int		lcrh_tx;
+	unsigned int		lcrh_rx;
+	bool			oversampling;
 };
 
 static struct vendor_data vendor_arm = {
 	.ifls			= UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
 	.fifosize		= 16,
+	.lcrh_tx		= UART011_LCRH,
+	.lcrh_rx		= UART011_LCRH,
+	.oversampling		= false,
 };
 
 static struct vendor_data vendor_st = {
 	.ifls			= UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF,
 	.fifosize		= 64,
+	.lcrh_tx		= ST_UART011_LCRH_TX,
+	.lcrh_rx		= ST_UART011_LCRH_RX,
+	.oversampling		= true,
 };
 
 static void pl011_stop_tx(struct uart_port *port)
@@ -327,12 +339,12 @@
 	unsigned int lcr_h;
 
 	spin_lock_irqsave(&uap->port.lock, flags);
-	lcr_h = readw(uap->port.membase + UART011_LCRH);
+	lcr_h = readw(uap->port.membase + uap->lcrh_tx);
 	if (break_state == -1)
 		lcr_h |= UART01x_LCRH_BRK;
 	else
 		lcr_h &= ~UART01x_LCRH_BRK;
-	writew(lcr_h, uap->port.membase + UART011_LCRH);
+	writew(lcr_h, uap->port.membase + uap->lcrh_tx);
 	spin_unlock_irqrestore(&uap->port.lock, flags);
 }
 
@@ -393,7 +405,17 @@
 	writew(cr, uap->port.membase + UART011_CR);
 	writew(0, uap->port.membase + UART011_FBRD);
 	writew(1, uap->port.membase + UART011_IBRD);
-	writew(0, uap->port.membase + UART011_LCRH);
+	writew(0, uap->port.membase + uap->lcrh_rx);
+	if (uap->lcrh_tx != uap->lcrh_rx) {
+		int i;
+		/*
+		 * Wait 10 PCLKs before writing LCRH_TX register,
+		 * to get this delay write read only register 10 times
+		 */
+		for (i = 0; i < 10; ++i)
+			writew(0xff, uap->port.membase + UART011_MIS);
+		writew(0, uap->port.membase + uap->lcrh_tx);
+	}
 	writew(0, uap->port.membase + UART01x_DR);
 	while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
 		barrier();
@@ -422,10 +444,19 @@
 	return retval;
 }
 
+static void pl011_shutdown_channel(struct uart_amba_port *uap,
+					unsigned int lcrh)
+{
+      unsigned long val;
+
+      val = readw(uap->port.membase + lcrh);
+      val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN);
+      writew(val, uap->port.membase + lcrh);
+}
+
 static void pl011_shutdown(struct uart_port *port)
 {
 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
-	unsigned long val;
 
 	/*
 	 * disable all interrupts
@@ -450,9 +481,9 @@
 	/*
 	 * disable break condition and fifos
 	 */
-	val = readw(uap->port.membase + UART011_LCRH);
-	val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN);
-	writew(val, uap->port.membase + UART011_LCRH);
+	pl011_shutdown_channel(uap, uap->lcrh_rx);
+	if (uap->lcrh_rx != uap->lcrh_tx)
+		pl011_shutdown_channel(uap, uap->lcrh_tx);
 
 	/*
 	 * Shut down the clock producer
@@ -472,8 +503,13 @@
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
-	quot = port->uartclk * 4 / baud;
+	baud = uart_get_baud_rate(port, termios, old, 0,
+				  port->uartclk/(uap->oversampling ? 8 : 16));
+
+	if (baud > port->uartclk/16)
+		quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud);
+	else
+		quot = DIV_ROUND_CLOSEST(port->uartclk * 4, baud);
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
@@ -552,6 +588,13 @@
 		uap->autorts = false;
 	}
 
+	if (uap->oversampling) {
+		if (baud > port->uartclk/16)
+			old_cr |= ST_UART011_CR_OVSFACT;
+		else
+			old_cr &= ~ST_UART011_CR_OVSFACT;
+	}
+
 	/* Set baud rate */
 	writew(quot & 0x3f, port->membase + UART011_FBRD);
 	writew(quot >> 6, port->membase + UART011_IBRD);
@@ -561,7 +604,17 @@
 	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
 	 * ----------^----------^----------^----------^-----
 	 */
-	writew(lcr_h, port->membase + UART011_LCRH);
+	writew(lcr_h, port->membase + uap->lcrh_rx);
+	if (uap->lcrh_rx != uap->lcrh_tx) {
+		int i;
+		/*
+		 * Wait 10 PCLKs before writing LCRH_TX register,
+		 * to get this delay write read only register 10 times
+		 */
+		for (i = 0; i < 10; ++i)
+			writew(0xff, uap->port.membase + UART011_MIS);
+		writew(lcr_h, port->membase + uap->lcrh_tx);
+	}
 	writew(old_cr, port->membase + UART011_CR);
 
 	spin_unlock_irqrestore(&port->lock, flags);
@@ -688,7 +741,7 @@
 	if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) {
 		unsigned int lcr_h, ibrd, fbrd;
 
-		lcr_h = readw(uap->port.membase + UART011_LCRH);
+		lcr_h = readw(uap->port.membase + uap->lcrh_tx);
 
 		*parity = 'n';
 		if (lcr_h & UART01x_LCRH_PEN) {
@@ -707,6 +760,12 @@
 		fbrd = readw(uap->port.membase + UART011_FBRD);
 
 		*baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);
+
+		if (uap->oversampling) {
+			if (readw(uap->port.membase + UART011_CR)
+				  & ST_UART011_CR_OVSFACT)
+				*baud *= 2;
+		}
 	}
 }
 
@@ -800,6 +859,9 @@
 	}
 
 	uap->ifls = vendor->ifls;
+	uap->lcrh_rx = vendor->lcrh_rx;
+	uap->lcrh_tx = vendor->lcrh_tx;
+	uap->oversampling = vendor->oversampling;
 	uap->port.dev = &dev->dev;
 	uap->port.mapbase = dev->res.start;
 	uap->port.membase = base;
@@ -868,7 +930,7 @@
 }
 #endif
 
-static struct amba_id pl011_ids[] __initdata = {
+static struct amba_id pl011_ids[] = {
 	{
 		.id	= 0x00041011,
 		.mask	= 0x000fffff,
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index eaa79c8..93ead19 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -76,11 +76,12 @@
 static const char driver_name [] = "at91_udc";
 static const char ep0name[] = "ep0";
 
+#define VBUS_POLL_TIMEOUT	msecs_to_jiffies(1000)
 
-#define at91_udp_read(dev, reg) \
-	__raw_readl((dev)->udp_baseaddr + (reg))
-#define at91_udp_write(dev, reg, val) \
-	__raw_writel((val), (dev)->udp_baseaddr + (reg))
+#define at91_udp_read(udc, reg) \
+	__raw_readl((udc)->udp_baseaddr + (reg))
+#define at91_udp_write(udc, reg, val) \
+	__raw_writel((val), (udc)->udp_baseaddr + (reg))
 
 /*-------------------------------------------------------------------------*/
 
@@ -102,8 +103,9 @@
 	u32			csr;
 	struct at91_request	*req;
 	unsigned long	flags;
+	struct at91_udc	*udc = ep->udc;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&udc->lock, flags);
 
 	csr = __raw_readl(ep->creg);
 
@@ -147,7 +149,7 @@
 				&req->req, length,
 				req->req.length, req->req.buf);
 	}
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 }
 
 static void proc_irq_show(struct seq_file *s, const char *label, u32 mask)
@@ -272,7 +274,9 @@
 		VDBG("%s done %p, status %d\n", ep->ep.name, req, status);
 
 	ep->stopped = 1;
+	spin_unlock(&udc->lock);
 	req->req.complete(&ep->ep, &req->req);
+	spin_lock(&udc->lock);
 	ep->stopped = stopped;
 
 	/* ep0 is always ready; other endpoints need a non-empty queue */
@@ -472,7 +476,7 @@
 				const struct usb_endpoint_descriptor *desc)
 {
 	struct at91_ep	*ep = container_of(_ep, struct at91_ep, ep);
-	struct at91_udc	*dev = ep->udc;
+	struct at91_udc	*udc = ep->udc;
 	u16		maxpacket;
 	u32		tmp;
 	unsigned long	flags;
@@ -487,7 +491,7 @@
 		return -EINVAL;
 	}
 
-	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
+	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
 		DBG("bogus device state\n");
 		return -ESHUTDOWN;
 	}
@@ -521,7 +525,7 @@
 	}
 
 ok:
-	local_irq_save(flags);
+	spin_lock_irqsave(&udc->lock, flags);
 
 	/* initialize endpoint to match this descriptor */
 	ep->is_in = usb_endpoint_dir_in(desc);
@@ -540,10 +544,10 @@
 	 * reset/init endpoint fifo.  NOTE:  leaves fifo_bank alone,
 	 * since endpoint resets don't reset hw pingpong state.
 	 */
-	at91_udp_write(dev, AT91_UDP_RST_EP, ep->int_mask);
-	at91_udp_write(dev, AT91_UDP_RST_EP, 0);
+	at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask);
+	at91_udp_write(udc, AT91_UDP_RST_EP, 0);
 
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 	return 0;
 }
 
@@ -556,7 +560,7 @@
 	if (ep == &ep->udc->ep[0])
 		return -EINVAL;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&udc->lock, flags);
 
 	nuke(ep, -ESHUTDOWN);
 
@@ -571,7 +575,7 @@
 		__raw_writel(0, ep->creg);
 	}
 
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 	return 0;
 }
 
@@ -607,7 +611,7 @@
 {
 	struct at91_request	*req;
 	struct at91_ep		*ep;
-	struct at91_udc		*dev;
+	struct at91_udc		*udc;
 	int			status;
 	unsigned long		flags;
 
@@ -625,9 +629,9 @@
 		return -EINVAL;
 	}
 
-	dev = ep->udc;
+	udc = ep->udc;
 
-	if (!dev || !dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
+	if (!udc || !udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
 		DBG("invalid device\n");
 		return -EINVAL;
 	}
@@ -635,7 +639,7 @@
 	_req->status = -EINPROGRESS;
 	_req->actual = 0;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&udc->lock, flags);
 
 	/* try to kickstart any empty and idle queue */
 	if (list_empty(&ep->queue) && !ep->stopped) {
@@ -653,7 +657,7 @@
 		if (is_ep0) {
 			u32	tmp;
 
-			if (!dev->req_pending) {
+			if (!udc->req_pending) {
 				status = -EINVAL;
 				goto done;
 			}
@@ -662,11 +666,11 @@
 			 * defer changing CONFG until after the gadget driver
 			 * reconfigures the endpoints.
 			 */
-			if (dev->wait_for_config_ack) {
-				tmp = at91_udp_read(dev, AT91_UDP_GLB_STAT);
+			if (udc->wait_for_config_ack) {
+				tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
 				tmp ^= AT91_UDP_CONFG;
 				VDBG("toggle config\n");
-				at91_udp_write(dev, AT91_UDP_GLB_STAT, tmp);
+				at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp);
 			}
 			if (req->req.length == 0) {
 ep0_in_status:
@@ -676,7 +680,7 @@
 				tmp &= ~SET_FX;
 				tmp |= CLR_FX | AT91_UDP_TXPKTRDY;
 				__raw_writel(tmp, ep->creg);
-				dev->req_pending = 0;
+				udc->req_pending = 0;
 				goto done;
 			}
 		}
@@ -695,31 +699,40 @@
 
 	if (req && !status) {
 		list_add_tail (&req->queue, &ep->queue);
-		at91_udp_write(dev, AT91_UDP_IER, ep->int_mask);
+		at91_udp_write(udc, AT91_UDP_IER, ep->int_mask);
 	}
 done:
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 	return (status < 0) ? status : 0;
 }
 
 static int at91_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 {
-	struct at91_ep	*ep;
+	struct at91_ep		*ep;
 	struct at91_request	*req;
+	unsigned long		flags;
+	struct at91_udc		*udc;
 
 	ep = container_of(_ep, struct at91_ep, ep);
 	if (!_ep || ep->ep.name == ep0name)
 		return -EINVAL;
 
+	udc = ep->udc;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
 	/* make sure it's actually queued on this endpoint */
 	list_for_each_entry (req, &ep->queue, queue) {
 		if (&req->req == _req)
 			break;
 	}
-	if (&req->req != _req)
+	if (&req->req != _req) {
+		spin_unlock_irqrestore(&udc->lock, flags);
 		return -EINVAL;
+	}
 
 	done(ep, req, -ECONNRESET);
+	spin_unlock_irqrestore(&udc->lock, flags);
 	return 0;
 }
 
@@ -736,7 +749,7 @@
 		return -EINVAL;
 
 	creg = ep->creg;
-	local_irq_save(flags);
+	spin_lock_irqsave(&udc->lock, flags);
 
 	csr = __raw_readl(creg);
 
@@ -761,7 +774,7 @@
 		__raw_writel(csr, creg);
 	}
 
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 	return status;
 }
 
@@ -795,7 +808,7 @@
 	unsigned long	flags;
 
 	DBG("%s\n", __func__ );
-	local_irq_save(flags);
+	spin_lock_irqsave(&udc->lock, flags);
 
 	if (!udc->clocked || !udc->suspended)
 		goto done;
@@ -809,7 +822,7 @@
 	at91_udp_write(udc, AT91_UDP_GLB_STAT, glbstate);
 
 done:
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 	return status;
 }
 
@@ -851,8 +864,11 @@
 		ep->stopped = 1;
 		nuke(ep, -ESHUTDOWN);
 	}
-	if (driver)
+	if (driver) {
+		spin_unlock(&udc->lock);
 		driver->disconnect(&udc->gadget);
+		spin_lock(&udc->lock);
+	}
 
 	udc_reinit(udc);
 }
@@ -935,13 +951,13 @@
 	unsigned long	flags;
 
 	// VDBG("vbus %s\n", is_active ? "on" : "off");
-	local_irq_save(flags);
+	spin_lock_irqsave(&udc->lock, flags);
 	udc->vbus = (is_active != 0);
 	if (udc->driver)
 		pullup(udc, is_active);
 	else
 		pullup(udc, 0);
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 	return 0;
 }
 
@@ -950,10 +966,10 @@
 	struct at91_udc	*udc = to_udc(gadget);
 	unsigned long	flags;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&udc->lock, flags);
 	udc->enabled = is_on = !!is_on;
 	pullup(udc, is_on);
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 	return 0;
 }
 
@@ -962,9 +978,9 @@
 	struct at91_udc	*udc = to_udc(gadget);
 	unsigned long	flags;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&udc->lock, flags);
 	udc->selfpowered = (is_on != 0);
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 	return 0;
 }
 
@@ -1226,8 +1242,11 @@
 #undef w_length
 
 	/* pass request up to the gadget driver */
-	if (udc->driver)
+	if (udc->driver) {
+		spin_unlock(&udc->lock);
 		status = udc->driver->setup(&udc->gadget, &pkt.r);
+		spin_lock(&udc->lock);
+	}
 	else
 		status = -ENODEV;
 	if (status < 0) {
@@ -1378,6 +1397,9 @@
 	struct at91_udc		*udc = _udc;
 	u32			rescans = 5;
 	int			disable_clock = 0;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
 
 	if (!udc->clocked) {
 		clk_on(udc);
@@ -1433,8 +1455,11 @@
 			 * and then into standby to avoid drawing more than
 			 * 500uA power (2500uA for some high-power configs).
 			 */
-			if (udc->driver && udc->driver->suspend)
+			if (udc->driver && udc->driver->suspend) {
+				spin_unlock(&udc->lock);
 				udc->driver->suspend(&udc->gadget);
+				spin_lock(&udc->lock);
+			}
 
 		/* host initiated resume */
 		} else if (status & AT91_UDP_RXRSM) {
@@ -1451,8 +1476,11 @@
 			 * would normally want to switch out of slow clock
 			 * mode into normal mode.
 			 */
-			if (udc->driver && udc->driver->resume)
+			if (udc->driver && udc->driver->resume) {
+				spin_unlock(&udc->lock);
 				udc->driver->resume(&udc->gadget);
+				spin_lock(&udc->lock);
+			}
 
 		/* endpoint IRQs are cleared by handling them */
 		} else {
@@ -1474,6 +1502,8 @@
 	if (disable_clock)
 		clk_off(udc);
 
+	spin_unlock_irqrestore(&udc->lock, flags);
+
 	return IRQ_HANDLED;
 }
 
@@ -1556,24 +1586,53 @@
 	/* ep6 and ep7 are also reserved (custom silicon might use them) */
 };
 
+static void at91_vbus_update(struct at91_udc *udc, unsigned value)
+{
+	value ^= udc->board.vbus_active_low;
+	if (value != udc->vbus)
+		at91_vbus_session(&udc->gadget, value);
+}
+
 static irqreturn_t at91_vbus_irq(int irq, void *_udc)
 {
 	struct at91_udc	*udc = _udc;
-	unsigned	value;
 
 	/* vbus needs at least brief debouncing */
 	udelay(10);
-	value = gpio_get_value(udc->board.vbus_pin);
-	if (value != udc->vbus)
-		at91_vbus_session(&udc->gadget, value);
+	at91_vbus_update(udc, gpio_get_value(udc->board.vbus_pin));
 
 	return IRQ_HANDLED;
 }
 
+static void at91_vbus_timer_work(struct work_struct *work)
+{
+	struct at91_udc *udc = container_of(work, struct at91_udc,
+					    vbus_timer_work);
+
+	at91_vbus_update(udc, gpio_get_value_cansleep(udc->board.vbus_pin));
+
+	if (!timer_pending(&udc->vbus_timer))
+		mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT);
+}
+
+static void at91_vbus_timer(unsigned long data)
+{
+	struct at91_udc *udc = (struct at91_udc *)data;
+
+	/*
+	 * If we are polling vbus it is likely that the gpio is on an
+	 * bus such as i2c or spi which may sleep, so schedule some work
+	 * to read the vbus gpio
+	 */
+	if (!work_pending(&udc->vbus_timer_work))
+		schedule_work(&udc->vbus_timer_work);
+}
+
 int usb_gadget_register_driver (struct usb_gadget_driver *driver)
 {
 	struct at91_udc	*udc = &controller;
 	int		retval;
+	unsigned long	flags;
 
 	if (!driver
 			|| driver->speed < USB_SPEED_FULL
@@ -1605,9 +1664,9 @@
 		return retval;
 	}
 
-	local_irq_disable();
+	spin_lock_irqsave(&udc->lock, flags);
 	pullup(udc, 1);
-	local_irq_enable();
+	spin_unlock_irqrestore(&udc->lock, flags);
 
 	DBG("bound to %s\n", driver->driver.name);
 	return 0;
@@ -1617,15 +1676,16 @@
 int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 {
 	struct at91_udc *udc = &controller;
+	unsigned long	flags;
 
 	if (!driver || driver != udc->driver || !driver->unbind)
 		return -EINVAL;
 
-	local_irq_disable();
+	spin_lock_irqsave(&udc->lock, flags);
 	udc->enabled = 0;
 	at91_udp_write(udc, AT91_UDP_IDR, ~0);
 	pullup(udc, 0);
-	local_irq_enable();
+	spin_unlock_irqrestore(&udc->lock, flags);
 
 	driver->unbind(&udc->gadget);
 	udc->gadget.dev.driver = NULL;
@@ -1641,8 +1701,13 @@
 
 static void at91udc_shutdown(struct platform_device *dev)
 {
+	struct at91_udc *udc = platform_get_drvdata(dev);
+	unsigned long	flags;
+
 	/* force disconnect on reboot */
+	spin_lock_irqsave(&udc->lock, flags);
 	pullup(platform_get_drvdata(dev), 0);
+	spin_unlock_irqrestore(&udc->lock, flags);
 }
 
 static int __init at91udc_probe(struct platform_device *pdev)
@@ -1683,6 +1748,7 @@
 	udc->board = *(struct at91_udc_data *) dev->platform_data;
 	udc->pdev = pdev;
 	udc->enabled = 0;
+	spin_lock_init(&udc->lock);
 
 	/* rm9200 needs manual D+ pullup; off by default */
 	if (cpu_is_at91rm9200()) {
@@ -1763,13 +1829,23 @@
 		 * Get the initial state of VBUS - we cannot expect
 		 * a pending interrupt.
 		 */
-		udc->vbus = gpio_get_value(udc->board.vbus_pin);
-		if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
-				IRQF_DISABLED, driver_name, udc)) {
-			DBG("request vbus irq %d failed\n",
-					udc->board.vbus_pin);
-			retval = -EBUSY;
-			goto fail3;
+		udc->vbus = gpio_get_value_cansleep(udc->board.vbus_pin) ^
+			udc->board.vbus_active_low;
+
+		if (udc->board.vbus_polled) {
+			INIT_WORK(&udc->vbus_timer_work, at91_vbus_timer_work);
+			setup_timer(&udc->vbus_timer, at91_vbus_timer,
+				    (unsigned long)udc);
+			mod_timer(&udc->vbus_timer,
+				  jiffies + VBUS_POLL_TIMEOUT);
+		} else {
+			if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
+					IRQF_DISABLED, driver_name, udc)) {
+				DBG("request vbus irq %d failed\n",
+				    udc->board.vbus_pin);
+				retval = -EBUSY;
+				goto fail3;
+			}
 		}
 	} else {
 		DBG("no VBUS detection, assuming always-on\n");
@@ -1804,13 +1880,16 @@
 {
 	struct at91_udc *udc = platform_get_drvdata(pdev);
 	struct resource *res;
+	unsigned long	flags;
 
 	DBG("remove\n");
 
 	if (udc->driver)
 		return -EBUSY;
 
+	spin_lock_irqsave(&udc->lock, flags);
 	pullup(udc, 0);
+	spin_unlock_irqrestore(&udc->lock, flags);
 
 	device_init_wakeup(&pdev->dev, 0);
 	remove_debug_file(udc);
@@ -1840,6 +1919,7 @@
 {
 	struct at91_udc *udc = platform_get_drvdata(pdev);
 	int		wake = udc->driver && device_may_wakeup(&pdev->dev);
+	unsigned long	flags;
 
 	/* Unless we can act normally to the host (letting it wake us up
 	 * whenever it has work for us) force disconnect.  Wakeup requires
@@ -1849,13 +1929,15 @@
 	if ((!udc->suspended && udc->addr)
 			|| !wake
 			|| at91_suspend_entering_slow_clock()) {
+		spin_lock_irqsave(&udc->lock, flags);
 		pullup(udc, 0);
 		wake = 0;
+		spin_unlock_irqrestore(&udc->lock, flags);
 	} else
 		enable_irq_wake(udc->udp_irq);
 
 	udc->active_suspend = wake;
-	if (udc->board.vbus_pin > 0 && wake)
+	if (udc->board.vbus_pin > 0 && !udc->board.vbus_polled && wake)
 		enable_irq_wake(udc->board.vbus_pin);
 	return 0;
 }
@@ -1863,15 +1945,20 @@
 static int at91udc_resume(struct platform_device *pdev)
 {
 	struct at91_udc *udc = platform_get_drvdata(pdev);
+	unsigned long	flags;
 
-	if (udc->board.vbus_pin > 0 && udc->active_suspend)
+	if (udc->board.vbus_pin > 0 && !udc->board.vbus_polled &&
+	    udc->active_suspend)
 		disable_irq_wake(udc->board.vbus_pin);
 
 	/* maybe reconnect to host; if so, clocks on */
 	if (udc->active_suspend)
 		disable_irq_wake(udc->udp_irq);
-	else
+	else {
+		spin_lock_irqsave(&udc->lock, flags);
 		pullup(udc, 1);
+		spin_unlock_irqrestore(&udc->lock, flags);
+	}
 	return 0;
 }
 #else
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h
index c65d622..108ca54 100644
--- a/drivers/usb/gadget/at91_udc.h
+++ b/drivers/usb/gadget/at91_udc.h
@@ -144,6 +144,9 @@
 	struct proc_dir_entry		*pde;
 	void __iomem			*udp_baseaddr;
 	int				udp_irq;
+	spinlock_t			lock;
+	struct timer_list		vbus_timer;
+	struct work_struct		vbus_timer_work;
 };
 
 static inline struct at91_udc *to_udc(struct usb_gadget *g)
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 3b1237a..f6fdc20 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -25,7 +25,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/seq_file.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/completion.h>
 #include <linux/debugfs.h>
 #include <linux/jiffies.h>
@@ -525,10 +525,8 @@
  * Called from map_io. We need to call to this early enough so that we
  * can reserve the fixed SDRAM regions before VM could get hold of them.
  */
-void __init omap_vram_reserve_sdram(void)
+void __init omap_vram_reserve_sdram_memblock(void)
 {
-	struct bootmem_data	*bdata;
-	unsigned long		sdram_start, sdram_size;
 	u32 paddr;
 	u32 size = 0;
 
@@ -555,29 +553,28 @@
 
 	size = PAGE_ALIGN(size);
 
-	bdata = NODE_DATA(0)->bdata;
-	sdram_start = bdata->node_min_pfn << PAGE_SHIFT;
-	sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start;
-
 	if (paddr) {
-		if ((paddr & ~PAGE_MASK) || paddr < sdram_start ||
-				paddr + size > sdram_start + sdram_size) {
+		struct memblock_property res;
+
+		res.base = paddr;
+		res.size = size;
+		if ((paddr & ~PAGE_MASK) || memblock_find(&res) ||
+		    res.base != paddr || res.size != size) {
 			pr_err("Illegal SDRAM region for VRAM\n");
 			return;
 		}
 
-		if (reserve_bootmem(paddr, size, BOOTMEM_EXCLUSIVE) < 0) {
-			pr_err("FB: failed to reserve VRAM\n");
-			return;
-		}
-	} else {
-		if (size > sdram_size) {
-			pr_err("Illegal SDRAM size for VRAM\n");
+		if (memblock_is_region_reserved(paddr, size)) {
+			pr_err("FB: failed to reserve VRAM - busy\n");
 			return;
 		}
 
-		paddr = virt_to_phys(alloc_bootmem_pages(size));
-		BUG_ON(paddr & ~PAGE_MASK);
+		if (memblock_reserve(paddr, size) < 0) {
+			pr_err("FB: failed to reserve VRAM - no memory\n");
+			return;
+		}
+	} else {
+		paddr = memblock_alloc_base(size, PAGE_SIZE, MEMBLOCK_REAL_LIMIT);
 	}
 
 	omap_vram_add_region(paddr, size);
diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig
index 04b8280..bc87b9c 100644
--- a/fs/ceph/Kconfig
+++ b/fs/ceph/Kconfig
@@ -2,7 +2,7 @@
         tristate "Ceph distributed file system (EXPERIMENTAL)"
 	depends on INET && EXPERIMENTAL
 	select LIBCRC32C
-	select CONFIG_CRYPTO_AES
+	select CRYPTO_AES
 	help
 	  Choose Y or M here to include support for mounting the
 	  experimental Ceph distributed file system.  Ceph is an extremely
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 74144d6..b81be9a 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -627,7 +627,7 @@
 	if (fmode >= 0)
 		__ceph_get_fmode(ci, fmode);
 	spin_unlock(&inode->i_lock);
-	wake_up(&ci->i_cap_wq);
+	wake_up_all(&ci->i_cap_wq);
 	return 0;
 }
 
@@ -1181,7 +1181,7 @@
 	}
 
 	if (wake)
-		wake_up(&ci->i_cap_wq);
+		wake_up_all(&ci->i_cap_wq);
 
 	return delayed;
 }
@@ -2153,7 +2153,7 @@
 	else if (flushsnaps)
 		ceph_flush_snaps(ci);
 	if (wake)
-		wake_up(&ci->i_cap_wq);
+		wake_up_all(&ci->i_cap_wq);
 	if (put)
 		iput(inode);
 }
@@ -2229,7 +2229,7 @@
 		iput(inode);
 	} else if (complete_capsnap) {
 		ceph_flush_snaps(ci);
-		wake_up(&ci->i_cap_wq);
+		wake_up_all(&ci->i_cap_wq);
 	}
 	if (drop_capsnap)
 		iput(inode);
@@ -2405,7 +2405,7 @@
 	if (queue_invalidate)
 		ceph_queue_invalidate(inode);
 	if (wake)
-		wake_up(&ci->i_cap_wq);
+		wake_up_all(&ci->i_cap_wq);
 
 	if (check_caps == 1)
 		ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY,
@@ -2460,7 +2460,7 @@
 					 struct ceph_inode_info,
 					 i_flushing_item)->vfs_inode);
 		mdsc->num_cap_flushing--;
-		wake_up(&mdsc->cap_flushing_wq);
+		wake_up_all(&mdsc->cap_flushing_wq);
 		dout(" inode %p now !flushing\n", inode);
 
 		if (ci->i_dirty_caps == 0) {
@@ -2472,7 +2472,7 @@
 		}
 	}
 	spin_unlock(&mdsc->cap_dirty_lock);
-	wake_up(&ci->i_cap_wq);
+	wake_up_all(&ci->i_cap_wq);
 
 out:
 	spin_unlock(&inode->i_lock);
@@ -2984,6 +2984,7 @@
 		memcpy(*p, dentry->d_name.name, dentry->d_name.len);
 		*p += dentry->d_name.len;
 		rel->dname_seq = cpu_to_le32(di->lease_seq);
+		__ceph_mdsc_drop_dentry_lease(dentry);
 	}
 	spin_unlock(&dentry->d_lock);
 	return ret;
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index f857193..f94ed3c 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -266,6 +266,7 @@
 	spin_lock(&inode->i_lock);
 	if ((filp->f_pos == 2 || fi->dentry) &&
 	    !ceph_test_opt(client, NOASYNCREADDIR) &&
+	    ceph_snap(inode) != CEPH_SNAPDIR &&
 	    (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
 	    __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
 		err = __dcache_readdir(filp, dirent, filldir);
@@ -1013,18 +1014,22 @@
 
 /*
  * When a dentry is released, clear the dir I_COMPLETE if it was part
- * of the current dir gen.
+ * of the current dir gen or if this is in the snapshot namespace.
  */
 static void ceph_dentry_release(struct dentry *dentry)
 {
 	struct ceph_dentry_info *di = ceph_dentry(dentry);
 	struct inode *parent_inode = dentry->d_parent->d_inode;
+	u64 snapid = ceph_snap(parent_inode);
 
-	if (parent_inode) {
+	dout("dentry_release %p parent %p\n", dentry, parent_inode);
+
+	if (parent_inode && snapid != CEPH_SNAPDIR) {
 		struct ceph_inode_info *ci = ceph_inode(parent_inode);
 
 		spin_lock(&parent_inode->i_lock);
-		if (ci->i_shared_gen == di->lease_shared_gen) {
+		if (ci->i_shared_gen == di->lease_shared_gen ||
+		    snapid <= CEPH_MAXSNAP) {
 			dout(" clearing %p complete (d_release)\n",
 			     parent_inode);
 			ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
@@ -1241,7 +1246,9 @@
 
 struct dentry_operations ceph_snapdir_dentry_ops = {
 	.d_revalidate = ceph_snapdir_d_revalidate,
+	.d_release = ceph_dentry_release,
 };
 
 struct dentry_operations ceph_snap_dentry_ops = {
+	.d_release = ceph_dentry_release,
 };
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 6251a15..7c08698 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -265,7 +265,7 @@
 	kmem_cache_free(ceph_file_cachep, cf);
 
 	/* wake up anyone waiting for caps on this inode */
-	wake_up(&ci->i_cap_wq);
+	wake_up_all(&ci->i_cap_wq);
 	return 0;
 }
 
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 8f9b9fe..389f9db 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -1199,8 +1199,10 @@
 				goto out;
 			}
 			err = ceph_init_dentry(dn);
-			if (err < 0)
+			if (err < 0) {
+				dput(dn);
 				goto out;
+			}
 		} else if (dn->d_inode &&
 			   (ceph_ino(dn->d_inode) != vino.ino ||
 			    ceph_snap(dn->d_inode) != vino.snap)) {
@@ -1499,7 +1501,7 @@
 	if (wrbuffer_refs == 0)
 		ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
 	if (wake)
-		wake_up(&ci->i_cap_wq);
+		wake_up_all(&ci->i_cap_wq);
 }
 
 
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 416c08d..dd440bd 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -868,7 +868,7 @@
 {
 	struct ceph_inode_info *ci = ceph_inode(inode);
 
-	wake_up(&ci->i_cap_wq);
+	wake_up_all(&ci->i_cap_wq);
 	if (arg) {
 		spin_lock(&inode->i_lock);
 		ci->i_wanted_max_size = 0;
@@ -1564,7 +1564,7 @@
 	if (req->r_callback)
 		req->r_callback(mdsc, req);
 	else
-		complete(&req->r_completion);
+		complete_all(&req->r_completion);
 }
 
 /*
@@ -1932,7 +1932,7 @@
 	if (head->safe) {
 		req->r_got_safe = true;
 		__unregister_request(mdsc, req);
-		complete(&req->r_safe_completion);
+		complete_all(&req->r_safe_completion);
 
 		if (req->r_got_unsafe) {
 			/*
@@ -1947,7 +1947,7 @@
 
 			/* last unsafe request during umount? */
 			if (mdsc->stopping && !__get_oldest_req(mdsc))
-				complete(&mdsc->safe_umount_waiters);
+				complete_all(&mdsc->safe_umount_waiters);
 			mutex_unlock(&mdsc->mutex);
 			goto out;
 		}
@@ -2126,7 +2126,7 @@
 			pr_info("mds%d reconnect denied\n", session->s_mds);
 		remove_session_caps(session);
 		wake = 1; /* for good measure */
-		complete(&mdsc->session_close_waiters);
+		complete_all(&mdsc->session_close_waiters);
 		kick_requests(mdsc, mds);
 		break;
 
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c
index cc115ea..54fe01c 100644
--- a/fs/ceph/mon_client.c
+++ b/fs/ceph/mon_client.c
@@ -345,7 +345,7 @@
 
 out:
 	mutex_unlock(&monc->mutex);
-	wake_up(&client->auth_wq);
+	wake_up_all(&client->auth_wq);
 }
 
 /*
@@ -462,7 +462,7 @@
 	}
 	mutex_unlock(&monc->mutex);
 	if (req) {
-		complete(&req->completion);
+		complete_all(&req->completion);
 		put_generic_request(req);
 	}
 	return;
@@ -718,7 +718,7 @@
 				     monc->m_auth->front_max);
 	if (ret < 0) {
 		monc->client->auth_err = ret;
-		wake_up(&monc->client->auth_wq);
+		wake_up_all(&monc->client->auth_wq);
 	} else if (ret > 0) {
 		__send_prepared_auth_request(monc, ret);
 	} else if (!was_auth && monc->auth->ops->is_authenticated(monc->auth)) {
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c
index 92b7251..e385223 100644
--- a/fs/ceph/osd_client.c
+++ b/fs/ceph/osd_client.c
@@ -862,12 +862,12 @@
 	if (req->r_callback)
 		req->r_callback(req, msg);
 	else
-		complete(&req->r_completion);
+		complete_all(&req->r_completion);
 
 	if (flags & CEPH_OSD_FLAG_ONDISK) {
 		if (req->r_safe_callback)
 			req->r_safe_callback(req, msg);
-		complete(&req->r_safe_completion);  /* fsync waiter */
+		complete_all(&req->r_safe_completion);  /* fsync waiter */
 	}
 
 done:
@@ -1083,7 +1083,7 @@
 	if (newmap)
 		kick_requests(osdc, NULL);
 	up_read(&osdc->map_sem);
-	wake_up(&osdc->client->auth_wq);
+	wake_up_all(&osdc->client->auth_wq);
 	return;
 
 bad:
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c
index 277f8b3..416d46a 100644
--- a/fs/ceph/osdmap.c
+++ b/fs/ceph/osdmap.c
@@ -831,12 +831,13 @@
 		/* remove any? */
 		while (rbp && pgid_cmp(rb_entry(rbp, struct ceph_pg_mapping,
 						node)->pgid, pgid) <= 0) {
-			struct rb_node *cur = rbp;
+			struct ceph_pg_mapping *cur =
+				rb_entry(rbp, struct ceph_pg_mapping, node);
+			
 			rbp = rb_next(rbp);
-			dout(" removed pg_temp %llx\n",
-			     *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
-					       node)->pgid);
-			rb_erase(cur, &map->pg_temp);
+			dout(" removed pg_temp %llx\n", *(u64 *)&cur->pgid);
+			rb_erase(&cur->node, &map->pg_temp);
+			kfree(cur);
 		}
 
 		if (pglen) {
@@ -852,19 +853,22 @@
 			for (j = 0; j < pglen; j++)
 				pg->osds[j] = ceph_decode_32(p);
 			err = __insert_pg_mapping(pg, &map->pg_temp);
-			if (err)
+			if (err) {
+				kfree(pg);
 				goto bad;
+			}
 			dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid,
 			     pglen);
 		}
 	}
 	while (rbp) {
-		struct rb_node *cur = rbp;
+		struct ceph_pg_mapping *cur =
+			rb_entry(rbp, struct ceph_pg_mapping, node);
+
 		rbp = rb_next(rbp);
-		dout(" removed pg_temp %llx\n",
-		     *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
-				       node)->pgid);
-		rb_erase(cur, &map->pg_temp);
+		dout(" removed pg_temp %llx\n", *(u64 *)&cur->pgid);
+		rb_erase(&cur->node, &map->pg_temp);
+		kfree(cur);
 	}
 
 	/* ignore the rest */
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index 2d8dbce..46c4dd8 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -31,9 +31,9 @@
 
 static struct hlist_head *ecryptfs_daemon_hash;
 struct mutex ecryptfs_daemon_hash_mux;
-static int ecryptfs_hash_buckets;
+static int ecryptfs_hash_bits;
 #define ecryptfs_uid_hash(uid) \
-        hash_long((unsigned long)uid, ecryptfs_hash_buckets)
+        hash_long((unsigned long)uid, ecryptfs_hash_bits)
 
 static u32 ecryptfs_msg_counter;
 static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr;
@@ -486,18 +486,19 @@
 	}
 	mutex_init(&ecryptfs_daemon_hash_mux);
 	mutex_lock(&ecryptfs_daemon_hash_mux);
-	ecryptfs_hash_buckets = 1;
-	while (ecryptfs_number_of_users >> ecryptfs_hash_buckets)
-		ecryptfs_hash_buckets++;
+	ecryptfs_hash_bits = 1;
+	while (ecryptfs_number_of_users >> ecryptfs_hash_bits)
+		ecryptfs_hash_bits++;
 	ecryptfs_daemon_hash = kmalloc((sizeof(struct hlist_head)
-					* ecryptfs_hash_buckets), GFP_KERNEL);
+					* (1 << ecryptfs_hash_bits)),
+				       GFP_KERNEL);
 	if (!ecryptfs_daemon_hash) {
 		rc = -ENOMEM;
 		printk(KERN_ERR "%s: Failed to allocate memory\n", __func__);
 		mutex_unlock(&ecryptfs_daemon_hash_mux);
 		goto out;
 	}
-	for (i = 0; i < ecryptfs_hash_buckets; i++)
+	for (i = 0; i < (1 << ecryptfs_hash_bits); i++)
 		INIT_HLIST_HEAD(&ecryptfs_daemon_hash[i]);
 	mutex_unlock(&ecryptfs_daemon_hash_mux);
 	ecryptfs_msg_ctx_arr = kmalloc((sizeof(struct ecryptfs_msg_ctx)
@@ -554,7 +555,7 @@
 		int i;
 
 		mutex_lock(&ecryptfs_daemon_hash_mux);
-		for (i = 0; i < ecryptfs_hash_buckets; i++) {
+		for (i = 0; i < (1 << ecryptfs_hash_bits); i++) {
 			int rc;
 
 			hlist_for_each_entry(daemon, elem,
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 26ca336..6b48d7c 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1231,6 +1231,25 @@
 	return 0;
 }
 
+static void *gfs2_alloc_sort_buffer(unsigned size)
+{
+	void *ptr = NULL;
+
+	if (size < KMALLOC_MAX_SIZE)
+		ptr = kmalloc(size, GFP_NOFS | __GFP_NOWARN);
+	if (!ptr)
+		ptr = __vmalloc(size, GFP_NOFS, PAGE_KERNEL);
+	return ptr;
+}
+
+static void gfs2_free_sort_buffer(void *ptr)
+{
+	if (is_vmalloc_addr(ptr))
+		vfree(ptr);
+	else
+		kfree(ptr);
+}
+
 static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
 			      filldir_t filldir, int *copied, unsigned *depth,
 			      u64 leaf_no)
@@ -1271,7 +1290,7 @@
 	 * 99 is the maximum number of entries that can fit in a single
 	 * leaf block.
 	 */
-	larr = vmalloc((leaves + entries + 99) * sizeof(void *));
+	larr = gfs2_alloc_sort_buffer((leaves + entries + 99) * sizeof(void *));
 	if (!larr)
 		goto out;
 	darr = (const struct gfs2_dirent **)(larr + leaves);
@@ -1282,7 +1301,7 @@
 	do {
 		error = get_leaf(ip, lfn, &bh);
 		if (error)
-			goto out_kfree;
+			goto out_free;
 		lf = (struct gfs2_leaf *)bh->b_data;
 		lfn = be64_to_cpu(lf->lf_next);
 		if (lf->lf_entries) {
@@ -1291,7 +1310,7 @@
 						gfs2_dirent_gather, NULL, &g);
 			error = PTR_ERR(dent);
 			if (IS_ERR(dent))
-				goto out_kfree;
+				goto out_free;
 			if (entries2 != g.offset) {
 				fs_warn(sdp, "Number of entries corrupt in dir "
 						"leaf %llu, entries2 (%u) != "
@@ -1300,7 +1319,7 @@
 					entries2, g.offset);
 					
 				error = -EIO;
-				goto out_kfree;
+				goto out_free;
 			}
 			error = 0;
 			larr[leaf++] = bh;
@@ -1312,10 +1331,10 @@
 	BUG_ON(entries2 != entries);
 	error = do_filldir_main(ip, offset, opaque, filldir, darr,
 				entries, copied);
-out_kfree:
+out_free:
 	for(i = 0; i < leaf; i++)
 		brelse(larr[i]);
-	vfree(larr);
+	gfs2_free_sort_buffer(larr);
 out:
 	return error;
 }
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index 8b10386..b0c1740 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -14,14 +14,19 @@
 #ifndef ASMARM_AMBA_H
 #define ASMARM_AMBA_H
 
+#include <linux/clk.h>
 #include <linux/device.h>
+#include <linux/err.h>
 #include <linux/resource.h>
 
 #define AMBA_NR_IRQS	2
 
+struct clk;
+
 struct amba_device {
 	struct device		dev;
 	struct resource		res;
+	struct clk		*pclk;
 	u64			dma_mask;
 	unsigned int		periphid;
 	unsigned int		irq[AMBA_NR_IRQS];
@@ -59,6 +64,12 @@
 int amba_request_regions(struct amba_device *, const char *);
 void amba_release_regions(struct amba_device *);
 
+#define amba_pclk_enable(d)	\
+	(IS_ERR((d)->pclk) ? 0 : clk_enable((d)->pclk))
+
+#define amba_pclk_disable(d)	\
+	do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0)
+
 #define amba_config(d)	(((d)->periphid >> 24) & 0xff)
 #define amba_rev(d)	(((d)->periphid >> 20) & 0x0f)
 #define amba_manf(d)	(((d)->periphid >> 12) & 0xff)
diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h
index 7e466fe..ca84ce7 100644
--- a/include/linux/amba/mmci.h
+++ b/include/linux/amba/mmci.h
@@ -15,9 +15,10 @@
  * @ocr_mask: available voltages on the 4 pins from the block, this
  * is ignored if a regulator is used, see the MMC_VDD_* masks in
  * mmc/host.h
- * @translate_vdd: a callback function to translate a MMC_VDD_*
- * mask into a value to be binary or:ed and written into the
- * MMCIPWR register of the block
+ * @vdd_handler: a callback function to translate a MMC_VDD_*
+ * mask into a value to be binary (or set some other custom bits
+ * in MMCIPWR) or:ed and written into the MMCIPWR register of the
+ * block.  May also control external power based on the power_mode.
  * @status: if no GPIO read function was given to the block in
  * gpio_wp (below) this function will be called to determine
  * whether a card is present in the MMC slot or not
@@ -29,7 +30,8 @@
 struct mmci_platform_data {
 	unsigned int f_max;
 	unsigned int ocr_mask;
-	u32 (*translate_vdd)(struct device *, unsigned int);
+	u32 (*vdd_handler)(struct device *, unsigned int vdd,
+			   unsigned char power_mode);
 	unsigned int (*status)(struct device *);
 	int	gpio_wp;
 	int	gpio_cd;
diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h
index 5a5a7fd..e1b634b 100644
--- a/include/linux/amba/serial.h
+++ b/include/linux/amba/serial.h
@@ -38,10 +38,12 @@
 #define UART01x_FR		0x18	/* Flag register (Read only). */
 #define UART010_IIR		0x1C	/* Interrupt indentification register (Read). */
 #define UART010_ICR		0x1C	/* Interrupt clear register (Write). */
+#define ST_UART011_LCRH_RX	0x1C    /* Rx line control register. */
 #define UART01x_ILPR		0x20	/* IrDA low power counter register. */
 #define UART011_IBRD		0x24	/* Integer baud rate divisor register. */
 #define UART011_FBRD		0x28	/* Fractional baud rate divisor register. */
 #define UART011_LCRH		0x2c	/* Line control register. */
+#define ST_UART011_LCRH_TX	0x2c    /* Tx Line control register. */
 #define UART011_CR		0x30	/* Control register. */
 #define UART011_IFLS		0x34	/* Interrupt fifo level select. */
 #define UART011_IMSC		0x38	/* Interrupt mask. */
@@ -84,6 +86,7 @@
 #define UART010_CR_TIE 		0x0020
 #define UART010_CR_RIE 		0x0010
 #define UART010_CR_MSIE		0x0008
+#define ST_UART011_CR_OVSFACT	0x0008	/* Oversampling factor */
 #define UART01x_CR_IIRLP	0x0004	/* SIR low power mode */
 #define UART01x_CR_SIREN	0x0002	/* SIR enable */
 #define UART01x_CR_UARTEN	0x0001	/* UART enable */
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index 9bdd914..7e4cd61 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -253,7 +253,7 @@
 /* in arch/arm/plat-omap/fb.c */
 extern void omapfb_set_platform_data(struct omapfb_platform_data *data);
 extern void omapfb_set_ctrl_platform_data(void *pdata);
-extern void omapfb_reserve_sdram(void);
+extern void omapfb_reserve_sdram_memblock(void);
 
 #endif
 
diff --git a/include/linux/regulator/tps6507x.h b/include/linux/regulator/tps6507x.h
new file mode 100644
index 0000000..4892f59
--- /dev/null
+++ b/include/linux/regulator/tps6507x.h
@@ -0,0 +1,32 @@
+/*
+ * tps6507x.h  --  Voltage regulation for the Texas Instruments TPS6507X
+ *
+ * Copyright (C) 2010 Texas Instruments, 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.
+ *
+ * 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
+ */
+
+#ifndef REGULATOR_TPS6507X
+#define REGULATOR_TPS6507X
+
+/**
+ * tps6507x_reg_platform_data - platform data for tps6507x
+ * @defdcdc_default: Defines whether DCDC high or the low register controls
+ *	output voltage by default. Valid for DCDC2 and DCDC3 outputs only.
+ */
+struct tps6507x_reg_platform_data {
+	bool defdcdc_default;
+};
+
+#endif
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c
index 250ed11..44524cc 100644
--- a/lib/atomic64_test.c
+++ b/lib/atomic64_test.c
@@ -114,7 +114,7 @@
 	BUG_ON(v.counter != r);
 
 #if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || \
-    defined(CONFIG_S390) || defined(_ASM_GENERIC_ATOMIC64_H)
+    defined(CONFIG_S390) || defined(_ASM_GENERIC_ATOMIC64_H) || defined(CONFIG_ARM)
 	INIT(onestwos);
 	BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1));
 	r -= one;
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
new file mode 100644
index 0000000..15130b50
--- /dev/null
+++ b/tools/perf/arch/arm/Makefile
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
diff --git a/tools/perf/arch/arm/util/dwarf-regs.c b/tools/perf/arch/arm/util/dwarf-regs.c
new file mode 100644
index 0000000..fff6450
--- /dev/null
+++ b/tools/perf/arch/arm/util/dwarf-regs.c
@@ -0,0 +1,64 @@
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2010 Will Deacon, ARM 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.
+ */
+
+#include <libio.h>
+#include <dwarf-regs.h>
+
+struct pt_regs_dwarfnum {
+	const char *name;
+	unsigned int dwarfnum;
+};
+
+#define STR(s) #s
+#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
+#define GPR_DWARFNUM_NAME(num) \
+	{.name = STR(%r##num), .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
+
+/*
+ * Reference:
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040a/IHI0040A_aadwarf.pdf
+ */
+static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
+	GPR_DWARFNUM_NAME(0),
+	GPR_DWARFNUM_NAME(1),
+	GPR_DWARFNUM_NAME(2),
+	GPR_DWARFNUM_NAME(3),
+	GPR_DWARFNUM_NAME(4),
+	GPR_DWARFNUM_NAME(5),
+	GPR_DWARFNUM_NAME(6),
+	GPR_DWARFNUM_NAME(7),
+	GPR_DWARFNUM_NAME(8),
+	GPR_DWARFNUM_NAME(9),
+	GPR_DWARFNUM_NAME(10),
+	REG_DWARFNUM_NAME("%fp", 11),
+	REG_DWARFNUM_NAME("%ip", 12),
+	REG_DWARFNUM_NAME("%sp", 13),
+	REG_DWARFNUM_NAME("%lr", 14),
+	REG_DWARFNUM_NAME("%pc", 15),
+	REG_DWARFNUM_END,
+};
+
+/**
+ * get_arch_regstr() - lookup register name from it's DWARF register number
+ * @n:	the DWARF register number
+ *
+ * get_arch_regstr() returns the name of the register in struct
+ * regdwarfnum_table from it's DWARF register number. If the register is not
+ * found in the table, this returns NULL;
+ */
+const char *get_arch_regstr(unsigned int n)
+{
+	const struct pt_regs_dwarfnum *roff;
+	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
+		if (roff->dwarfnum == n)
+			return roff->name;
+	return NULL;
+}