summary refs log tree commit diff
path: root/arch/arm/mach-spear
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2013-04-19 22:30:31 +0200
committerArnd Bergmann <arnd@arndb.de>2013-04-19 22:50:01 +0200
commit1b361942b53c33f38d55065c13785aadb5103a18 (patch)
tree07b26d32b175f27f18f1fca3d5944a58f89cd17f /arch/arm/mach-spear
parent61b464aef0e306f141dbc0bb3f9c58049a987a7e (diff)
parentbcf3e72eff584136600a51a5b30ef7a794664d19 (diff)
downloadlinux-1b361942b53c33f38d55065c13785aadb5103a18.tar.gz
Merge branch 'spear/multiplatform' into late/cleanup
This is a prerequisite for the spear/dwdma series.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-spear')
-rw-r--r--arch/arm/mach-spear/Kconfig103
-rw-r--r--arch/arm/mach-spear/Makefile24
-rw-r--r--arch/arm/mach-spear/Makefile.boot3
-rw-r--r--arch/arm/mach-spear/generic.h59
-rw-r--r--arch/arm/mach-spear/headsmp.S47
-rw-r--r--arch/arm/mach-spear/hotplug.c103
-rw-r--r--arch/arm/mach-spear/include/mach/debug-macro.S36
-rw-r--r--arch/arm/mach-spear/include/mach/irqs.h35
-rw-r--r--arch/arm/mach-spear/include/mach/misc_regs.h22
-rw-r--r--arch/arm/mach-spear/include/mach/spear.h95
-rw-r--r--arch/arm/mach-spear/include/mach/timex.h19
-rw-r--r--arch/arm/mach-spear/include/mach/uncompress.h42
-rw-r--r--arch/arm/mach-spear/pl080.c78
-rw-r--r--arch/arm/mach-spear/pl080.h21
-rw-r--r--arch/arm/mach-spear/platsmp.c130
-rw-r--r--arch/arm/mach-spear/restart.c34
-rw-r--r--arch/arm/mach-spear/spear1310.c96
-rw-r--r--arch/arm/mach-spear/spear1340.c193
-rw-r--r--arch/arm/mach-spear/spear13xx-dma.h128
-rw-r--r--arch/arm/mach-spear/spear13xx.c184
-rw-r--r--arch/arm/mach-spear/spear300.c220
-rw-r--r--arch/arm/mach-spear/spear310.c262
-rw-r--r--arch/arm/mach-spear/spear320.c277
-rw-r--r--arch/arm/mach-spear/spear3xx.c116
-rw-r--r--arch/arm/mach-spear/spear6xx.c431
-rw-r--r--arch/arm/mach-spear/time.c245
26 files changed, 3003 insertions, 0 deletions
diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig
new file mode 100644
index 000000000000..5412aeb377ac
--- /dev/null
+++ b/arch/arm/mach-spear/Kconfig
@@ -0,0 +1,103 @@
+#
+# SPEAr Platform configuration file
+#
+
+menuconfig PLAT_SPEAR
+	bool "ST SPEAr Family" if ARCH_MULTI_V7 || ARCH_MULTI_V5
+	default PLAT_SPEAR_SINGLE
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
+	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
+	select COMMON_CLK
+	select GENERIC_CLOCKEVENTS
+	select HAVE_CLK
+
+if PLAT_SPEAR
+
+config ARCH_SPEAR13XX
+	bool "ST SPEAr13xx"
+	depends on ARCH_MULTI_V7 || PLAT_SPEAR_SINGLE
+	select ARCH_HAS_CPUFREQ
+	select ARM_GIC
+	select CPU_V7
+	select GPIO_SPEAR_SPICS
+	select HAVE_SMP
+	select MIGHT_HAVE_CACHE_L2X0
+	select PINCTRL
+	select USE_OF
+	help
+	  Supports for ARM's SPEAR13XX family
+
+if ARCH_SPEAR13XX
+
+config MACH_SPEAR1310
+	bool "SPEAr1310 Machine support with Device Tree"
+	select PINCTRL_SPEAR1310
+	help
+	  Supports ST SPEAr1310 machine configured via the device-tree
+
+config MACH_SPEAR1340
+	bool "SPEAr1340 Machine support with Device Tree"
+	select PINCTRL_SPEAR1340
+	help
+	  Supports ST SPEAr1340 machine configured via the device-tree
+
+endif #ARCH_SPEAR13XX
+
+config ARCH_SPEAR3XX
+	bool "ST SPEAr3xx"
+	depends on ARCH_MULTI_V5 || PLAT_SPEAR_SINGLE
+	depends on !ARCH_SPEAR13XX
+	select ARM_VIC
+	select CPU_ARM926T
+	select PINCTRL
+	select USE_OF
+	help
+	  Supports for ARM's SPEAR3XX family
+
+if ARCH_SPEAR3XX
+
+config MACH_SPEAR300
+	bool "SPEAr300 Machine support with Device Tree"
+	select PINCTRL_SPEAR300
+	help
+	  Supports ST SPEAr300 machine configured via the device-tree
+
+config MACH_SPEAR310
+	bool "SPEAr310 Machine support with Device Tree"
+	select PINCTRL_SPEAR310
+	help
+	  Supports ST SPEAr310 machine configured via the device-tree
+
+config MACH_SPEAR320
+	bool "SPEAr320 Machine support with Device Tree"
+	select PINCTRL_SPEAR320
+	help
+	  Supports ST SPEAr320 machine configured via the device-tree
+
+endif
+
+config ARCH_SPEAR6XX
+	bool "ST SPEAr6XX"
+	depends on ARCH_MULTI_V5 || PLAT_SPEAR_SINGLE
+	depends on !ARCH_SPEAR13XX
+	select ARM_VIC
+	select CPU_ARM926T
+	help
+	  Supports for ARM's SPEAR6XX family
+
+config MACH_SPEAR600
+	def_bool y
+	depends on ARCH_SPEAR6XX
+	select USE_OF
+	help
+	  Supports ST SPEAr600 boards configured via the device-treesource "arch/arm/mach-spear6xx/Kconfig"
+
+config ARCH_SPEAR_AUTO
+	def_bool PLAT_SPEAR_SINGLE
+	depends on !ARCH_SPEAR13XX && !ARCH_SPEAR6XX
+	select ARCH_SPEAR3XX
+
+endif
+
diff --git a/arch/arm/mach-spear/Makefile b/arch/arm/mach-spear/Makefile
new file mode 100644
index 000000000000..dc9ce80508ad
--- /dev/null
+++ b/arch/arm/mach-spear/Makefile
@@ -0,0 +1,24 @@
+#
+# SPEAr Platform specific Makefile
+#
+
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
+
+# Common support
+obj-y	:= restart.o time.o
+
+obj-$(CONFIG_SMP)		+= headsmp.o platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
+
+obj-$(CONFIG_ARCH_SPEAR13XX)	+= spear13xx.o
+obj-$(CONFIG_MACH_SPEAR1310)	+= spear1310.o
+obj-$(CONFIG_MACH_SPEAR1340)	+= spear1340.o
+
+obj-$(CONFIG_ARCH_SPEAR3XX)	+= spear3xx.o
+obj-$(CONFIG_ARCH_SPEAR3XX)	+= pl080.o
+obj-$(CONFIG_MACH_SPEAR300)	+= spear300.o
+obj-$(CONFIG_MACH_SPEAR310)	+= spear310.o
+obj-$(CONFIG_MACH_SPEAR320)	+= spear320.o
+
+obj-$(CONFIG_ARCH_SPEAR6XX)	+= spear6xx.o
+obj-$(CONFIG_ARCH_SPEAR6XX)	+= pl080.o
diff --git a/arch/arm/mach-spear/Makefile.boot b/arch/arm/mach-spear/Makefile.boot
new file mode 100644
index 000000000000..4674a4c221db
--- /dev/null
+++ b/arch/arm/mach-spear/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y	+= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
diff --git a/arch/arm/mach-spear/generic.h b/arch/arm/mach-spear/generic.h
new file mode 100644
index 000000000000..8ba7e75b648d
--- /dev/null
+++ b/arch/arm/mach-spear/generic.h
@@ -0,0 +1,59 @@
+/*
+ * spear machine family generic header file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Rajeev Kumar <rajeev-dlh.kumar@st.com>
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <linux/dmaengine.h>
+#include <linux/amba/pl08x.h>
+#include <linux/init.h>
+#include <asm/mach/time.h>
+
+extern void spear13xx_timer_init(void);
+extern void spear3xx_timer_init(void);
+extern struct pl022_ssp_controller pl022_plat_data;
+extern struct pl08x_platform_data pl080_plat_data;
+extern struct dw_dma_platform_data dmac_plat_data;
+extern struct dw_dma_slave cf_dma_priv;
+extern struct dw_dma_slave nand_read_dma_priv;
+extern struct dw_dma_slave nand_write_dma_priv;
+bool dw_dma_filter(struct dma_chan *chan, void *slave);
+
+void __init spear_setup_of_timer(void);
+void __init spear3xx_clk_init(void __iomem *misc_base,
+			      void __iomem *soc_config_base);
+void __init spear3xx_map_io(void);
+void __init spear3xx_dt_init_irq(void);
+void __init spear6xx_clk_init(void __iomem *misc_base);
+void __init spear13xx_map_io(void);
+void __init spear13xx_l2x0_init(void);
+
+void spear_restart(char, const char *);
+
+void spear13xx_secondary_startup(void);
+void __cpuinit spear13xx_cpu_die(unsigned int cpu);
+
+extern struct smp_operations spear13xx_smp_ops;
+
+#ifdef CONFIG_MACH_SPEAR1310
+void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base);
+#else
+static inline void spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) {}
+#endif
+
+#ifdef CONFIG_MACH_SPEAR1340
+void __init spear1340_clk_init(void __iomem *misc_base);
+#else
+static inline void spear1340_clk_init(void __iomem *misc_base) {}
+#endif
+
+#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear/headsmp.S b/arch/arm/mach-spear/headsmp.S
new file mode 100644
index 000000000000..ed85473a047f
--- /dev/null
+++ b/arch/arm/mach-spear/headsmp.S
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-spear13XX/headsmp.S
+ *
+ * Picked from realview
+ * Copyright (c) 2012 ST Microelectronics Limited
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+	__INIT
+
+/*
+ * spear13xx specific entry point for secondary CPUs. This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(spear13xx_secondary_startup)
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, r0, #15
+	adr	r4, 1f
+	ldmia	r4, {r5, r6}
+	sub	r4, r4, r5
+	add	r6, r6, r4
+pen:	ldr	r7, [r6]
+	cmp	r7, r0
+	bne	pen
+
+	/* re-enable coherency */
+	mrc	p15, 0, r0, c1, c0, 1
+	orr	r0, r0, #(1 << 6) | (1 << 0)
+	mcr	p15, 0, r0, c1, c0, 1
+	/*
+	 * we've been released from the holding pen: secondary_stack
+	 * should now contain the SVC stack for this core
+	 */
+	b	secondary_startup
+
+	.align
+1:	.long	.
+	.long	pen_release
+ENDPROC(spear13xx_secondary_startup)
diff --git a/arch/arm/mach-spear/hotplug.c b/arch/arm/mach-spear/hotplug.c
new file mode 100644
index 000000000000..a7d2dd11a4f2
--- /dev/null
+++ b/arch/arm/mach-spear/hotplug.c
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/arm/mach-spear13xx/hotplug.c
+ *
+ * Copyright (C) 2012 ST Microelectronics Ltd.
+ * Deepak Sikri <deepak.sikri@st.com>
+ *
+ * based upon linux/arch/arm/mach-realview/hotplug.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/smp_plat.h>
+
+static inline void cpu_enter_lowpower(void)
+{
+	unsigned int v;
+
+	flush_cache_all();
+	asm volatile(
+	"	mcr	p15, 0, %1, c7, c5, 0\n"
+	"	dsb\n"
+	/*
+	 * Turn off coherency
+	 */
+	"	mrc	p15, 0, %0, c1, c0, 1\n"
+	"	bic	%0, %0, #0x20\n"
+	"	mcr	p15, 0, %0, c1, c0, 1\n"
+	"	mrc	p15, 0, %0, c1, c0, 0\n"
+	"	bic	%0, %0, %2\n"
+	"	mcr	p15, 0, %0, c1, c0, 0\n"
+	: "=&r" (v)
+	: "r" (0), "Ir" (CR_C)
+	: "cc", "memory");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+	unsigned int v;
+
+	asm volatile("mrc	p15, 0, %0, c1, c0, 0\n"
+	"	orr	%0, %0, %1\n"
+	"	mcr	p15, 0, %0, c1, c0, 0\n"
+	"	mrc	p15, 0, %0, c1, c0, 1\n"
+	"	orr	%0, %0, #0x20\n"
+	"	mcr	p15, 0, %0, c1, c0, 1\n"
+	: "=&r" (v)
+	: "Ir" (CR_C)
+	: "cc");
+}
+
+static inline void spear13xx_do_lowpower(unsigned int cpu, int *spurious)
+{
+	for (;;) {
+		wfi();
+
+		if (pen_release == cpu) {
+			/*
+			 * OK, proper wakeup, we're done
+			 */
+			break;
+		}
+
+		/*
+		 * Getting here, means that we have come out of WFI without
+		 * having been woken up - this shouldn't happen
+		 *
+		 * Just note it happening - when we're woken, we can report
+		 * its occurrence.
+		 */
+		(*spurious)++;
+	}
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __ref spear13xx_cpu_die(unsigned int cpu)
+{
+	int spurious = 0;
+
+	/*
+	 * we're ready for shutdown now, so do it
+	 */
+	cpu_enter_lowpower();
+	spear13xx_do_lowpower(cpu, &spurious);
+
+	/*
+	 * bring this CPU back into the world of cache
+	 * coherency, and then restore interrupts
+	 */
+	cpu_leave_lowpower();
+
+	if (spurious)
+		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
diff --git a/arch/arm/mach-spear/include/mach/debug-macro.S b/arch/arm/mach-spear/include/mach/debug-macro.S
new file mode 100644
index 000000000000..75b05ad0fbad
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/debug-macro.S
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/plat-spear/include/plat/debug-macro.S
+ *
+ * Debugging macro include header for spear platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/amba/serial.h>
+#include <mach/spear.h>
+
+		.macro	addruart, rp, rv, tmp
+		mov	\rp, #SPEAR_DBG_UART_BASE		@ Physical base
+		mov	\rv, #VA_SPEAR_DBG_UART_BASE		@ Virtual base
+		.endm
+
+		.macro	senduart, rd, rx
+		strb	\rd, [\rx, #UART01x_DR]			@ ASC_TX_BUFFER
+		.endm
+
+		.macro	waituart, rd, rx
+1001:		ldr	\rd, [\rx, #UART01x_FR]			@ FLAG REGISTER
+		tst	\rd, #UART01x_FR_TXFF			@ TX_FULL
+		bne	1001b
+		.endm
+
+		.macro	busyuart, rd, rx
+1002:		ldr	\rd, [\rx, #UART01x_FR]			@ FLAG REGISTER
+		tst	\rd, #UART011_FR_TXFE			@ TX_EMPTY
+		beq	1002b
+		.endm
diff --git a/arch/arm/mach-spear/include/mach/irqs.h b/arch/arm/mach-spear/include/mach/irqs.h
new file mode 100644
index 000000000000..92da0a8c6bce
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/irqs.h
@@ -0,0 +1,35 @@
+/*
+ * IRQ helper macros for spear machine family
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Rajeev Kumar <rajeev-dlh.kumar@st.com>
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+#ifdef CONFIG_ARCH_SPEAR3XX
+#define NR_IRQS			256
+#endif
+
+#ifdef CONFIG_ARCH_SPEAR6XX
+/* IRQ definitions */
+/* VIC 1 */
+#define IRQ_VIC_END				64
+
+/* GPIO pins virtual irqs */
+#define VIRTUAL_IRQS				24
+#define NR_IRQS					(IRQ_VIC_END + VIRTUAL_IRQS)
+#endif
+
+#ifdef CONFIG_ARCH_SPEAR13XX
+#define IRQ_GIC_END			160
+#define NR_IRQS				IRQ_GIC_END
+#endif
+
+#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear/include/mach/misc_regs.h b/arch/arm/mach-spear/include/mach/misc_regs.h
new file mode 100644
index 000000000000..935639ce59ba
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/misc_regs.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/misc_regs.h
+ *
+ * Miscellaneous registers definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MISC_REGS_H
+#define __MACH_MISC_REGS_H
+
+#include <mach/spear.h>
+
+#define MISC_BASE		(VA_SPEAR_ICM3_MISC_REG_BASE)
+#define DMA_CHN_CFG		(MISC_BASE + 0x0A0)
+
+#endif /* __MACH_MISC_REGS_H */
diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h
new file mode 100644
index 000000000000..374ddc393df1
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/spear.h
@@ -0,0 +1,95 @@
+/*
+ * SPEAr3xx/6xx Machine family specific definition
+ *
+ * Copyright (C) 2009,2012 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPEAR_H
+#define __MACH_SPEAR_H
+
+#include <asm/memory.h>
+
+#if defined(CONFIG_ARCH_SPEAR3XX) || defined (CONFIG_ARCH_SPEAR6XX)
+
+/* ICM1 - Low speed connection */
+#define SPEAR_ICM1_2_BASE		UL(0xD0000000)
+#define VA_SPEAR_ICM1_2_BASE		IOMEM(0xFD000000)
+#define SPEAR_ICM1_UART_BASE		UL(0xD0000000)
+#define VA_SPEAR_ICM1_UART_BASE		(VA_SPEAR_ICM1_2_BASE - SPEAR_ICM1_2_BASE + SPEAR_ICM1_UART_BASE)
+#define SPEAR3XX_ICM1_SSP_BASE		UL(0xD0100000)
+
+/* ML-1, 2 - Multi Layer CPU Subsystem */
+#define SPEAR_ICM3_ML1_2_BASE		UL(0xF0000000)
+#define VA_SPEAR6XX_ML_CPU_BASE		IOMEM(0xF0000000)
+
+/* ICM3 - Basic Subsystem */
+#define SPEAR_ICM3_SMI_CTRL_BASE	UL(0xFC000000)
+#define VA_SPEAR_ICM3_SMI_CTRL_BASE	IOMEM(0xFC000000)
+#define SPEAR_ICM3_DMA_BASE		UL(0xFC400000)
+#define SPEAR_ICM3_SYS_CTRL_BASE	UL(0xFCA00000)
+#define VA_SPEAR_ICM3_SYS_CTRL_BASE	(VA_SPEAR_ICM3_SMI_CTRL_BASE - SPEAR_ICM3_SMI_CTRL_BASE + SPEAR_ICM3_SYS_CTRL_BASE)
+#define SPEAR_ICM3_MISC_REG_BASE	UL(0xFCA80000)
+#define VA_SPEAR_ICM3_MISC_REG_BASE	(VA_SPEAR_ICM3_SMI_CTRL_BASE - SPEAR_ICM3_SMI_CTRL_BASE + SPEAR_ICM3_MISC_REG_BASE)
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE		SPEAR_ICM1_UART_BASE
+#define VA_SPEAR_DBG_UART_BASE		VA_SPEAR_ICM1_UART_BASE
+
+/* Sysctl base for spear platform */
+#define SPEAR_SYS_CTRL_BASE		SPEAR_ICM3_SYS_CTRL_BASE
+#define VA_SPEAR_SYS_CTRL_BASE		VA_SPEAR_ICM3_SYS_CTRL_BASE
+#endif /* SPEAR3xx || SPEAR6XX */
+
+/* SPEAr320 Macros */
+#define SPEAR320_SOC_CONFIG_BASE	UL(0xB3000000)
+#define VA_SPEAR320_SOC_CONFIG_BASE	IOMEM(0xFE000000)
+
+#ifdef CONFIG_ARCH_SPEAR13XX
+
+#define PERIP_GRP2_BASE				UL(0xB3000000)
+#define VA_PERIP_GRP2_BASE			IOMEM(0xFE000000)
+#define MCIF_SDHCI_BASE				UL(0xB3000000)
+#define SYSRAM0_BASE				UL(0xB3800000)
+#define VA_SYSRAM0_BASE				IOMEM(0xFE800000)
+#define SYS_LOCATION				(VA_SYSRAM0_BASE + 0x600)
+
+#define PERIP_GRP1_BASE				UL(0xE0000000)
+#define VA_PERIP_GRP1_BASE			IOMEM(0xFD000000)
+#define UART_BASE				UL(0xE0000000)
+#define VA_UART_BASE				IOMEM(0xFD000000)
+#define SSP_BASE				UL(0xE0100000)
+#define MISC_BASE				UL(0xE0700000)
+#define VA_MISC_BASE				IOMEM(0xFD700000)
+
+#define A9SM_AND_MPMC_BASE			UL(0xEC000000)
+#define VA_A9SM_AND_MPMC_BASE			IOMEM(0xFC000000)
+
+#define SPEAR1310_RAS_BASE			UL(0xD8400000)
+#define VA_SPEAR1310_RAS_BASE			IOMEM(UL(0xFA400000))
+
+/* A9SM peripheral offsets */
+#define A9SM_PERIP_BASE				UL(0xEC800000)
+#define VA_A9SM_PERIP_BASE			IOMEM(0xFC800000)
+#define VA_SCU_BASE				(VA_A9SM_PERIP_BASE + 0x00)
+
+#define L2CC_BASE				UL(0xED000000)
+#define VA_L2CC_BASE				IOMEM(UL(0xFB000000))
+
+/* others */
+#define DMAC0_BASE				UL(0xEA800000)
+#define DMAC1_BASE				UL(0xEB000000)
+#define MCIF_CF_BASE				UL(0xB2800000)
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE			UART_BASE
+#define VA_SPEAR_DBG_UART_BASE			VA_UART_BASE
+
+#endif /* SPEAR13XX */
+
+#endif /* __MACH_SPEAR_H */
diff --git a/arch/arm/mach-spear/include/mach/timex.h b/arch/arm/mach-spear/include/mach/timex.h
new file mode 100644
index 000000000000..ef95e5b780bd
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/plat-spear/include/plat/timex.h
+ *
+ * SPEAr platform specific timex definitions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_TIMEX_H
+#define __PLAT_TIMEX_H
+
+#define CLOCK_TICK_RATE			48000000
+
+#endif /* __PLAT_TIMEX_H */
diff --git a/arch/arm/mach-spear/include/mach/uncompress.h b/arch/arm/mach-spear/include/mach/uncompress.h
new file mode 100644
index 000000000000..51b2dc93e4da
--- /dev/null
+++ b/arch/arm/mach-spear/include/mach/uncompress.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/plat-spear/include/plat/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/amba/serial.h>
+#include <mach/spear.h>
+
+#ifndef __PLAT_UNCOMPRESS_H
+#define __PLAT_UNCOMPRESS_H
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+	void __iomem *base = (void __iomem *)SPEAR_DBG_UART_BASE;
+
+	while (readl_relaxed(base + UART01x_FR) & UART01x_FR_TXFF)
+		barrier();
+
+	writel_relaxed(c, base + UART01x_DR);
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#endif /* __PLAT_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear/pl080.c b/arch/arm/mach-spear/pl080.c
new file mode 100644
index 000000000000..cfa1199d0f4a
--- /dev/null
+++ b/arch/arm/mach-spear/pl080.c
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/plat-spear/pl080.c
+ *
+ * DMAC pl080 definitions for SPEAr platform
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/amba/pl08x.h>
+#include <linux/amba/bus.h>
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/spinlock_types.h>
+#include <mach/spear.h>
+#include <mach/misc_regs.h>
+
+static spinlock_t lock = __SPIN_LOCK_UNLOCKED(x);
+
+struct {
+	unsigned char busy;
+	unsigned char val;
+} signals[16] = {{0, 0}, };
+
+int pl080_get_signal(const struct pl08x_channel_data *cd)
+{
+	unsigned int signal = cd->min_signal, val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&lock, flags);
+
+	/* Return if signal is already acquired by somebody else */
+	if (signals[signal].busy &&
+			(signals[signal].val != cd->muxval)) {
+		spin_unlock_irqrestore(&lock, flags);
+		return -EBUSY;
+	}
+
+	/* If acquiring for the first time, configure it */
+	if (!signals[signal].busy) {
+		val = readl(DMA_CHN_CFG);
+
+		/*
+		 * Each request line has two bits in DMA_CHN_CFG register. To
+		 * goto the bits of current request line, do left shift of
+		 * value by 2 * signal number.
+		 */
+		val &= ~(0x3 << (signal * 2));
+		val |= cd->muxval << (signal * 2);
+		writel(val, DMA_CHN_CFG);
+	}
+
+	signals[signal].busy++;
+	signals[signal].val = cd->muxval;
+	spin_unlock_irqrestore(&lock, flags);
+
+	return signal;
+}
+
+void pl080_put_signal(const struct pl08x_channel_data *cd, int signal)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&lock, flags);
+
+	/* if signal is not used */
+	if (!signals[signal].busy)
+		BUG();
+
+	signals[signal].busy--;
+
+	spin_unlock_irqrestore(&lock, flags);
+}
diff --git a/arch/arm/mach-spear/pl080.h b/arch/arm/mach-spear/pl080.h
new file mode 100644
index 000000000000..eb6590ded40d
--- /dev/null
+++ b/arch/arm/mach-spear/pl080.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/plat-spear/include/plat/pl080.h
+ *
+ * DMAC pl080 definitions for SPEAr platform
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_PL080_H
+#define __PLAT_PL080_H
+
+struct pl08x_channel_data;
+int pl080_get_signal(const struct pl08x_channel_data *cd);
+void pl080_put_signal(const struct pl08x_channel_data *cd, int signal);
+
+#endif /* __PLAT_PL080_H */
diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c
new file mode 100644
index 000000000000..927979e26b4d
--- /dev/null
+++ b/arch/arm/mach-spear/platsmp.c
@@ -0,0 +1,130 @@
+/*
+ * arch/arm/mach-spear13xx/platsmp.c
+ *
+ * based upon linux/arch/arm/mach-realview/platsmp.c
+ *
+ * Copyright (C) 2012 ST Microelectronics Ltd.
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <linux/irqchip/arm-gic.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_scu.h>
+#include <mach/spear.h>
+#include "generic.h"
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
+
+static void __cpuinit spear13xx_secondary_init(unsigned int cpu)
+{
+	/*
+	 * if any interrupts are already enabled for the primary
+	 * core (e.g. timer irq), then they will not have been enabled
+	 * for us: do so
+	 */
+	gic_secondary_init(0);
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	pen_release = -1;
+	smp_wmb();
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+static int __cpuinit spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+
+	/*
+	 * set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	pen_release = cpu;
+	flush_cache_all();
+	outer_flush_all();
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		smp_rmb();
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return pen_release != -1 ? -ENOSYS : 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+static void __init spear13xx_smp_init_cpus(void)
+{
+	unsigned int i, ncores = scu_get_core_count(scu_base);
+
+	if (ncores > nr_cpu_ids) {
+		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+			ncores, nr_cpu_ids);
+		ncores = nr_cpu_ids;
+	}
+
+	for (i = 0; i < ncores; i++)
+		set_cpu_possible(i, true);
+}
+
+static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus)
+{
+
+	scu_enable(scu_base);
+
+	/*
+	 * Write the address of secondary startup into the system-wide location
+	 * (presently it is in SRAM). The BootMonitor waits until it receives a
+	 * soft interrupt, and then the secondary CPU branches to this address.
+	 */
+	__raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
+}
+
+struct smp_operations spear13xx_smp_ops __initdata = {
+       .smp_init_cpus		= spear13xx_smp_init_cpus,
+       .smp_prepare_cpus	= spear13xx_smp_prepare_cpus,
+       .smp_secondary_init	= spear13xx_secondary_init,
+       .smp_boot_secondary	= spear13xx_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die			= spear13xx_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-spear/restart.c b/arch/arm/mach-spear/restart.c
new file mode 100644
index 000000000000..2b44500bb718
--- /dev/null
+++ b/arch/arm/mach-spear/restart.c
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/plat-spear/restart.c
+ *
+ * SPEAr platform specific restart functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/io.h>
+#include <linux/amba/sp810.h>
+#include <asm/system_misc.h>
+#include <mach/spear.h>
+#include "generic.h"
+
+#define SPEAR13XX_SYS_SW_RES			(VA_MISC_BASE + 0x204)
+void spear_restart(char mode, const char *cmd)
+{
+	if (mode == 's') {
+		/* software reset, Jump into ROM at address 0 */
+		soft_restart(0);
+	} else {
+		/* hardware reset, Use on-chip reset capability */
+#ifdef CONFIG_ARCH_SPEAR13XX
+		writel_relaxed(0x01, SPEAR13XX_SYS_SW_RES);
+#endif
+#if defined(CONFIG_ARCH_SPEAR3XX) || defined(CONFIG_ARCH_SPEAR6XX)
+		sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE);
+#endif
+	}
+}
diff --git a/arch/arm/mach-spear/spear1310.c b/arch/arm/mach-spear/spear1310.c
new file mode 100644
index 000000000000..ed3b5c287a7b
--- /dev/null
+++ b/arch/arm/mach-spear/spear1310.c
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-spear13xx/spear1310.c
+ *
+ * SPEAr1310 machine source file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr1310: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/pata_arasan_cf_data.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+/* Base addresses */
+#define SPEAR1310_SSP1_BASE			UL(0x5D400000)
+#define SPEAR1310_SATA0_BASE			UL(0xB1000000)
+#define SPEAR1310_SATA1_BASE			UL(0xB1800000)
+#define SPEAR1310_SATA2_BASE			UL(0xB4000000)
+
+#define SPEAR1310_RAS_GRP1_BASE			UL(0xD8000000)
+#define VA_SPEAR1310_RAS_GRP1_BASE		UL(0xFA000000)
+
+static struct arasan_cf_pdata cf_pdata = {
+	.cf_if_clk = CF_IF_CLK_166M,
+	.quirk = CF_BROKEN_UDMA,
+	.dma_priv = &cf_dma_priv,
+};
+
+/* ssp device registration */
+static struct pl022_ssp_controller ssp1_plat_data = {
+	.enable_dma = 0,
+};
+
+/* Add SPEAr1310 auxdata to pass platform data */
+static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_pdata),
+	OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
+	OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
+	OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
+
+	OF_DEV_AUXDATA("arm,pl022", SPEAR1310_SSP1_BASE, NULL, &ssp1_plat_data),
+	{}
+};
+
+static void __init spear1310_dt_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear1310_auxdata_lookup, NULL);
+}
+
+static const char * const spear1310_dt_board_compat[] = {
+	"st,spear1310",
+	"st,spear1310-evb",
+	NULL,
+};
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL		VIRTUAL
+ * 0xD8000000		0xFA000000
+ */
+struct map_desc spear1310_io_desc[] __initdata = {
+	{
+		.virtual	= VA_SPEAR1310_RAS_GRP1_BASE,
+		.pfn		= __phys_to_pfn(SPEAR1310_RAS_GRP1_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	},
+};
+
+static void __init spear1310_map_io(void)
+{
+	iotable_init(spear1310_io_desc, ARRAY_SIZE(spear1310_io_desc));
+	spear13xx_map_io();
+}
+
+DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree")
+	.smp		=	smp_ops(spear13xx_smp_ops),
+	.map_io		=	spear1310_map_io,
+	.init_irq	=	irqchip_init,
+	.init_time	=	spear13xx_timer_init,
+	.init_machine	=	spear1310_dt_init,
+	.restart	=	spear_restart,
+	.dt_compat	=	spear1310_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c
new file mode 100644
index 000000000000..75e38644bbfb
--- /dev/null
+++ b/arch/arm/mach-spear/spear1340.c
@@ -0,0 +1,193 @@
+/*
+ * arch/arm/mach-spear13xx/spear1340.c
+ *
+ * SPEAr1340 machine source file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr1340: " fmt
+
+#include <linux/ahci_platform.h>
+#include <linux/amba/serial.h>
+#include <linux/delay.h>
+#include <linux/dw_dmac.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <asm/mach/arch.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+#include "spear13xx-dma.h"
+
+/* Base addresses */
+#define SPEAR1340_SATA_BASE			UL(0xB1000000)
+#define SPEAR1340_UART1_BASE			UL(0xB4100000)
+
+/* Power Management Registers */
+#define SPEAR1340_PCM_CFG			(VA_MISC_BASE + 0x100)
+#define SPEAR1340_PCM_WKUP_CFG			(VA_MISC_BASE + 0x104)
+#define SPEAR1340_SWITCH_CTR			(VA_MISC_BASE + 0x108)
+
+#define SPEAR1340_PERIP1_SW_RST			(VA_MISC_BASE + 0x318)
+#define SPEAR1340_PERIP2_SW_RST			(VA_MISC_BASE + 0x31C)
+#define SPEAR1340_PERIP3_SW_RST			(VA_MISC_BASE + 0x320)
+
+/* PCIE - SATA configuration registers */
+#define SPEAR1340_PCIE_SATA_CFG			(VA_MISC_BASE + 0x424)
+	/* PCIE CFG MASks */
+	#define SPEAR1340_PCIE_CFG_DEVICE_PRESENT	(1 << 11)
+	#define SPEAR1340_PCIE_CFG_POWERUP_RESET	(1 << 10)
+	#define SPEAR1340_PCIE_CFG_CORE_CLK_EN		(1 << 9)
+	#define SPEAR1340_PCIE_CFG_AUX_CLK_EN		(1 << 8)
+	#define SPEAR1340_SATA_CFG_TX_CLK_EN		(1 << 4)
+	#define SPEAR1340_SATA_CFG_RX_CLK_EN		(1 << 3)
+	#define SPEAR1340_SATA_CFG_POWERUP_RESET	(1 << 2)
+	#define SPEAR1340_SATA_CFG_PM_CLK_EN		(1 << 1)
+	#define SPEAR1340_PCIE_SATA_SEL_PCIE		(0)
+	#define SPEAR1340_PCIE_SATA_SEL_SATA		(1)
+	#define SPEAR1340_SATA_PCIE_CFG_MASK		0xF1F
+	#define SPEAR1340_PCIE_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_PCIE | \
+			SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
+			SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
+			SPEAR1340_PCIE_CFG_POWERUP_RESET | \
+			SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
+	#define SPEAR1340_SATA_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_SATA | \
+			SPEAR1340_SATA_CFG_PM_CLK_EN | \
+			SPEAR1340_SATA_CFG_POWERUP_RESET | \
+			SPEAR1340_SATA_CFG_RX_CLK_EN | \
+			SPEAR1340_SATA_CFG_TX_CLK_EN)
+
+#define SPEAR1340_PCIE_MIPHY_CFG		(VA_MISC_BASE + 0x428)
+	#define SPEAR1340_MIPHY_OSC_BYPASS_EXT		(1 << 31)
+	#define SPEAR1340_MIPHY_CLK_REF_DIV2		(1 << 27)
+	#define SPEAR1340_MIPHY_CLK_REF_DIV4		(2 << 27)
+	#define SPEAR1340_MIPHY_CLK_REF_DIV8		(3 << 27)
+	#define SPEAR1340_MIPHY_PLL_RATIO_TOP(x)	(x << 0)
+	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
+			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+			SPEAR1340_MIPHY_CLK_REF_DIV2 | \
+			SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
+	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
+			(SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
+	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
+			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
+
+static struct dw_dma_slave uart1_dma_param[] = {
+	{
+		/* Tx */
+		.cfg_hi = DWC_CFGH_DST_PER(SPEAR1340_DMA_REQ_UART1_TX),
+		.cfg_lo = 0,
+		.src_master = DMA_MASTER_MEMORY,
+		.dst_master = SPEAR1340_DMA_MASTER_UART1,
+	}, {
+		/* Rx */
+		.cfg_hi = DWC_CFGH_SRC_PER(SPEAR1340_DMA_REQ_UART1_RX),
+		.cfg_lo = 0,
+		.src_master = SPEAR1340_DMA_MASTER_UART1,
+		.dst_master = DMA_MASTER_MEMORY,
+	}
+};
+
+static struct amba_pl011_data uart1_data = {
+	.dma_filter = dw_dma_filter,
+	.dma_tx_param = &uart1_dma_param[0],
+	.dma_rx_param = &uart1_dma_param[1],
+};
+
+/* SATA device registration */
+static int sata_miphy_init(struct device *dev, void __iomem *addr)
+{
+	writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
+	writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
+			SPEAR1340_PCIE_MIPHY_CFG);
+	/* Switch on sata power domain */
+	writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
+	msleep(20);
+	/* Disable PCIE SATA Controller reset */
+	writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
+			SPEAR1340_PERIP1_SW_RST);
+	msleep(20);
+
+	return 0;
+}
+
+void sata_miphy_exit(struct device *dev)
+{
+	writel(0, SPEAR1340_PCIE_SATA_CFG);
+	writel(0, SPEAR1340_PCIE_MIPHY_CFG);
+
+	/* Enable PCIE SATA Controller reset */
+	writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
+			SPEAR1340_PERIP1_SW_RST);
+	msleep(20);
+	/* Switch off sata power domain */
+	writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
+	msleep(20);
+}
+
+int sata_suspend(struct device *dev)
+{
+	if (dev->power.power_state.event == PM_EVENT_FREEZE)
+		return 0;
+
+	sata_miphy_exit(dev);
+
+	return 0;
+}
+
+int sata_resume(struct device *dev)
+{
+	if (dev->power.power_state.event == PM_EVENT_THAW)
+		return 0;
+
+	return sata_miphy_init(dev, NULL);
+}
+
+static struct ahci_platform_data sata_pdata = {
+	.init = sata_miphy_init,
+	.exit = sata_miphy_exit,
+	.suspend = sata_suspend,
+	.resume = sata_resume,
+};
+
+/* Add SPEAr1340 auxdata to pass platform data */
+static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
+	OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
+	OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
+	OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
+
+	OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
+			&sata_pdata),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR1340_UART1_BASE, NULL, &uart1_data),
+	{}
+};
+
+static void __init spear1340_dt_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear1340_auxdata_lookup, NULL);
+}
+
+static const char * const spear1340_dt_board_compat[] = {
+	"st,spear1340",
+	"st,spear1340-evb",
+	NULL,
+};
+
+DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree")
+	.smp		=	smp_ops(spear13xx_smp_ops),
+	.map_io		=	spear13xx_map_io,
+	.init_irq	=	irqchip_init,
+	.init_time	=	spear13xx_timer_init,
+	.init_machine	=	spear1340_dt_init,
+	.restart	=	spear_restart,
+	.dt_compat	=	spear1340_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear13xx-dma.h b/arch/arm/mach-spear/spear13xx-dma.h
new file mode 100644
index 000000000000..d50bdb605925
--- /dev/null
+++ b/arch/arm/mach-spear/spear13xx-dma.h
@@ -0,0 +1,128 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/dma.h
+ *
+ * DMA information for SPEAr13xx machine family
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* request id of all the peripherals */
+enum dma_master_info {
+	/* Accessible from only one master */
+	DMA_MASTER_MCIF = 0,
+	DMA_MASTER_FSMC = 1,
+	/* Accessible from both 0 & 1 */
+	DMA_MASTER_MEMORY = 0,
+	DMA_MASTER_ADC = 0,
+	DMA_MASTER_UART0 = 0,
+	DMA_MASTER_SSP0 = 0,
+	DMA_MASTER_I2C0 = 0,
+
+#ifdef CONFIG_MACH_SPEAR1310
+	/* Accessible from only one master */
+	SPEAR1310_DMA_MASTER_JPEG = 1,
+
+	/* Accessible from both 0 & 1 */
+	SPEAR1310_DMA_MASTER_I2S = 0,
+	SPEAR1310_DMA_MASTER_UART1 = 0,
+	SPEAR1310_DMA_MASTER_UART2 = 0,
+	SPEAR1310_DMA_MASTER_UART3 = 0,
+	SPEAR1310_DMA_MASTER_UART4 = 0,
+	SPEAR1310_DMA_MASTER_UART5 = 0,
+	SPEAR1310_DMA_MASTER_I2C1 = 0,
+	SPEAR1310_DMA_MASTER_I2C2 = 0,
+	SPEAR1310_DMA_MASTER_I2C3 = 0,
+	SPEAR1310_DMA_MASTER_I2C4 = 0,
+	SPEAR1310_DMA_MASTER_I2C5 = 0,
+	SPEAR1310_DMA_MASTER_I2C6 = 0,
+	SPEAR1310_DMA_MASTER_I2C7 = 0,
+	SPEAR1310_DMA_MASTER_SSP1 = 0,
+#endif
+
+#ifdef CONFIG_MACH_SPEAR1340
+	/* Accessible from only one master */
+	SPEAR1340_DMA_MASTER_I2S_PLAY = 1,
+	SPEAR1340_DMA_MASTER_I2S_REC = 1,
+	SPEAR1340_DMA_MASTER_I2C1 = 1,
+	SPEAR1340_DMA_MASTER_UART1 = 1,
+
+	/* following are accessible from both master 0 & 1 */
+	SPEAR1340_DMA_MASTER_SPDIF = 0,
+	SPEAR1340_DMA_MASTER_CAM = 1,
+	SPEAR1340_DMA_MASTER_VIDEO_IN = 0,
+	SPEAR1340_DMA_MASTER_MALI = 0,
+#endif
+};
+
+enum request_id {
+	DMA_REQ_ADC = 0,
+	DMA_REQ_SSP0_TX = 4,
+	DMA_REQ_SSP0_RX = 5,
+	DMA_REQ_UART0_TX = 6,
+	DMA_REQ_UART0_RX = 7,
+	DMA_REQ_I2C0_TX = 8,
+	DMA_REQ_I2C0_RX = 9,
+
+#ifdef CONFIG_MACH_SPEAR1310
+	SPEAR1310_DMA_REQ_FROM_JPEG = 2,
+	SPEAR1310_DMA_REQ_TO_JPEG = 3,
+	SPEAR1310_DMA_REQ_I2S_TX = 10,
+	SPEAR1310_DMA_REQ_I2S_RX = 11,
+
+	SPEAR1310_DMA_REQ_I2C1_RX = 0,
+	SPEAR1310_DMA_REQ_I2C1_TX = 1,
+	SPEAR1310_DMA_REQ_I2C2_RX = 2,
+	SPEAR1310_DMA_REQ_I2C2_TX = 3,
+	SPEAR1310_DMA_REQ_I2C3_RX = 4,
+	SPEAR1310_DMA_REQ_I2C3_TX = 5,
+	SPEAR1310_DMA_REQ_I2C4_RX = 6,
+	SPEAR1310_DMA_REQ_I2C4_TX = 7,
+	SPEAR1310_DMA_REQ_I2C5_RX = 8,
+	SPEAR1310_DMA_REQ_I2C5_TX = 9,
+	SPEAR1310_DMA_REQ_I2C6_RX = 10,
+	SPEAR1310_DMA_REQ_I2C6_TX = 11,
+	SPEAR1310_DMA_REQ_UART1_RX = 12,
+	SPEAR1310_DMA_REQ_UART1_TX = 13,
+	SPEAR1310_DMA_REQ_UART2_RX = 14,
+	SPEAR1310_DMA_REQ_UART2_TX = 15,
+	SPEAR1310_DMA_REQ_UART5_RX = 16,
+	SPEAR1310_DMA_REQ_UART5_TX = 17,
+	SPEAR1310_DMA_REQ_SSP1_RX = 18,
+	SPEAR1310_DMA_REQ_SSP1_TX = 19,
+	SPEAR1310_DMA_REQ_I2C7_RX = 20,
+	SPEAR1310_DMA_REQ_I2C7_TX = 21,
+	SPEAR1310_DMA_REQ_UART3_RX = 28,
+	SPEAR1310_DMA_REQ_UART3_TX = 29,
+	SPEAR1310_DMA_REQ_UART4_RX = 30,
+	SPEAR1310_DMA_REQ_UART4_TX = 31,
+#endif
+
+#ifdef CONFIG_MACH_SPEAR1340
+	SPEAR1340_DMA_REQ_SPDIF_TX = 2,
+	SPEAR1340_DMA_REQ_SPDIF_RX = 3,
+	SPEAR1340_DMA_REQ_I2S_TX = 10,
+	SPEAR1340_DMA_REQ_I2S_RX = 11,
+	SPEAR1340_DMA_REQ_UART1_TX = 12,
+	SPEAR1340_DMA_REQ_UART1_RX = 13,
+	SPEAR1340_DMA_REQ_I2C1_TX = 14,
+	SPEAR1340_DMA_REQ_I2C1_RX = 15,
+	SPEAR1340_DMA_REQ_CAM0_EVEN = 0,
+	SPEAR1340_DMA_REQ_CAM0_ODD = 1,
+	SPEAR1340_DMA_REQ_CAM1_EVEN = 2,
+	SPEAR1340_DMA_REQ_CAM1_ODD = 3,
+	SPEAR1340_DMA_REQ_CAM2_EVEN = 4,
+	SPEAR1340_DMA_REQ_CAM2_ODD = 5,
+	SPEAR1340_DMA_REQ_CAM3_EVEN = 6,
+	SPEAR1340_DMA_REQ_CAM3_ODD = 7,
+#endif
+};
+
+#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
new file mode 100644
index 000000000000..1b97e8623472
--- /dev/null
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -0,0 +1,184 @@
+/*
+ * arch/arm/mach-spear13xx/spear13xx.c
+ *
+ * SPEAr13XX machines common source file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr13xx: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/clk.h>
+#include <linux/dw_dmac.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/map.h>
+#include <asm/smp_twd.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+#include "spear13xx-dma.h"
+
+/* common dw_dma filter routine to be used by peripherals */
+bool dw_dma_filter(struct dma_chan *chan, void *slave)
+{
+	struct dw_dma_slave *dws = (struct dw_dma_slave *)slave;
+
+	if (chan->device->dev == dws->dma_dev) {
+		chan->private = slave;
+		return true;
+	} else {
+		return false;
+	}
+}
+
+/* ssp device registration */
+static struct dw_dma_slave ssp_dma_param[] = {
+	{
+		/* Tx */
+		.cfg_hi = DWC_CFGH_DST_PER(DMA_REQ_SSP0_TX),
+		.cfg_lo = 0,
+		.src_master = DMA_MASTER_MEMORY,
+		.dst_master = DMA_MASTER_SSP0,
+	}, {
+		/* Rx */
+		.cfg_hi = DWC_CFGH_SRC_PER(DMA_REQ_SSP0_RX),
+		.cfg_lo = 0,
+		.src_master = DMA_MASTER_SSP0,
+		.dst_master = DMA_MASTER_MEMORY,
+	}
+};
+
+struct pl022_ssp_controller pl022_plat_data = {
+	.enable_dma = 1,
+	.dma_filter = dw_dma_filter,
+	.dma_rx_param = &ssp_dma_param[1],
+	.dma_tx_param = &ssp_dma_param[0],
+};
+
+/* CF device registration */
+struct dw_dma_slave cf_dma_priv = {
+	.cfg_hi = 0,
+	.cfg_lo = 0,
+	.src_master = 0,
+	.dst_master = 0,
+};
+
+/* dmac device registeration */
+struct dw_dma_platform_data dmac_plat_data = {
+	.nr_channels = 8,
+	.chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
+	.chan_priority = CHAN_PRIORITY_DESCENDING,
+	.block_size = 4095U,
+	.nr_masters = 2,
+	.data_width = { 3, 3, 0, 0 },
+};
+
+void __init spear13xx_l2x0_init(void)
+{
+	/*
+	 * 512KB (64KB/way), 8-way associativity, parity supported
+	 *
+	 * FIXME: 9th bit, of Auxillary Controller register must be set
+	 * for some spear13xx devices for stable L2 operation.
+	 *
+	 * Enable Early BRESP, L2 prefetch for Instruction and Data,
+	 * write alloc and 'Full line of zero' options
+	 *
+	 */
+
+	writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
+
+	/*
+	 * Program following latencies in order to make
+	 * SPEAr1340 work at 600 MHz
+	 */
+	writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
+	writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
+	l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
+}
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL		VIRTUAL
+ * 0xB3000000		0xFE000000
+ * 0xE0000000		0xFD000000
+ * 0xEC000000		0xFC000000
+ * 0xED000000		0xFB000000
+ */
+struct map_desc spear13xx_io_desc[] __initdata = {
+	{
+		.virtual	= (unsigned long)VA_PERIP_GRP2_BASE,
+		.pfn		= __phys_to_pfn(PERIP_GRP2_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= (unsigned long)VA_PERIP_GRP1_BASE,
+		.pfn		= __phys_to_pfn(PERIP_GRP1_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= (unsigned long)VA_A9SM_AND_MPMC_BASE,
+		.pfn		= __phys_to_pfn(A9SM_AND_MPMC_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= (unsigned long)VA_L2CC_BASE,
+		.pfn		= __phys_to_pfn(L2CC_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	},
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear13xx_map_io(void)
+{
+	iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
+}
+
+static void __init spear13xx_clk_init(void)
+{
+	if (of_machine_is_compatible("st,spear1310"))
+		spear1310_clk_init(VA_MISC_BASE, VA_SPEAR1310_RAS_BASE);
+	else if (of_machine_is_compatible("st,spear1340"))
+		spear1340_clk_init(VA_MISC_BASE);
+	else
+		pr_err("%s: Unknown machine\n", __func__);
+}
+
+void __init spear13xx_timer_init(void)
+{
+	char pclk_name[] = "osc_24m_clk";
+	struct clk *gpt_clk, *pclk;
+
+	spear13xx_clk_init();
+
+	/* get the system timer clock */
+	gpt_clk = clk_get_sys("gpt0", NULL);
+	if (IS_ERR(gpt_clk)) {
+		pr_err("%s:couldn't get clk for gpt\n", __func__);
+		BUG();
+	}
+
+	/* get the suitable parent clock for timer*/
+	pclk = clk_get(NULL, pclk_name);
+	if (IS_ERR(pclk)) {
+		pr_err("%s:couldn't get %s as parent for gpt\n", __func__,
+				pclk_name);
+		BUG();
+	}
+
+	clk_set_parent(gpt_clk, pclk);
+	clk_put(gpt_clk);
+	clk_put(pclk);
+
+	spear_setup_of_timer();
+	twd_local_timer_of_register();
+}
diff --git a/arch/arm/mach-spear/spear300.c b/arch/arm/mach-spear/spear300.c
new file mode 100644
index 000000000000..bac56e845f7a
--- /dev/null
+++ b/arch/arm/mach-spear/spear300.c
@@ -0,0 +1,220 @@
+/*
+ * arch/arm/mach-spear3xx/spear300.c
+ *
+ * SPEAr300 machine source file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr300: " fmt
+
+#include <linux/amba/pl08x.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear300_dma_info[] = {
+	{
+		.bus_id = "uart0_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "irda",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "adc",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "to_jpeg",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "from_jpeg",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras0_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras0_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras1_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras1_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras2_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras2_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras3_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras3_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras4_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras4_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	},
+};
+
+/* Add SPEAr300 auxdata to pass platform data */
+static struct of_dev_auxdata spear300_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+			&pl022_plat_data),
+	OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
+			&pl080_plat_data),
+	{}
+};
+
+static void __init spear300_dt_init(void)
+{
+	pl080_plat_data.slave_channels = spear300_dma_info;
+	pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear300_dma_info);
+
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear300_auxdata_lookup, NULL);
+}
+
+static const char * const spear300_dt_board_compat[] = {
+	"st,spear300",
+	"st,spear300-evb",
+	NULL,
+};
+
+static void __init spear300_map_io(void)
+{
+	spear3xx_map_io();
+}
+
+DT_MACHINE_START(SPEAR300_DT, "ST SPEAr300 SoC with Flattened Device Tree")
+	.map_io		=	spear300_map_io,
+	.init_irq	=	irqchip_init,
+	.init_time	=	spear3xx_timer_init,
+	.init_machine	=	spear300_dt_init,
+	.restart	=	spear_restart,
+	.dt_compat	=	spear300_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear310.c b/arch/arm/mach-spear/spear310.c
new file mode 100644
index 000000000000..6ffbc63d516d
--- /dev/null
+++ b/arch/arm/mach-spear/spear310.c
@@ -0,0 +1,262 @@
+/*
+ * arch/arm/mach-spear3xx/spear310.c
+ *
+ * SPEAr310 machine source file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr310: " fmt
+
+#include <linux/amba/pl08x.h>
+#include <linux/amba/serial.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+#define SPEAR310_UART1_BASE		UL(0xB2000000)
+#define SPEAR310_UART2_BASE		UL(0xB2080000)
+#define SPEAR310_UART3_BASE		UL(0xB2100000)
+#define SPEAR310_UART4_BASE		UL(0xB2180000)
+#define SPEAR310_UART5_BASE		UL(0xB2200000)
+
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear310_dma_info[] = {
+	{
+		.bus_id = "uart0_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "irda",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "adc",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "to_jpeg",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "from_jpeg",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart1_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart1_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart2_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart2_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart3_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart3_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart4_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart4_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart5_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart5_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	},
+};
+
+/* uart devices plat data */
+static struct amba_pl011_data spear310_uart_data[] = {
+	{
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart1_tx",
+		.dma_rx_param = "uart1_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart2_tx",
+		.dma_rx_param = "uart2_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart3_tx",
+		.dma_rx_param = "uart3_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart4_tx",
+		.dma_rx_param = "uart4_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart5_tx",
+		.dma_rx_param = "uart5_rx",
+	},
+};
+
+/* Add SPEAr310 auxdata to pass platform data */
+static struct of_dev_auxdata spear310_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+			&pl022_plat_data),
+	OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
+			&pl080_plat_data),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART1_BASE, NULL,
+			&spear310_uart_data[0]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART2_BASE, NULL,
+			&spear310_uart_data[1]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART3_BASE, NULL,
+			&spear310_uart_data[2]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART4_BASE, NULL,
+			&spear310_uart_data[3]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART5_BASE, NULL,
+			&spear310_uart_data[4]),
+	{}
+};
+
+static void __init spear310_dt_init(void)
+{
+	pl080_plat_data.slave_channels = spear310_dma_info;
+	pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear310_dma_info);
+
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear310_auxdata_lookup, NULL);
+}
+
+static const char * const spear310_dt_board_compat[] = {
+	"st,spear310",
+	"st,spear310-evb",
+	NULL,
+};
+
+static void __init spear310_map_io(void)
+{
+	spear3xx_map_io();
+}
+
+DT_MACHINE_START(SPEAR310_DT, "ST SPEAr310 SoC with Flattened Device Tree")
+	.map_io		=	spear310_map_io,
+	.init_irq	=	irqchip_init,
+	.init_time	=	spear3xx_timer_init,
+	.init_machine	=	spear310_dt_init,
+	.restart	=	spear_restart,
+	.dt_compat	=	spear310_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear320.c b/arch/arm/mach-spear/spear320.c
new file mode 100644
index 000000000000..6eb3eec65f96
--- /dev/null
+++ b/arch/arm/mach-spear/spear320.c
@@ -0,0 +1,277 @@
+/*
+ * arch/arm/mach-spear3xx/spear320.c
+ *
+ * SPEAr320 machine source file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr320: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/amba/pl08x.h>
+#include <linux/amba/serial.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include "generic.h"
+#include <mach/spear.h>
+
+#define SPEAR320_UART1_BASE		UL(0xA3000000)
+#define SPEAR320_UART2_BASE		UL(0xA4000000)
+#define SPEAR320_SSP0_BASE		UL(0xA5000000)
+#define SPEAR320_SSP1_BASE		UL(0xA6000000)
+
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear320_dma_info[] = {
+	{
+		.bus_id = "uart0_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c0_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c0_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "irda",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "adc",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "to_jpeg",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "from_jpeg",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp1_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp1_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp2_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp2_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "uart1_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "uart1_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "uart2_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "uart2_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2c1_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2c1_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2c2_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2c2_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2s_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2s_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "rs485_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "rs485_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB2,
+	},
+};
+
+static struct pl022_ssp_controller spear320_ssp_data[] = {
+	{
+		.bus_id = 1,
+		.enable_dma = 1,
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "ssp1_tx",
+		.dma_rx_param = "ssp1_rx",
+		.num_chipselect = 2,
+	}, {
+		.bus_id = 2,
+		.enable_dma = 1,
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "ssp2_tx",
+		.dma_rx_param = "ssp2_rx",
+		.num_chipselect = 2,
+	}
+};
+
+static struct amba_pl011_data spear320_uart_data[] = {
+	{
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart1_tx",
+		.dma_rx_param = "uart1_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart2_tx",
+		.dma_rx_param = "uart2_rx",
+	},
+};
+
+/* Add SPEAr310 auxdata to pass platform data */
+static struct of_dev_auxdata spear320_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+			&pl022_plat_data),
+	OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
+			&pl080_plat_data),
+	OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP0_BASE, NULL,
+			&spear320_ssp_data[0]),
+	OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP1_BASE, NULL,
+			&spear320_ssp_data[1]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART1_BASE, NULL,
+			&spear320_uart_data[0]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART2_BASE, NULL,
+			&spear320_uart_data[1]),
+	{}
+};
+
+static void __init spear320_dt_init(void)
+{
+	pl080_plat_data.slave_channels = spear320_dma_info;
+	pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear320_dma_info);
+
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear320_auxdata_lookup, NULL);
+}
+
+static const char * const spear320_dt_board_compat[] = {
+	"st,spear320",
+	"st,spear320-evb",
+	"st,spear320-hmi",
+	NULL,
+};
+
+struct map_desc spear320_io_desc[] __initdata = {
+	{
+		.virtual	= (unsigned long)VA_SPEAR320_SOC_CONFIG_BASE,
+		.pfn		= __phys_to_pfn(SPEAR320_SOC_CONFIG_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	},
+};
+
+static void __init spear320_map_io(void)
+{
+	iotable_init(spear320_io_desc, ARRAY_SIZE(spear320_io_desc));
+	spear3xx_map_io();
+}
+
+DT_MACHINE_START(SPEAR320_DT, "ST SPEAr320 SoC with Flattened Device Tree")
+	.map_io		=	spear320_map_io,
+	.init_irq	=	irqchip_init,
+	.init_time	=	spear3xx_timer_init,
+	.init_machine	=	spear320_dt_init,
+	.restart	=	spear_restart,
+	.dt_compat	=	spear320_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/spear3xx.c b/arch/arm/mach-spear/spear3xx.c
new file mode 100644
index 000000000000..0227c97797cd
--- /dev/null
+++ b/arch/arm/mach-spear/spear3xx.c
@@ -0,0 +1,116 @@
+/*
+ * arch/arm/mach-spear3xx/spear3xx.c
+ *
+ * SPEAr3XX machines common source file
+ *
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.linux@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr3xx: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/amba/pl080.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <asm/mach/map.h>
+#include "pl080.h"
+#include "generic.h"
+#include <mach/spear.h>
+#include <mach/misc_regs.h>
+
+/* ssp device registration */
+struct pl022_ssp_controller pl022_plat_data = {
+	.bus_id = 0,
+	.enable_dma = 1,
+	.dma_filter = pl08x_filter_id,
+	.dma_tx_param = "ssp0_tx",
+	.dma_rx_param = "ssp0_rx",
+	/*
+	 * This is number of spi devices that can be connected to spi. There are
+	 * two type of chipselects on which slave devices can work. One is chip
+	 * select provided by spi masters other is controlled through external
+	 * gpio's. We can't use chipselect provided from spi master (because as
+	 * soon as FIFO becomes empty, CS is disabled and transfer ends). So
+	 * this number now depends on number of gpios available for spi. each
+	 * slave on each master requires a separate gpio pin.
+	 */
+	.num_chipselect = 2,
+};
+
+/* dmac device registration */
+struct pl08x_platform_data pl080_plat_data = {
+	.memcpy_channel = {
+		.bus_id = "memcpy",
+		.cctl_memcpy =
+			(PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+			PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
+			PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
+			PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
+			PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
+			PL080_CONTROL_PROT_SYS),
+	},
+	.lli_buses = PL08X_AHB1,
+	.mem_buses = PL08X_AHB1,
+	.get_signal = pl080_get_signal,
+	.put_signal = pl080_put_signal,
+};
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL		VIRTUAL
+ * 0xD0000000		0xFD000000
+ * 0xFC000000		0xFC000000
+ */
+struct map_desc spear3xx_io_desc[] __initdata = {
+	{
+		.virtual	= (unsigned long)VA_SPEAR_ICM1_2_BASE,
+		.pfn		= __phys_to_pfn(SPEAR_ICM1_2_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE,
+		.pfn		= __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	},
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear3xx_map_io(void)
+{
+	iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc));
+}
+
+void __init spear3xx_timer_init(void)
+{
+	char pclk_name[] = "pll3_clk";
+	struct clk *gpt_clk, *pclk;
+
+	spear3xx_clk_init(MISC_BASE, VA_SPEAR320_SOC_CONFIG_BASE);
+
+	/* get the system timer clock */
+	gpt_clk = clk_get_sys("gpt0", NULL);
+	if (IS_ERR(gpt_clk)) {
+		pr_err("%s:couldn't get clk for gpt\n", __func__);
+		BUG();
+	}
+
+	/* get the suitable parent clock for timer*/
+	pclk = clk_get(NULL, pclk_name);
+	if (IS_ERR(pclk)) {
+		pr_err("%s:couldn't get %s as parent for gpt\n",
+				__func__, pclk_name);
+		BUG();
+	}
+
+	clk_set_parent(gpt_clk, pclk);
+	clk_put(gpt_clk);
+	clk_put(pclk);
+
+	spear_setup_of_timer();
+}
diff --git a/arch/arm/mach-spear/spear6xx.c b/arch/arm/mach-spear/spear6xx.c
new file mode 100644
index 000000000000..ec8eefbbdfad
--- /dev/null
+++ b/arch/arm/mach-spear/spear6xx.c
@@ -0,0 +1,431 @@
+/*
+ * arch/arm/mach-spear6xx/spear6xx.c
+ *
+ * SPEAr6XX machines common source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/amba/pl08x.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/irqchip.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/amba/pl080.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include "pl080.h"
+#include "generic.h"
+#include <mach/spear.h>
+#include <mach/misc_regs.h>
+
+/* dmac device registration */
+static struct pl08x_channel_data spear600_dma_info[] = {
+	{
+		.bus_id = "ssp1_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp1_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart1_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart1_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp2_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp2_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp0_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "irda",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "adc",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "to_jpeg",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "from_jpeg",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras0_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras0_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras1_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras1_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras2_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras2_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras3_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras3_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras4_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras4_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 1,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ext0_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext0_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext1_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext1_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext2_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext2_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext3_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext3_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext4_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext4_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext5_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext5_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext6_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext6_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext7_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext7_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 2,
+		.periph_buses = PL08X_AHB2,
+	},
+};
+
+static struct pl08x_platform_data spear6xx_pl080_plat_data = {
+	.memcpy_channel = {
+		.bus_id = "memcpy",
+		.cctl_memcpy =
+			(PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+			PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
+			PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
+			PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
+			PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
+			PL080_CONTROL_PROT_SYS),
+	},
+	.lli_buses = PL08X_AHB1,
+	.mem_buses = PL08X_AHB1,
+	.get_signal = pl080_get_signal,
+	.put_signal = pl080_put_signal,
+	.slave_channels = spear600_dma_info,
+	.num_slave_channels = ARRAY_SIZE(spear600_dma_info),
+};
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL		VIRTUAL
+ * 0xF0000000		0xF0000000
+ * 0xF1000000		0xF1000000
+ * 0xD0000000		0xFD000000
+ * 0xFC000000		0xFC000000
+ */
+struct map_desc spear6xx_io_desc[] __initdata = {
+	{
+		.virtual	= (unsigned long)VA_SPEAR6XX_ML_CPU_BASE,
+		.pfn		= __phys_to_pfn(SPEAR_ICM3_ML1_2_BASE),
+		.length		= 2 * SZ_16M,
+		.type		= MT_DEVICE
+	},	{
+		.virtual	= (unsigned long)VA_SPEAR_ICM1_2_BASE,
+		.pfn		= __phys_to_pfn(SPEAR_ICM1_2_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= (unsigned long)VA_SPEAR_ICM3_SMI_CTRL_BASE,
+		.pfn		= __phys_to_pfn(SPEAR_ICM3_SMI_CTRL_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	},
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear6xx_map_io(void)
+{
+	iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
+}
+
+void __init spear6xx_timer_init(void)
+{
+	char pclk_name[] = "pll3_clk";
+	struct clk *gpt_clk, *pclk;
+
+	spear6xx_clk_init(MISC_BASE);
+
+	/* get the system timer clock */
+	gpt_clk = clk_get_sys("gpt0", NULL);
+	if (IS_ERR(gpt_clk)) {
+		pr_err("%s:couldn't get clk for gpt\n", __func__);
+		BUG();
+	}
+
+	/* get the suitable parent clock for timer*/
+	pclk = clk_get(NULL, pclk_name);
+	if (IS_ERR(pclk)) {
+		pr_err("%s:couldn't get %s as parent for gpt\n",
+				__func__, pclk_name);
+		BUG();
+	}
+
+	clk_set_parent(gpt_clk, pclk);
+	clk_put(gpt_clk);
+	clk_put(pclk);
+
+	spear_setup_of_timer();
+}
+
+/* Add auxdata to pass platform data */
+struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arm,pl080", SPEAR_ICM3_DMA_BASE, NULL,
+			&spear6xx_pl080_plat_data),
+	{}
+};
+
+static void __init spear600_dt_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear6xx_auxdata_lookup, NULL);
+}
+
+static const char *spear600_dt_board_compat[] = {
+	"st,spear600",
+	NULL
+};
+
+DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)")
+	.map_io		=	spear6xx_map_io,
+	.init_irq	=	irqchip_init,
+	.init_time	=	spear6xx_timer_init,
+	.init_machine	=	spear600_dt_init,
+	.restart	=	spear_restart,
+	.dt_compat	=	spear600_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c
new file mode 100644
index 000000000000..d449673e40f7
--- /dev/null
+++ b/arch/arm/mach-spear/time.c
@@ -0,0 +1,245 @@
+/*
+ * arch/arm/plat-spear/time.c
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim<shiraz.hashim@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/time.h>
+#include <linux/irq.h>
+#include <asm/mach/time.h>
+#include "generic.h"
+
+/*
+ * We would use TIMER0 and TIMER1 as clockevent and clocksource.
+ * Timer0 and Timer1 both belong to same gpt block in cpu subbsystem. Further
+ * they share same functional clock. Any change in one's functional clock will
+ * also affect other timer.
+ */
+
+#define CLKEVT	0	/* gpt0, channel0 as clockevent */
+#define CLKSRC	1	/* gpt0, channel1 as clocksource */
+
+/* Register offsets, x is channel number */
+#define CR(x)		((x) * 0x80 + 0x80)
+#define IR(x)		((x) * 0x80 + 0x84)
+#define LOAD(x)		((x) * 0x80 + 0x88)
+#define COUNT(x)	((x) * 0x80 + 0x8C)
+
+/* Reg bit definitions */
+#define CTRL_INT_ENABLE		0x0100
+#define CTRL_ENABLE		0x0020
+#define CTRL_ONE_SHOT		0x0010
+
+#define CTRL_PRESCALER1		0x0
+#define CTRL_PRESCALER2		0x1
+#define CTRL_PRESCALER4		0x2
+#define CTRL_PRESCALER8		0x3
+#define CTRL_PRESCALER16	0x4
+#define CTRL_PRESCALER32	0x5
+#define CTRL_PRESCALER64	0x6
+#define CTRL_PRESCALER128	0x7
+#define CTRL_PRESCALER256	0x8
+
+#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;
+
+static void clockevent_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *clk_event_dev);
+static int clockevent_next_event(unsigned long evt,
+				 struct clock_event_device *clk_event_dev);
+
+static void spear_clocksource_init(void)
+{
+	u32 tick_rate;
+	u16 val;
+
+	/* program the prescaler (/256)*/
+	writew(CTRL_PRESCALER256, gpt_base + CR(CLKSRC));
+
+	/* find out actual clock driving Timer */
+	tick_rate = clk_get_rate(gpt_clk);
+	tick_rate >>= CTRL_PRESCALER256;
+
+	writew(0xFFFF, gpt_base + LOAD(CLKSRC));
+
+	val = readw(gpt_base + CR(CLKSRC));
+	val &= ~CTRL_ONE_SHOT;	/* autoreload mode */
+	val |= CTRL_ENABLE ;
+	writew(val, gpt_base + CR(CLKSRC));
+
+	/* register the clocksource */
+	clocksource_mmio_init(gpt_base + COUNT(CLKSRC), "tmr1", tick_rate,
+		200, 16, clocksource_mmio_readw_up);
+}
+
+static struct clock_event_device clkevt = {
+	.name = "tmr0",
+	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode = clockevent_set_mode,
+	.set_next_event = clockevent_next_event,
+	.shift = 0,	/* to be computed */
+};
+
+static void clockevent_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *clk_event_dev)
+{
+	u32 period;
+	u16 val;
+
+	/* stop the timer */
+	val = readw(gpt_base + CR(CLKEVT));
+	val &= ~CTRL_ENABLE;
+	writew(val, gpt_base + CR(CLKEVT));
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		period = clk_get_rate(gpt_clk) / HZ;
+		period >>= CTRL_PRESCALER16;
+		writew(period, gpt_base + LOAD(CLKEVT));
+
+		val = readw(gpt_base + CR(CLKEVT));
+		val &= ~CTRL_ONE_SHOT;
+		val |= CTRL_ENABLE | CTRL_INT_ENABLE;
+		writew(val, gpt_base + CR(CLKEVT));
+
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		val = readw(gpt_base + CR(CLKEVT));
+		val |= CTRL_ONE_SHOT;
+		writew(val, gpt_base + CR(CLKEVT));
+
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_RESUME:
+
+		break;
+	default:
+		pr_err("Invalid mode requested\n");
+		break;
+	}
+}
+
+static int clockevent_next_event(unsigned long cycles,
+				 struct clock_event_device *clk_event_dev)
+{
+	u16 val = readw(gpt_base + CR(CLKEVT));
+
+	if (val & CTRL_ENABLE)
+		writew(val & ~CTRL_ENABLE, gpt_base + CR(CLKEVT));
+
+	writew(cycles, gpt_base + LOAD(CLKEVT));
+
+	val |= CTRL_ENABLE | CTRL_INT_ENABLE;
+	writew(val, gpt_base + CR(CLKEVT));
+
+	return 0;
+}
+
+static irqreturn_t spear_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &clkevt;
+
+	writew(INT_STATUS, gpt_base + IR(CLKEVT));
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction spear_timer_irq = {
+	.name = "timer",
+	.flags = IRQF_DISABLED | IRQF_TIMER,
+	.handler = spear_timer_interrupt
+};
+
+static void __init spear_clockevent_init(int irq)
+{
+	u32 tick_rate;
+
+	/* program the prescaler */
+	writew(CTRL_PRESCALER16, gpt_base + CR(CLKEVT));
+
+	tick_rate = clk_get_rate(gpt_clk);
+	tick_rate >>= CTRL_PRESCALER16;
+
+	clkevt.cpumask = cpumask_of(0);
+
+	clockevents_config_and_register(&clkevt, tick_rate, 3, 0xfff0);
+
+	setup_irq(irq, &spear_timer_irq);
+}
+
+const static struct of_device_id timer_of_match[] __initconst = {
+	{ .compatible = "st,spear-timer", },
+	{ },
+};
+
+void __init spear_setup_of_timer(void)
+{
+	struct device_node *np;
+	int irq, ret;
+
+	np = of_find_matching_node(NULL, timer_of_match);
+	if (!np) {
+		pr_err("%s: No timer passed via DT\n", __func__);
+		return;
+	}
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (!irq) {
+		pr_err("%s: No irq passed for timer via DT\n", __func__);
+		return;
+	}
+
+	gpt_base = of_iomap(np, 0);
+	if (!gpt_base) {
+		pr_err("%s: of iomap failed\n", __func__);
+		return;
+	}
+
+	gpt_clk = clk_get_sys("gpt0", NULL);
+	if (!gpt_clk) {
+		pr_err("%s:couldn't get clk for gpt\n", __func__);
+		goto err_iomap;
+	}
+
+	ret = clk_prepare_enable(gpt_clk);
+	if (ret < 0) {
+		pr_err("%s:couldn't prepare-enable gpt clock\n", __func__);
+		goto err_prepare_enable_clk;
+	}
+
+	spear_clockevent_init(irq);
+	spear_clocksource_init();
+
+	return;
+
+err_prepare_enable_clk:
+	clk_put(gpt_clk);
+err_iomap:
+	iounmap(gpt_base);
+}