Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (224 commits)
  ARM: remove 'select GENERIC_TIME'
  ARM: 6136/1: ARCH_REQUIRE_GPIOLIB selects GENERIC_GPIO
  ARM: 6074/1: oprofile: convert from sysdev to platform device
  ARM: 6073/1: oprofile: remove old files and update KConfig
  ARM: 6072/1: oprofile: use perf-events framework as backend
  ARM: 6071/1: perf-events: allow modules to query the number of hardware counters
  ARM: 6070/1: perf-events: add support for xscale PMUs
  ARM: 6069/1: perf-events: use numeric ID to identify PMU
  ARM: 6064/1: pmu: register IRQs at runtime
  ARM: Optionally allow ARMv6 to use 'normal, bufferable' memory for DMA
  ARM: 6134/1: Handle instruction cache maintenance fault properly
  ARM: nwfpe: allow debugging output to be configured at runtime
  ARM: rename mach_cpu_disable() to platform_cpu_disable()
  ARM: 6132/1: PL330: Add common core driver
  ARM: 6094/1: Extend cache-l2x0 to support the 16-way PL310
  ARM: Move memory mapping into mmu.c
  ARM: Ensure meminfo is sorted prior to sanity_check_meminfo
  ARM: Remove useless linux/bootmem.h includes
  ARM: convert /proc/cpu/aligment to seq_file
  arm: use asm-generic/scatterlist.h
  ...
diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index 82e418d..7f5fc3b 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -20,6 +20,8 @@
 	- S3C24XX ARM Linux Overview
 Sharp-LH
 	- Linux on Sharp LH79524 and LH7A40X System On a Chip (SOC)
+SPEAr
+	- ST SPEAr platform Linux Overview
 VFP/
 	- Release notes for Linux Kernel Vector Floating Point support code
 empeg/
diff --git a/Documentation/arm/SPEAr/overview.txt b/Documentation/arm/SPEAr/overview.txt
new file mode 100644
index 0000000..253a35c
--- /dev/null
+++ b/Documentation/arm/SPEAr/overview.txt
@@ -0,0 +1,60 @@
+			SPEAr ARM Linux Overview
+			==========================
+
+Introduction
+------------
+
+  SPEAr (Structured Processor Enhanced Architecture).
+  weblink : http://www.st.com/spear
+
+  The ST Microelectronics SPEAr range of ARM9/CortexA9 System-on-Chip CPUs are
+  supported by the 'spear' platform of ARM Linux. Currently SPEAr300,
+  SPEAr310, SPEAr320 and SPEAr600 SOCs are supported. Support for the SPEAr13XX
+  series is in progress.
+
+  Hierarchy in SPEAr is as follows:
+
+  SPEAr (Platform)
+	- SPEAr3XX (3XX SOC series, based on ARM9)
+		- SPEAr300 (SOC)
+			- SPEAr300_EVB (Evaluation Board)
+		- SPEAr310 (SOC)
+			- SPEAr310_EVB (Evaluation Board)
+		- SPEAr320 (SOC)
+			- SPEAr320_EVB (Evaluation Board)
+	- SPEAr6XX (6XX SOC series, based on ARM9)
+		- SPEAr600 (SOC)
+			- SPEAr600_EVB (Evaluation Board)
+	- SPEAr13XX (13XX SOC series, based on ARM CORTEXA9)
+		- SPEAr1300 (SOC)
+
+  Configuration
+  -------------
+
+  A generic configuration is provided for each machine, and can be used as the
+  default by
+	make spear600_defconfig
+	make spear300_defconfig
+	make spear310_defconfig
+	make spear320_defconfig
+
+  Layout
+  ------
+
+  The common files for multiple machine families (SPEAr3XX, SPEAr6XX and
+  SPEAr13XX) are located in the platform code contained in arch/arm/plat-spear
+  with headers in plat/.
+
+  Each machine series have a directory with name arch/arm/mach-spear followed by
+  series name. Like mach-spear3xx, mach-spear6xx and mach-spear13xx.
+
+  Common file for machines of spear3xx family is mach-spear3xx/spear3xx.c and for
+  spear6xx is mach-spear6xx/spear6xx.c. mach-spear* also contain soc/machine
+  specific files, like spear300.c, spear310.c, spear320.c and spear600.c.
+  mach-spear* also contains board specific files for each machine type.
+
+
+  Document Author
+  ---------------
+
+  Viresh Kumar, (c) 2010 ST Microelectronics
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 05df0b7..a5e3811 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -520,29 +520,6 @@
 
 ----------------------------
 
-What:	corgikbd, spitzkbd, tosakbd driver
-When:	2.6.35
-Files:	drivers/input/keyboard/{corgi,spitz,tosa}kbd.c
-Why:	We now have a generic GPIO based matrix keyboard driver that
-	are fully capable of handling all the keys on these devices.
-	The original drivers manipulate the GPIO registers directly
-	and so are difficult to maintain.
-Who:	Eric Miao <eric.y.miao@gmail.com>
-
-----------------------------
-
-What:	corgi_ssp and corgi_ts driver
-When:	2.6.35
-Files:	arch/arm/mach-pxa/corgi_ssp.c, drivers/input/touchscreen/corgi_ts.c
-Why:	The corgi touchscreen is now deprecated in favour of the generic
-	ads7846.c driver. The noise reduction technique used in corgi_ts.c,
-	that's to wait till vsync before ADC sampling, is also integrated into
-	ads7846 driver now. Provided that the original driver is not generic
-	and is difficult to maintain, it will be removed later.
-Who:	Eric Miao <eric.y.miao@gmail.com>
-
-----------------------------
-
 What:	capifs
 When:	February 2011
 Files:	drivers/isdn/capi/capifs.*
diff --git a/MAINTAINERS b/MAINTAINERS
index 3d2651b..a77ae73 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -586,6 +586,12 @@
 F:	drivers/mtd/nand/bcm_umi_hamming.c
 F:	drivers/mtd/nand/nand_bcm_umi.h
 
+ARM/CAVIUM NETWORKS CNS3XXX MACHINE SUPPORT
+M:	Anton Vorontsov <avorontsov@mvista.com>
+S:	Maintained
+F:	arch/arm/mach-cns3xxx/
+T:	git git://git.infradead.org/users/cbou/linux-cns3xxx.git
+
 ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
 M:	Hartley Sweeten <hsweeten@visionengravers.com>
 M:	Ryan Mallon <ryan@bluewatersys.com>
@@ -775,11 +781,10 @@
 S:	Maintained
 
 ARM/Marvell Loki/Kirkwood/MV78xx0/Orion SOC support
-M:	Lennert Buytenhek <buytenh@marvell.com>
-M:	Nicolas Pitre <nico@marvell.com>
+M:	Lennert Buytenhek <kernel@wantstofly.org>
+M:	Nicolas Pitre <nico@fluxnic.net>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-T:	git git://git.marvell.com/orion
-S:	Maintained
+S:	Odd Fixes
 F:	arch/arm/mach-loki/
 F:	arch/arm/mach-kirkwood/
 F:	arch/arm/mach-mv78xx0/
@@ -994,6 +999,20 @@
 S:	Maintained
 F:	arch/arm/vfp/
 
+ARM/VOIPAC PXA270 SUPPORT
+M:	Marek Vasut <marek.vasut@gmail.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	arch/arm/mach-pxa/vpac270.c
+F:	arch/arm/mach-pxa/include/mach-pxa/vpac270.h
+
+ARM/ZIPIT Z2 SUPPORT
+M:	Marek Vasut <marek.vasut@gmail.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	arch/arm/mach-pxa/z2.c
+F:	arch/arm/mach-pxa/include/mach-pxa/z2.h
+
 ASC7621 HARDWARE MONITOR DRIVER
 M:	George Joseph <george.joseph@fairview5.com>
 L:	lm-sensors@lm-sensors.org
@@ -3635,7 +3654,8 @@
 
 MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
 M:	Nicolas Pitre <nico@fluxnic.net>
-S:	Maintained
+S:	Odd Fixes
+F: drivers/mmc/host/mvsdio.*
 
 MARVELL YUKON / SYSKONNECT DRIVER
 M:	Mirko Lindner <mlindner@syskonnect.de>
@@ -5133,7 +5153,7 @@
 
 SMC91x ETHERNET DRIVER
 M:	Nicolas Pitre <nico@fluxnic.net>
-S:	Maintained
+S:	Odd Fixes
 F:	drivers/net/smc91x.*
 
 SMSC47B397 HARDWARE MONITOR DRIVER
@@ -5264,6 +5284,46 @@
 F:	drivers/serial/sunzilog.c
 F:	drivers/serial/sunzilog.h
 
+SPEAR PLATFORM SUPPORT
+M:	Viresh Kumar <viresh.kumar@st.com>
+W:	http://www.st.com/spear
+S:	Maintained
+F:	arch/arm/plat-spear/
+
+SPEAR3XX MACHINE SUPPORT
+M:	Viresh Kumar <viresh.kumar@st.com>
+W:	http://www.st.com/spear
+S:	Maintained
+F:	arch/arm/mach-spear3xx/
+
+SPEAR6XX MACHINE SUPPORT
+M:	Rajeev Kumar <rajeev-dlh.kumar@st.com>
+W:	http://www.st.com/spear
+S:	Maintained
+F:	arch/arm/mach-spear6xx/
+
+SPEAR CLOCK FRAMEWORK SUPPORT
+M:	Viresh Kumar <viresh.kumar@st.com>
+W:	http://www.st.com/spear
+S:	Maintained
+F:	arch/arm/mach-spear*/clock.c
+F:	arch/arm/mach-spear*/include/mach/clkdev.h
+F:	arch/arm/plat-spear/clock.c
+F:	arch/arm/plat-spear/include/plat/clock.h and clkdev.h
+
+SPEAR PAD MULTIPLEXING SUPPORT
+M:	Viresh Kumar <viresh.kumar@st.com>
+W:	http://www.st.com/spear
+S:	Maintained
+F:	arch/arm/plat-spear/include/plat/padmux.h
+F:	arch/arm/plat-spear/padmux.c
+F:	arch/arm/mach-spear*/spear*xx.c
+F:	arch/arm/mach-spear*/include/mach/generic.h
+F:	arch/arm/mach-spear3xx/spear3*0.c
+F:	arch/arm/mach-spear3xx/spear3*0_evb.c
+F:	arch/arm/mach-spear6xx/spear600.c
+F:	arch/arm/mach-spear6xx/spear600_evb.c
+
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
 M:	Roger Wolff <R.E.Wolff@BitWizard.nl>
 S:	Supported
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 92622eb..a07b6c4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -13,7 +13,7 @@
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select GENERIC_ATOMIC64 if (!CPU_32v6K)
-	select HAVE_OPROFILE
+	select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
 	select HAVE_ARCH_KGDB
 	select HAVE_KPROBES if (!XIP_KERNEL)
 	select HAVE_KRETPROBES if (HAVE_KPROBES)
@@ -21,6 +21,7 @@
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_LZO
+	select HAVE_KERNEL_LZMA
 	select HAVE_PERF_EVENTS
 	select PERF_USE_VMALLOC
 	help
@@ -42,6 +43,11 @@
 
 config GENERIC_TIME
 	bool
+	default y
+
+config ARCH_USES_GETTIMEOFFSET
+	bool
+	default n
 
 config GENERIC_CLOCKEVENTS
 	bool
@@ -175,28 +181,6 @@
 	help
 	  Setting ARM L1 cache line size to 64 Bytes.
 
-if OPROFILE
-
-config OPROFILE_ARMV6
-	def_bool y
-	depends on CPU_V6 && !SMP
-	select OPROFILE_ARM11_CORE
-
-config OPROFILE_MPCORE
-	def_bool y
-	depends on CPU_V6 && SMP
-	select OPROFILE_ARM11_CORE
-
-config OPROFILE_ARM11_CORE
-	bool
-
-config OPROFILE_ARMV7
-	def_bool y
-	depends on CPU_V7 && !SMP
-	bool
-
-endif
-
 config VECTORS_BASE
 	hex
 	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
@@ -231,6 +215,7 @@
 	select CPU_ARM920T
 	select ARM_AMBA
 	select HAVE_CLK
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  This enables support for systems based on the Agilent AAEC-2000
 
@@ -238,21 +223,22 @@
 	bool "ARM Ltd. Integrator family"
 	select ARM_AMBA
 	select ARCH_HAS_CPUFREQ
-	select HAVE_CLK
 	select COMMON_CLKDEV
-	select ICST525
+	select ICST
+	select GENERIC_CLOCKEVENTS
+	select PLAT_VERSATILE
 	help
 	  Support for ARM's Integrator platform.
 
 config ARCH_REALVIEW
 	bool "ARM Ltd. RealView family"
 	select ARM_AMBA
-	select HAVE_CLK
 	select COMMON_CLKDEV
-	select ICST307
-	select GENERIC_TIME
+	select ICST
 	select GENERIC_CLOCKEVENTS
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select PLAT_VERSATILE
+	select ARM_TIMER_SP804
 	select GPIO_PL061 if GPIOLIB
 	help
 	  This enables support for ARM Ltd RealView boards.
@@ -261,20 +247,33 @@
 	bool "ARM Ltd. Versatile family"
 	select ARM_AMBA
 	select ARM_VIC
-	select HAVE_CLK
 	select COMMON_CLKDEV
-	select ICST307
-	select GENERIC_TIME
+	select ICST
 	select GENERIC_CLOCKEVENTS
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select PLAT_VERSATILE
+	select ARM_TIMER_SP804
 	help
 	  This enables support for ARM Ltd Versatile board.
 
+config ARCH_VEXPRESS
+	bool "ARM Ltd. Versatile Express family"
+	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select ARM_AMBA
+	select ARM_TIMER_SP804
+	select COMMON_CLKDEV
+	select GENERIC_CLOCKEVENTS
+	select HAVE_CLK
+	select ICST
+	select PLAT_VERSATILE
+	help
+	  This enables support for the ARM Ltd Versatile Express boards.
+
 config ARCH_AT91
 	bool "Atmel AT91"
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	select HAVE_CLK
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  This enables support for systems based on the Atmel AT91RM9200,
 	  AT91SAM9 and AT91CAP9 processors.
@@ -285,7 +284,6 @@
 	select CPU_V6
 	select ARM_AMBA
 	select COMMON_CLKDEV
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	help
@@ -294,14 +292,23 @@
 config ARCH_CLPS711X
 	bool "Cirrus Logic CLPS711x/EP721x-based"
 	select CPU_ARM720T
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  Support for Cirrus Logic 711x/721x based boards.
 
+config ARCH_CNS3XXX
+	bool "Cavium Networks CNS3XXX family"
+	select CPU_V6
+	select GENERIC_CLOCKEVENTS
+	select ARM_GIC
+	help
+	  Support for Cavium Networks CNS3XXX platform.
+
 config ARCH_GEMINI
 	bool "Cortina Systems Gemini"
 	select CPU_FA526
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  Support for the Cortina Systems Gemini family SoCs
 
@@ -310,6 +317,7 @@
 	select CPU_SA110
 	select ISA
 	select NO_IOPORT
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  This is an evaluation board for the StrongARM processor available
 	  from Digital. It has limited hardware on-board, including an
@@ -321,11 +329,10 @@
 	select CPU_ARM920T
 	select ARM_AMBA
 	select ARM_VIC
-	select GENERIC_GPIO
-	select HAVE_CLK
 	select COMMON_CLKDEV
 	select ARCH_REQUIRE_GPIOLIB
 	select ARCH_HAS_HOLES_MEMORYMODEL
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  This enables support for the Cirrus EP93xx series of CPUs.
 
@@ -333,16 +340,15 @@
 	bool "FootBridge"
 	select CPU_SA110
 	select FOOTBRIDGE
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  Support for systems based on the DC21285 companion chip
 	  ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
 
 config ARCH_MXC
 	bool "Freescale MXC/iMX-based"
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select ARCH_REQUIRE_GPIOLIB
-	select HAVE_CLK
 	select COMMON_CLKDEV
 	help
 	  Support for Freescale MXC/iMX-based family of processors
@@ -350,12 +356,9 @@
 config ARCH_STMP3XXX
 	bool "Freescale STMP3xxx"
 	select CPU_ARM926T
-	select HAVE_CLK
 	select COMMON_CLKDEV
 	select ARCH_REQUIRE_GPIOLIB
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
-	select GENERIC_GPIO
 	select USB_ARCH_HAS_EHCI
 	help
 	  Support for systems based on the Freescale 3xxx CPUs.
@@ -365,7 +368,6 @@
 	select CPU_ARM926T
 	select ARM_VIC
 	select GENERIC_CLOCKEVENTS
-	select GENERIC_TIME
 	help
 	  This enables support for systems based on the Hilscher NetX Soc
 
@@ -373,6 +375,7 @@
 	bool "Hynix HMS720x-based"
 	select CPU_ARM720T
 	select ISA_DMA_API
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  This enables support for systems based on the Hynix HMS720x
 
@@ -393,7 +396,6 @@
 	select CPU_XSCALE
 	select PLAT_IOP
 	select PCI
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
 	  Support for Intel's 80219 and IOP32X (XScale) family of
@@ -405,7 +407,6 @@
 	select CPU_XSCALE
 	select PLAT_IOP
 	select PCI
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
 	  Support for Intel's IOP33X (XScale) family of processors.
@@ -415,6 +416,7 @@
 	depends on MMU
 	select CPU_XSC3
  	select PCI
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  Support for Intel's IXP23xx (XScale) family of processors.
 
@@ -423,6 +425,7 @@
 	depends on MMU
 	select CPU_XSCALE
 	select PCI
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  Support for Intel's IXP2400/2800 (XScale) family of processors.
 
@@ -431,7 +434,6 @@
 	depends on MMU
 	select CPU_XSCALE
 	select GENERIC_GPIO
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select DMABOUNCE if PCI
 	help
@@ -441,6 +443,7 @@
 	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.
@@ -454,9 +457,7 @@
 config ARCH_DOVE
 	bool "Marvell Dove"
 	select PCI
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select PLAT_ORION
 	help
@@ -466,9 +467,7 @@
 	bool "Marvell Kirkwood"
 	select CPU_FEROCEON
 	select PCI
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select PLAT_ORION
 	help
@@ -478,7 +477,6 @@
 config ARCH_LOKI
 	bool "Marvell Loki (88RC8480)"
 	select CPU_FEROCEON
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select PLAT_ORION
 	help
@@ -488,9 +486,7 @@
 	bool "Marvell MV78xx0"
 	select CPU_FEROCEON
 	select PCI
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select PLAT_ORION
 	help
@@ -502,9 +498,7 @@
 	depends on MMU
 	select CPU_FEROCEON
 	select PCI
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select PLAT_ORION
 	help
@@ -515,11 +509,8 @@
 config ARCH_MMP
 	bool "Marvell PXA168/910/MMP2"
 	depends on MMU
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
-	select HAVE_CLK
 	select COMMON_CLKDEV
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select TICK_ONESHOT
 	select PLAT_PXA
@@ -529,8 +520,8 @@
 config ARCH_KS8695
 	bool "Micrel/Kendin KS8695"
 	select CPU_ARM922T
-	select GENERIC_GPIO
-        select ARCH_REQUIRE_GPIOLIB
+	select ARCH_REQUIRE_GPIOLIB
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
 	  System-on-Chip devices.
@@ -539,7 +530,6 @@
 	bool "NetSilicon NS9xxx"
 	select CPU_ARM926T
 	select GENERIC_GPIO
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
 	help
@@ -552,10 +542,7 @@
 	bool "Nuvoton W90X900 CPU"
 	select CPU_ARM926T
 	select ARCH_REQUIRE_GPIOLIB
-	select GENERIC_GPIO
-	select HAVE_CLK
 	select COMMON_CLKDEV
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	help
 	  Support for Nuvoton (Winbond logic dept.) ARM9 processor,
@@ -569,7 +556,6 @@
 config ARCH_NUC93X
 	bool "Nuvoton NUC93X CPU"
 	select CPU_ARM926T
-	select HAVE_CLK
 	select COMMON_CLKDEV
 	help
 	  Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
@@ -578,8 +564,8 @@
 config ARCH_PNX4008
 	bool "Philips Nexperia PNX4008 Mobile"
 	select CPU_ARM926T
-	select HAVE_CLK
 	select COMMON_CLKDEV
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  This enables support for Philips PNX4008 mobile platform.
 
@@ -588,11 +574,8 @@
 	depends on MMU
 	select ARCH_MTD_XIP
 	select ARCH_HAS_CPUFREQ
-	select GENERIC_GPIO
-	select HAVE_CLK
 	select COMMON_CLKDEV
 	select ARCH_REQUIRE_GPIOLIB
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select TICK_ONESHOT
 	select PLAT_PXA
@@ -601,14 +584,14 @@
 
 config ARCH_MSM
 	bool "Qualcomm MSM"
-	select CPU_V6
-	select GENERIC_TIME
+	select HAVE_CLK
 	select GENERIC_CLOCKEVENTS
 	help
-	  Support for Qualcomm MSM7K based systems.  This runs on the ARM11
-	  apps processor of the MSM7K and depends on a shared memory
-	  interface to the ARM9 modem processor which runs the baseband stack
-	  and controls some vital subsystems (clock and power control, etc).
+	  Support for Qualcomm MSM/QSD based systems.  This runs on the
+	  apps processor of the MSM/QSD and depends on a shared memory
+	  interface to the modem processor which runs the baseband
+	  stack and controls some vital subsystems
+	  (clock and power control, etc).
 
 config ARCH_SHMOBILE
 	bool "Renesas SH-Mobile"
@@ -625,6 +608,7 @@
 	select ISA_DMA_API
 	select NO_IOPORT
 	select ARCH_SPARSEMEM_ENABLE
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  On the Acorn Risc-PC, Linux can support the internal IDE disk and
 	  CD-ROM interface, serial and parallel port, and the floppy drive.
@@ -637,8 +621,6 @@
 	select ARCH_MTD_XIP
 	select ARCH_HAS_CPUFREQ
 	select CPU_FREQ
-	select GENERIC_GPIO
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
 	select TICK_ONESHOT
@@ -647,23 +629,28 @@
 	  Support for StrongARM 11x0 based boards.
 
 config ARCH_S3C2410
-	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
+	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450"
 	select GENERIC_GPIO
 	select ARCH_HAS_CPUFREQ
 	select HAVE_CLK
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  Samsung S3C2410X CPU based systems, such as the Simtec Electronics
 	  BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
 	  the Samsung SMDK2410 development board (and derivatives).
 
+	  Note, the S3C2416 and the S3C2450 are so close that they even share
+	  the same SoC ID code. This means that there is no seperate machine
+	  directory (no arch/arm/mach-s3c2450) as the S3C2416 was first.
+
 config ARCH_S3C64XX
 	bool "Samsung S3C64XX"
 	select PLAT_SAMSUNG
 	select CPU_V6
-	select GENERIC_GPIO
 	select ARM_VIC
 	select HAVE_CLK
 	select NO_IOPORT
+	select ARCH_USES_GETTIMEOFFSET
 	select ARCH_HAS_CPUFREQ
 	select ARCH_REQUIRE_GPIOLIB
 	select SAMSUNG_CLKSRC
@@ -720,6 +707,7 @@
 	select ISA_DMA
 	select ZONE_DMA
 	select PCI
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  Support for the StrongARM based Digital DNARD machine, also known
 	  as "Shark" (<http://www.shark-linux.de/shark.html>).
@@ -729,6 +717,7 @@
 	select CPU_ARM922T
 	select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM
 	select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
+	select ARCH_USES_GETTIMEOFFSET
 	help
 	  Say Y here for systems based on one of the Sharp LH7A40X
 	  System on a Chip processors.  These CPUs include an ARM922T
@@ -742,9 +731,7 @@
 	select HAVE_TCM
 	select ARM_AMBA
 	select ARM_VIC
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
-	select HAVE_CLK
 	select COMMON_CLKDEV
 	select GENERIC_GPIO
 	help
@@ -754,9 +741,9 @@
 	bool "ST-Ericsson U8500 Series"
 	select CPU_V7
 	select ARM_AMBA
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select COMMON_CLKDEV
+	select ARCH_REQUIRE_GPIOLIB
 	help
 	  Support for ST-Ericsson's Ux500 architecture
 
@@ -765,11 +752,8 @@
 	select ARM_AMBA
 	select ARM_VIC
 	select CPU_ARM926T
-	select HAVE_CLK
 	select COMMON_CLKDEV
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
 	help
 	  Support for the Nomadik platform by ST-Ericsson
@@ -777,11 +761,8 @@
 config ARCH_DAVINCI
 	bool "TI DaVinci"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
-	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
-	select HAVE_CLK
 	select ZONE_DMA
 	select HAVE_IDE
 	select COMMON_CLKDEV
@@ -792,16 +773,24 @@
 
 config ARCH_OMAP
 	bool "TI OMAP"
-	select GENERIC_GPIO
 	select HAVE_CLK
 	select ARCH_REQUIRE_GPIOLIB
 	select ARCH_HAS_CPUFREQ
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select ARCH_HAS_HOLES_MEMORYMODEL
 	help
 	  Support for TI's OMAP platform (OMAP1 and OMAP2).
 
+config PLAT_SPEAR
+	bool "ST SPEAr"
+	select ARM_AMBA
+	select ARCH_REQUIRE_GPIOLIB
+	select COMMON_CLKDEV
+	select GENERIC_CLOCKEVENTS
+	select HAVE_CLK
+	help
+	  Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
+
 endchoice
 
 #
@@ -817,6 +806,8 @@
 
 source "arch/arm/mach-clps711x/Kconfig"
 
+source "arch/arm/mach-cns3xxx/Kconfig"
+
 source "arch/arm/mach-davinci/Kconfig"
 
 source "arch/arm/mach-dove/Kconfig"
@@ -887,11 +878,13 @@
 source "arch/arm/plat-s3c24xx/Kconfig"
 source "arch/arm/plat-s5p/Kconfig"
 source "arch/arm/plat-s5pc1xx/Kconfig"
+source "arch/arm/plat-spear/Kconfig"
 
 if ARCH_S3C2410
 source "arch/arm/mach-s3c2400/Kconfig"
 source "arch/arm/mach-s3c2410/Kconfig"
 source "arch/arm/mach-s3c2412/Kconfig"
+source "arch/arm/mach-s3c2416/Kconfig"
 source "arch/arm/mach-s3c2440/Kconfig"
 source "arch/arm/mach-s3c2443/Kconfig"
 endif
@@ -920,6 +913,8 @@
 
 source "arch/arm/mach-versatile/Kconfig"
 
+source "arch/arm/mach-vexpress/Kconfig"
+
 source "arch/arm/mach-w90x900/Kconfig"
 
 # Definitions to make life easier
@@ -929,7 +924,6 @@
 config PLAT_IOP
 	bool
 	select GENERIC_CLOCKEVENTS
-	select GENERIC_TIME
 
 config PLAT_ORION
 	bool
@@ -937,6 +931,12 @@
 config PLAT_PXA
 	bool
 
+config PLAT_VERSATILE
+	bool
+
+config ARM_TIMER_SP804
+	bool
+
 source arch/arm/mm/Kconfig
 
 config IWMMXT
@@ -1065,6 +1065,10 @@
 	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
 	  VESA. If you have PCI, say Y, otherwise N.
 
+config PCI_DOMAINS
+	bool
+	depends on PCI
+
 config PCI_SYSCALL
 	def_bool PCI
 
@@ -1093,10 +1097,11 @@
 config SMP
 	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
-		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500)
+		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
+		 ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
 	depends on GENERIC_CLOCKEVENTS
 	select USE_GENERIC_SMP_HELPERS
-	select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500)
+	select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
 	help
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, like most personal computers, say N. If
@@ -1277,7 +1282,7 @@
 
 config HW_PERF_EVENTS
 	bool "Enable hardware performance counter support for perf events"
-	depends on PERF_EVENTS && CPU_HAS_PMU && (CPU_V6 || CPU_V7)
+	depends on PERF_EVENTS && CPU_HAS_PMU
 	default y
 	help
 	  Enable hardware performance counter support for perf events. If
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index ed820e7..d5af3b0 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -121,6 +121,7 @@
 machine-$(CONFIG_ARCH_AT91)		:= at91
 machine-$(CONFIG_ARCH_BCMRING)		:= bcmring
 machine-$(CONFIG_ARCH_CLPS711X)		:= clps711x
+machine-$(CONFIG_ARCH_CNS3XXX)		:= cns3xxx
 machine-$(CONFIG_ARCH_DAVINCI)		:= davinci
 machine-$(CONFIG_ARCH_DOVE)		:= dove
 machine-$(CONFIG_ARCH_EBSA110)		:= ebsa110
@@ -160,7 +161,7 @@
 machine-$(CONFIG_ARCH_PXA)		:= pxa
 machine-$(CONFIG_ARCH_REALVIEW)		:= realview
 machine-$(CONFIG_ARCH_RPC)		:= rpc
-machine-$(CONFIG_ARCH_S3C2410)		:= s3c2410 s3c2400 s3c2412 s3c2440 s3c2443
+machine-$(CONFIG_ARCH_S3C2410)		:= s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
 machine-$(CONFIG_ARCH_S3C24A0)		:= s3c24a0
 machine-$(CONFIG_ARCH_S3C64XX)		:= s3c64xx
 machine-$(CONFIG_ARCH_S5P6440)		:= s5p6440
@@ -175,9 +176,14 @@
 machine-$(CONFIG_ARCH_U300)		:= u300
 machine-$(CONFIG_ARCH_U8500)		:= ux500
 machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
+machine-$(CONFIG_ARCH_VEXPRESS)		:= vexpress
 machine-$(CONFIG_ARCH_W90X900)		:= w90x900
 machine-$(CONFIG_ARCH_NUC93X)		:= nuc93x
 machine-$(CONFIG_FOOTBRIDGE)		:= footbridge
+machine-$(CONFIG_MACH_SPEAR300)		:= spear3xx
+machine-$(CONFIG_MACH_SPEAR310)		:= spear3xx
+machine-$(CONFIG_MACH_SPEAR320)		:= spear3xx
+machine-$(CONFIG_MACH_SPEAR600)		:= spear6xx
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -192,6 +198,8 @@
 plat-$(CONFIG_PLAT_S3C24XX)	:= s3c24xx samsung
 plat-$(CONFIG_PLAT_S5PC1XX)	:= s5pc1xx samsung
 plat-$(CONFIG_PLAT_S5P)		:= s5p samsung
+plat-$(CONFIG_PLAT_SPEAR)	:= spear
+plat-$(CONFIG_PLAT_VERSATILE)	:= versatile
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 97c89e7..53faa90 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -65,6 +65,7 @@
 
 suffix_$(CONFIG_KERNEL_GZIP) = gzip
 suffix_$(CONFIG_KERNEL_LZO)  = lzo
+suffix_$(CONFIG_KERNEL_LZMA) = lzma
 
 targets       := vmlinux vmlinux.lds \
 		 piggy.$(suffix_y) piggy.$(suffix_y).o \
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
index 9c09707..4c72a97 100644
--- a/arch/arm/boot/compressed/decompress.c
+++ b/arch/arm/boot/compressed/decompress.c
@@ -40,6 +40,10 @@
 #include "../../../../lib/decompress_unlzo.c"
 #endif
 
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
 void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
 {
 	decompress(input, len, NULL, NULL, output, NULL, error);
diff --git a/arch/arm/boot/compressed/piggy.lzma.S b/arch/arm/boot/compressed/piggy.lzma.S
new file mode 100644
index 0000000..d7e69cf
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.lzma.S
@@ -0,0 +1,6 @@
+	.section .piggydata,#alloc
+	.globl	input_data
+input_data:
+	.incbin	"arch/arm/boot/compressed/piggy.lzma"
+	.globl	input_data_end
+input_data_end:
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 4efbb9d..0a34c81 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -12,10 +12,10 @@
 	  The maximum number of VICs available in the system, for
 	  power management.
 
-config ICST525
+config ICST
 	bool
 
-config ICST307
+config PL330
 	bool
 
 config SA1111
@@ -40,3 +40,4 @@
 
 config COMMON_CLKDEV
 	bool
+	select HAVE_CLK
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 76be7ff..e6e8664 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -4,8 +4,8 @@
 
 obj-$(CONFIG_ARM_GIC)		+= gic.o
 obj-$(CONFIG_ARM_VIC)		+= vic.o
-obj-$(CONFIG_ICST525)		+= icst525.o
-obj-$(CONFIG_ICST307)		+= icst307.o
+obj-$(CONFIG_ICST)		+= icst.o
+obj-$(CONFIG_PL330)		+= pl330.o
 obj-$(CONFIG_SA1111)		+= sa1111.o
 obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
 obj-$(CONFIG_DMABOUNCE)		+= dmabounce.o
diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c
index dba4c1d..e2b2bb6 100644
--- a/arch/arm/common/clkdev.c
+++ b/arch/arm/common/clkdev.c
@@ -53,12 +53,13 @@
 				continue;
 			match += 1;
 		}
-		if (match == 0)
-			continue;
 
 		if (match > best) {
 			clk = p->clk;
-			best = match;
+			if (match != 3)
+				best = match;
+			else
+				break;
 		}
 	}
 	return clk;
diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c
new file mode 100644
index 0000000..9a7f09c
--- /dev/null
+++ b/arch/arm/common/icst.c
@@ -0,0 +1,100 @@
+/*
+ *  linux/arch/arm/common/icst307.c
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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.
+ *
+ *  Support functions for calculating clocks/divisors for the ICST307
+ *  clock generators.  See http://www.icst.com/ for more information
+ *  on these devices.
+ *
+ *  This is an almost identical implementation to the ICST525 clock generator.
+ *  The s2div and idx2s files are different
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <asm/hardware/icst.h>
+
+/*
+ * Divisors for each OD setting.
+ */
+const unsigned char icst307_s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 };
+const unsigned char icst525_s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
+EXPORT_SYMBOL(icst307_s2div);
+EXPORT_SYMBOL(icst525_s2div);
+
+unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco)
+{
+	return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]);
+}
+
+EXPORT_SYMBOL(icst_hz);
+
+/*
+ * Ascending divisor S values.
+ */
+const unsigned char icst307_idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 };
+const unsigned char icst525_idx2s[8] = { 1, 3, 4, 7, 5, 2, 6, 0 };
+EXPORT_SYMBOL(icst307_idx2s);
+EXPORT_SYMBOL(icst525_idx2s);
+
+struct icst_vco
+icst_hz_to_vco(const struct icst_params *p, unsigned long freq)
+{
+	struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
+	unsigned long f;
+	unsigned int i = 0, rd, best = (unsigned int)-1;
+
+	/*
+	 * First, find the PLL output divisor such
+	 * that the PLL output is within spec.
+	 */
+	do {
+		f = freq * p->s2div[p->idx2s[i]];
+
+		if (f > p->vco_min && f <= p->vco_max)
+			break;
+	} while (i < 8);
+
+	if (i >= 8)
+		return vco;
+
+	vco.s = p->idx2s[i];
+
+	/*
+	 * Now find the closest divisor combination
+	 * which gives a PLL output of 'f'.
+	 */
+	for (rd = p->rd_min; rd <= p->rd_max; rd++) {
+		unsigned long fref_div, f_pll;
+		unsigned int vd;
+		int f_diff;
+
+		fref_div = (2 * p->ref) / rd;
+
+		vd = (f + fref_div / 2) / fref_div;
+		if (vd < p->vd_min || vd > p->vd_max)
+			continue;
+
+		f_pll = fref_div * vd;
+		f_diff = f_pll - f;
+		if (f_diff < 0)
+			f_diff = -f_diff;
+
+		if ((unsigned)f_diff < best) {
+			vco.v = vd - 8;
+			vco.r = rd - 2;
+			if (f_diff == 0)
+				break;
+			best = f_diff;
+		}
+	}
+
+	return vco;
+}
+
+EXPORT_SYMBOL(icst_hz_to_vco);
diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c
deleted file mode 100644
index 6d094c1..0000000
--- a/arch/arm/common/icst307.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *  linux/arch/arm/common/icst307.c
- *
- *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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.
- *
- *  Support functions for calculating clocks/divisors for the ICST307
- *  clock generators.  See http://www.icst.com/ for more information
- *  on these devices.
- *
- *  This is an almost identical implementation to the ICST525 clock generator.
- *  The s2div and idx2s files are different
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include <asm/hardware/icst307.h>
-
-/*
- * Divisors for each OD setting.
- */
-static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 };
-
-unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco)
-{
-	return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]);
-}
-
-EXPORT_SYMBOL(icst307_khz);
-
-/*
- * Ascending divisor S values.
- */
-static unsigned char idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 };
-
-struct icst307_vco
-icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq)
-{
-	struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
-	unsigned long f;
-	unsigned int i = 0, rd, best = (unsigned int)-1;
-
-	/*
-	 * First, find the PLL output divisor such
-	 * that the PLL output is within spec.
-	 */
-	do {
-		f = freq * s2div[idx2s[i]];
-
-		/*
-		 * f must be between 6MHz and 200MHz (3.3 or 5V)
-		 */
-		if (f > 6000 && f <= p->vco_max)
-			break;
-	} while (i < ARRAY_SIZE(idx2s));
-
-	if (i >= ARRAY_SIZE(idx2s))
-		return vco;
-
-	vco.s = idx2s[i];
-
-	/*
-	 * Now find the closest divisor combination
-	 * which gives a PLL output of 'f'.
-	 */
-	for (rd = p->rd_min; rd <= p->rd_max; rd++) {
-		unsigned long fref_div, f_pll;
-		unsigned int vd;
-		int f_diff;
-
-		fref_div = (2 * p->ref) / rd;
-
-		vd = (f + fref_div / 2) / fref_div;
-		if (vd < p->vd_min || vd > p->vd_max)
-			continue;
-
-		f_pll = fref_div * vd;
-		f_diff = f_pll - f;
-		if (f_diff < 0)
-			f_diff = -f_diff;
-
-		if ((unsigned)f_diff < best) {
-			vco.v = vd - 8;
-			vco.r = rd - 2;
-			if (f_diff == 0)
-				break;
-			best = f_diff;
-		}
-	}
-
-	return vco;
-}
-
-EXPORT_SYMBOL(icst307_khz_to_vco);
-
-struct icst307_vco
-icst307_ps_to_vco(const struct icst307_params *p, unsigned long period)
-{
-	struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
-	unsigned long f, ps;
-	unsigned int i = 0, rd, best = (unsigned int)-1;
-
-	ps = 1000000000UL / p->vco_max;
-
-	/*
-	 * First, find the PLL output divisor such
-	 * that the PLL output is within spec.
-	 */
-	do {
-		f = period / s2div[idx2s[i]];
-
-		/*
-		 * f must be between 6MHz and 200MHz (3.3 or 5V)
-		 */
-		if (f >= ps && f < 1000000000UL / 6000 + 1)
-			break;
-	} while (i < ARRAY_SIZE(idx2s));
-
-	if (i >= ARRAY_SIZE(idx2s))
-		return vco;
-
-	vco.s = idx2s[i];
-
-	ps = 500000000UL / p->ref;
-
-	/*
-	 * Now find the closest divisor combination
-	 * which gives a PLL output of 'f'.
-	 */
-	for (rd = p->rd_min; rd <= p->rd_max; rd++) {
-		unsigned long f_in_div, f_pll;
-		unsigned int vd;
-		int f_diff;
-
-		f_in_div = ps * rd;
-
-		vd = (f_in_div + f / 2) / f;
-		if (vd < p->vd_min || vd > p->vd_max)
-			continue;
-
-		f_pll = (f_in_div + vd / 2) / vd;
-		f_diff = f_pll - f;
-		if (f_diff < 0)
-			f_diff = -f_diff;
-
-		if ((unsigned)f_diff < best) {
-			vco.v = vd - 8;
-			vco.r = rd - 2;
-			if (f_diff == 0)
-				break;
-			best = f_diff;
-		}
-	}
-
-	return vco;
-}
-
-EXPORT_SYMBOL(icst307_ps_to_vco);
diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c
deleted file mode 100644
index 3d377c5..0000000
--- a/arch/arm/common/icst525.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- *  linux/arch/arm/common/icst525.c
- *
- *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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.
- *
- *  Support functions for calculating clocks/divisors for the ICST525
- *  clock generators.  See http://www.icst.com/ for more information
- *  on these devices.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include <asm/hardware/icst525.h>
-
-/*
- * Divisors for each OD setting.
- */
-static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
-
-unsigned long icst525_khz(const struct icst525_params *p, struct icst525_vco vco)
-{
-	return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]);
-}
-
-EXPORT_SYMBOL(icst525_khz);
-
-/*
- * Ascending divisor S values.
- */
-static unsigned char idx2s[] = { 1, 3, 4, 7, 5, 2, 6, 0 };
-
-struct icst525_vco
-icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq)
-{
-	struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
-	unsigned long f;
-	unsigned int i = 0, rd, best = (unsigned int)-1;
-
-	/*
-	 * First, find the PLL output divisor such
-	 * that the PLL output is within spec.
-	 */
-	do {
-		f = freq * s2div[idx2s[i]];
-
-		/*
-		 * f must be between 10MHz and
-		 *  320MHz (5V) or 200MHz (3V)
-		 */
-		if (f > 10000 && f <= p->vco_max)
-			break;
-	} while (i < ARRAY_SIZE(idx2s));
-
-	if (i >= ARRAY_SIZE(idx2s))
-		return vco;
-
-	vco.s = idx2s[i];
-
-	/*
-	 * Now find the closest divisor combination
-	 * which gives a PLL output of 'f'.
-	 */
-	for (rd = p->rd_min; rd <= p->rd_max; rd++) {
-		unsigned long fref_div, f_pll;
-		unsigned int vd;
-		int f_diff;
-
-		fref_div = (2 * p->ref) / rd;
-
-		vd = (f + fref_div / 2) / fref_div;
-		if (vd < p->vd_min || vd > p->vd_max)
-			continue;
-
-		f_pll = fref_div * vd;
-		f_diff = f_pll - f;
-		if (f_diff < 0)
-			f_diff = -f_diff;
-
-		if ((unsigned)f_diff < best) {
-			vco.v = vd - 8;
-			vco.r = rd - 2;
-			if (f_diff == 0)
-				break;
-			best = f_diff;
-		}
-	}
-
-	return vco;
-}
-
-EXPORT_SYMBOL(icst525_khz_to_vco);
-
-struct icst525_vco
-icst525_ps_to_vco(const struct icst525_params *p, unsigned long period)
-{
-	struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
-	unsigned long f, ps;
-	unsigned int i = 0, rd, best = (unsigned int)-1;
-
-	ps = 1000000000UL / p->vco_max;
-
-	/*
-	 * First, find the PLL output divisor such
-	 * that the PLL output is within spec.
-	 */
-	do {
-		f = period / s2div[idx2s[i]];
-
-		/*
-		 * f must be between 10MHz and
-		 *  320MHz (5V) or 200MHz (3V)
-		 */
-		if (f >= ps && f < 100000)
-			break;
-	} while (i < ARRAY_SIZE(idx2s));
-
-	if (i >= ARRAY_SIZE(idx2s))
-		return vco;
-
-	vco.s = idx2s[i];
-
-	ps = 500000000UL / p->ref;
-
-	/*
-	 * Now find the closest divisor combination
-	 * which gives a PLL output of 'f'.
-	 */
-	for (rd = p->rd_min; rd <= p->rd_max; rd++) {
-		unsigned long f_in_div, f_pll;
-		unsigned int vd;
-		int f_diff;
-
-		f_in_div = ps * rd;
-
-		vd = (f_in_div + f / 2) / f;
-		if (vd < p->vd_min || vd > p->vd_max)
-			continue;
-
-		f_pll = (f_in_div + vd / 2) / vd;
-		f_diff = f_pll - f;
-		if (f_diff < 0)
-			f_diff = -f_diff;
-
-		if ((unsigned)f_diff < best) {
-			vco.v = vd - 8;
-			vco.r = rd - 2;
-			if (f_diff == 0)
-				break;
-			best = f_diff;
-		}
-	}
-
-	return vco;
-}
-
-EXPORT_SYMBOL(icst525_ps_to_vco);
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
new file mode 100644
index 0000000..5ebbab6
--- /dev/null
+++ b/arch/arm/common/pl330.c
@@ -0,0 +1,1966 @@
+/* linux/arch/arm/common/pl330.c
+ *
+ * Copyright (C) 2010 Samsung Electronics Co Ltd.
+ *	Jaswinder Singh <jassi.brar@samsung.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/hardware/pl330.h>
+
+/* Register and Bit field Definitions */
+#define DS		0x0
+#define DS_ST_STOP	0x0
+#define DS_ST_EXEC	0x1
+#define DS_ST_CMISS	0x2
+#define DS_ST_UPDTPC	0x3
+#define DS_ST_WFE	0x4
+#define DS_ST_ATBRR	0x5
+#define DS_ST_QBUSY	0x6
+#define DS_ST_WFP	0x7
+#define DS_ST_KILL	0x8
+#define DS_ST_CMPLT	0x9
+#define DS_ST_FLTCMP	0xe
+#define DS_ST_FAULT	0xf
+
+#define DPC		0x4
+#define INTEN		0x20
+#define ES		0x24
+#define INTSTATUS	0x28
+#define INTCLR		0x2c
+#define FSM		0x30
+#define FSC		0x34
+#define FTM		0x38
+
+#define _FTC		0x40
+#define FTC(n)		(_FTC + (n)*0x4)
+
+#define _CS		0x100
+#define CS(n)		(_CS + (n)*0x8)
+#define CS_CNS		(1 << 21)
+
+#define _CPC		0x104
+#define CPC(n)		(_CPC + (n)*0x8)
+
+#define _SA		0x400
+#define SA(n)		(_SA + (n)*0x20)
+
+#define _DA		0x404
+#define DA(n)		(_DA + (n)*0x20)
+
+#define _CC		0x408
+#define CC(n)		(_CC + (n)*0x20)
+
+#define CC_SRCINC	(1 << 0)
+#define CC_DSTINC	(1 << 14)
+#define CC_SRCPRI	(1 << 8)
+#define CC_DSTPRI	(1 << 22)
+#define CC_SRCNS	(1 << 9)
+#define CC_DSTNS	(1 << 23)
+#define CC_SRCIA	(1 << 10)
+#define CC_DSTIA	(1 << 24)
+#define CC_SRCBRSTLEN_SHFT	4
+#define CC_DSTBRSTLEN_SHFT	18
+#define CC_SRCBRSTSIZE_SHFT	1
+#define CC_DSTBRSTSIZE_SHFT	15
+#define CC_SRCCCTRL_SHFT	11
+#define CC_SRCCCTRL_MASK	0x7
+#define CC_DSTCCTRL_SHFT	25
+#define CC_DRCCCTRL_MASK	0x7
+#define CC_SWAP_SHFT	28
+
+#define _LC0		0x40c
+#define LC0(n)		(_LC0 + (n)*0x20)
+
+#define _LC1		0x410
+#define LC1(n)		(_LC1 + (n)*0x20)
+
+#define DBGSTATUS	0xd00
+#define DBG_BUSY	(1 << 0)
+
+#define DBGCMD		0xd04
+#define DBGINST0	0xd08
+#define DBGINST1	0xd0c
+
+#define CR0		0xe00
+#define CR1		0xe04
+#define CR2		0xe08
+#define CR3		0xe0c
+#define CR4		0xe10
+#define CRD		0xe14
+
+#define PERIPH_ID	0xfe0
+#define PCELL_ID	0xff0
+
+#define CR0_PERIPH_REQ_SET	(1 << 0)
+#define CR0_BOOT_EN_SET		(1 << 1)
+#define CR0_BOOT_MAN_NS		(1 << 2)
+#define CR0_NUM_CHANS_SHIFT	4
+#define CR0_NUM_CHANS_MASK	0x7
+#define CR0_NUM_PERIPH_SHIFT	12
+#define CR0_NUM_PERIPH_MASK	0x1f
+#define CR0_NUM_EVENTS_SHIFT	17
+#define CR0_NUM_EVENTS_MASK	0x1f
+
+#define CR1_ICACHE_LEN_SHIFT	0
+#define CR1_ICACHE_LEN_MASK	0x7
+#define CR1_NUM_ICACHELINES_SHIFT	4
+#define CR1_NUM_ICACHELINES_MASK	0xf
+
+#define CRD_DATA_WIDTH_SHIFT	0
+#define CRD_DATA_WIDTH_MASK	0x7
+#define CRD_WR_CAP_SHIFT	4
+#define CRD_WR_CAP_MASK		0x7
+#define CRD_WR_Q_DEP_SHIFT	8
+#define CRD_WR_Q_DEP_MASK	0xf
+#define CRD_RD_CAP_SHIFT	12
+#define CRD_RD_CAP_MASK		0x7
+#define CRD_RD_Q_DEP_SHIFT	16
+#define CRD_RD_Q_DEP_MASK	0xf
+#define CRD_DATA_BUFF_SHIFT	20
+#define CRD_DATA_BUFF_MASK	0x3ff
+
+#define	PART		0x330
+#define DESIGNER	0x41
+#define REVISION	0x0
+#define INTEG_CFG	0x0
+#define PERIPH_ID_VAL	((PART << 0) | (DESIGNER << 12) \
+			  | (REVISION << 20) | (INTEG_CFG << 24))
+
+#define PCELL_ID_VAL	0xb105f00d
+
+#define PL330_STATE_STOPPED		(1 << 0)
+#define PL330_STATE_EXECUTING		(1 << 1)
+#define PL330_STATE_WFE			(1 << 2)
+#define PL330_STATE_FAULTING		(1 << 3)
+#define PL330_STATE_COMPLETING		(1 << 4)
+#define PL330_STATE_WFP			(1 << 5)
+#define PL330_STATE_KILLING		(1 << 6)
+#define PL330_STATE_FAULT_COMPLETING	(1 << 7)
+#define PL330_STATE_CACHEMISS		(1 << 8)
+#define PL330_STATE_UPDTPC		(1 << 9)
+#define PL330_STATE_ATBARRIER		(1 << 10)
+#define PL330_STATE_QUEUEBUSY		(1 << 11)
+#define PL330_STATE_INVALID		(1 << 15)
+
+#define PL330_STABLE_STATES (PL330_STATE_STOPPED | PL330_STATE_EXECUTING \
+				| PL330_STATE_WFE | PL330_STATE_FAULTING)
+
+#define CMD_DMAADDH	0x54
+#define CMD_DMAEND	0x00
+#define CMD_DMAFLUSHP	0x35
+#define CMD_DMAGO	0xa0
+#define CMD_DMALD	0x04
+#define CMD_DMALDP	0x25
+#define CMD_DMALP	0x20
+#define CMD_DMALPEND	0x28
+#define CMD_DMAKILL	0x01
+#define CMD_DMAMOV	0xbc
+#define CMD_DMANOP	0x18
+#define CMD_DMARMB	0x12
+#define CMD_DMASEV	0x34
+#define CMD_DMAST	0x08
+#define CMD_DMASTP	0x29
+#define CMD_DMASTZ	0x0c
+#define CMD_DMAWFE	0x36
+#define CMD_DMAWFP	0x30
+#define CMD_DMAWMB	0x13
+
+#define SZ_DMAADDH	3
+#define SZ_DMAEND	1
+#define SZ_DMAFLUSHP	2
+#define SZ_DMALD	1
+#define SZ_DMALDP	2
+#define SZ_DMALP	2
+#define SZ_DMALPEND	2
+#define SZ_DMAKILL	1
+#define SZ_DMAMOV	6
+#define SZ_DMANOP	1
+#define SZ_DMARMB	1
+#define SZ_DMASEV	2
+#define SZ_DMAST	1
+#define SZ_DMASTP	2
+#define SZ_DMASTZ	1
+#define SZ_DMAWFE	2
+#define SZ_DMAWFP	2
+#define SZ_DMAWMB	1
+#define SZ_DMAGO	6
+
+#define BRST_LEN(ccr)	((((ccr) >> CC_SRCBRSTLEN_SHFT) & 0xf) + 1)
+#define BRST_SIZE(ccr)	(1 << (((ccr) >> CC_SRCBRSTSIZE_SHFT) & 0x7))
+
+#define BYTE_TO_BURST(b, ccr)  ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr))
+#define BURST_TO_BYTE(c, ccr)  ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr))
+
+/*
+ * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req
+ * at 1byte/burst for P<->M and M<->M respectively.
+ * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req
+ * should be enough for P<->M and M<->M respectively.
+ */
+#define MCODE_BUFF_PER_REQ	256
+
+/*
+ * Mark a _pl330_req as free.
+ * We do it by writing DMAEND as the first instruction
+ * because no valid request is going to have DMAEND as
+ * its first instruction to execute.
+ */
+#define MARK_FREE(req)	do { \
+				_emit_END(0, (req)->mc_cpu); \
+				(req)->mc_len = 0; \
+			} while (0)
+
+/* If the _pl330_req is available to the client */
+#define IS_FREE(req)	(*((u8 *)((req)->mc_cpu)) == CMD_DMAEND)
+
+/* Use this _only_ to wait on transient states */
+#define UNTIL(t, s)	while (!(_state(t) & (s))) cpu_relax();
+
+#ifdef PL330_DEBUG_MCGEN
+static unsigned cmd_line;
+#define PL330_DBGCMD_DUMP(off, x...)	do { \
+						printk("%x:", cmd_line); \
+						printk(x); \
+						cmd_line += off; \
+					} while (0)
+#define PL330_DBGMC_START(addr)		(cmd_line = addr)
+#else
+#define PL330_DBGCMD_DUMP(off, x...)	do {} while (0)
+#define PL330_DBGMC_START(addr)		do {} while (0)
+#endif
+
+struct _xfer_spec {
+	u32 ccr;
+	struct pl330_req *r;
+	struct pl330_xfer *x;
+};
+
+enum dmamov_dst {
+	SAR = 0,
+	CCR,
+	DAR,
+};
+
+enum pl330_dst {
+	SRC = 0,
+	DST,
+};
+
+enum pl330_cond {
+	SINGLE,
+	BURST,
+	ALWAYS,
+};
+
+struct _pl330_req {
+	u32 mc_bus;
+	void *mc_cpu;
+	/* Number of bytes taken to setup MC for the req */
+	u32 mc_len;
+	struct pl330_req *r;
+	/* Hook to attach to DMAC's list of reqs with due callback */
+	struct list_head rqd;
+};
+
+/* ToBeDone for tasklet */
+struct _pl330_tbd {
+	bool reset_dmac;
+	bool reset_mngr;
+	u8 reset_chan;
+};
+
+/* A DMAC Thread */
+struct pl330_thread {
+	u8 id;
+	int ev;
+	/* If the channel is not yet acquired by any client */
+	bool free;
+	/* Parent DMAC */
+	struct pl330_dmac *dmac;
+	/* Only two at a time */
+	struct _pl330_req req[2];
+	/* Index of the last submitted request */
+	unsigned lstenq;
+};
+
+enum pl330_dmac_state {
+	UNINIT,
+	INIT,
+	DYING,
+};
+
+/* A DMAC */
+struct pl330_dmac {
+	spinlock_t		lock;
+	/* Holds list of reqs with due callbacks */
+	struct list_head	req_done;
+	/* Pointer to platform specific stuff */
+	struct pl330_info	*pinfo;
+	/* Maximum possible events/irqs */
+	int			events[32];
+	/* BUS address of MicroCode buffer */
+	u32			mcode_bus;
+	/* CPU address of MicroCode buffer */
+	void			*mcode_cpu;
+	/* List of all Channel threads */
+	struct pl330_thread	*channels;
+	/* Pointer to the MANAGER thread */
+	struct pl330_thread	*manager;
+	/* To handle bad news in interrupt */
+	struct tasklet_struct	tasks;
+	struct _pl330_tbd	dmac_tbd;
+	/* State of DMAC operation */
+	enum pl330_dmac_state	state;
+};
+
+static inline void _callback(struct pl330_req *r, enum pl330_op_err err)
+{
+	if (r && r->xfer_cb)
+		r->xfer_cb(r->token, err);
+}
+
+static inline bool _queue_empty(struct pl330_thread *thrd)
+{
+	return (IS_FREE(&thrd->req[0]) && IS_FREE(&thrd->req[1]))
+		? true : false;
+}
+
+static inline bool _queue_full(struct pl330_thread *thrd)
+{
+	return (IS_FREE(&thrd->req[0]) || IS_FREE(&thrd->req[1]))
+		? false : true;
+}
+
+static inline bool is_manager(struct pl330_thread *thrd)
+{
+	struct pl330_dmac *pl330 = thrd->dmac;
+
+	/* MANAGER is indexed at the end */
+	if (thrd->id == pl330->pinfo->pcfg.num_chan)
+		return true;
+	else
+		return false;
+}
+
+/* If manager of the thread is in Non-Secure mode */
+static inline bool _manager_ns(struct pl330_thread *thrd)
+{
+	struct pl330_dmac *pl330 = thrd->dmac;
+
+	return (pl330->pinfo->pcfg.mode & DMAC_MODE_NS) ? true : false;
+}
+
+static inline u32 get_id(struct pl330_info *pi, u32 off)
+{
+	void __iomem *regs = pi->base;
+	u32 id = 0;
+
+	id |= (readb(regs + off + 0x0) << 0);
+	id |= (readb(regs + off + 0x4) << 8);
+	id |= (readb(regs + off + 0x8) << 16);
+	id |= (readb(regs + off + 0xc) << 24);
+
+	return id;
+}
+
+static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[],
+		enum pl330_dst da, u16 val)
+{
+	if (dry_run)
+		return SZ_DMAADDH;
+
+	buf[0] = CMD_DMAADDH;
+	buf[0] |= (da << 1);
+	*((u16 *)&buf[1]) = val;
+
+	PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n",
+		da == 1 ? "DA" : "SA", val);
+
+	return SZ_DMAADDH;
+}
+
+static inline u32 _emit_END(unsigned dry_run, u8 buf[])
+{
+	if (dry_run)
+		return SZ_DMAEND;
+
+	buf[0] = CMD_DMAEND;
+
+	PL330_DBGCMD_DUMP(SZ_DMAEND, "\tDMAEND\n");
+
+	return SZ_DMAEND;
+}
+
+static inline u32 _emit_FLUSHP(unsigned dry_run, u8 buf[], u8 peri)
+{
+	if (dry_run)
+		return SZ_DMAFLUSHP;
+
+	buf[0] = CMD_DMAFLUSHP;
+
+	peri &= 0x1f;
+	peri <<= 3;
+	buf[1] = peri;
+
+	PL330_DBGCMD_DUMP(SZ_DMAFLUSHP, "\tDMAFLUSHP %u\n", peri >> 3);
+
+	return SZ_DMAFLUSHP;
+}
+
+static inline u32 _emit_LD(unsigned dry_run, u8 buf[],	enum pl330_cond cond)
+{
+	if (dry_run)
+		return SZ_DMALD;
+
+	buf[0] = CMD_DMALD;
+
+	if (cond == SINGLE)
+		buf[0] |= (0 << 1) | (1 << 0);
+	else if (cond == BURST)
+		buf[0] |= (1 << 1) | (1 << 0);
+
+	PL330_DBGCMD_DUMP(SZ_DMALD, "\tDMALD%c\n",
+		cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'));
+
+	return SZ_DMALD;
+}
+
+static inline u32 _emit_LDP(unsigned dry_run, u8 buf[],
+		enum pl330_cond cond, u8 peri)
+{
+	if (dry_run)
+		return SZ_DMALDP;
+
+	buf[0] = CMD_DMALDP;
+
+	if (cond == BURST)
+		buf[0] |= (1 << 1);
+
+	peri &= 0x1f;
+	peri <<= 3;
+	buf[1] = peri;
+
+	PL330_DBGCMD_DUMP(SZ_DMALDP, "\tDMALDP%c %u\n",
+		cond == SINGLE ? 'S' : 'B', peri >> 3);
+
+	return SZ_DMALDP;
+}
+
+static inline u32 _emit_LP(unsigned dry_run, u8 buf[],
+		unsigned loop, u8 cnt)
+{
+	if (dry_run)
+		return SZ_DMALP;
+
+	buf[0] = CMD_DMALP;
+
+	if (loop)
+		buf[0] |= (1 << 1);
+
+	cnt--; /* DMAC increments by 1 internally */
+	buf[1] = cnt;
+
+	PL330_DBGCMD_DUMP(SZ_DMALP, "\tDMALP_%c %u\n", loop ? '1' : '0', cnt);
+
+	return SZ_DMALP;
+}
+
+struct _arg_LPEND {
+	enum pl330_cond cond;
+	bool forever;
+	unsigned loop;
+	u8 bjump;
+};
+
+static inline u32 _emit_LPEND(unsigned dry_run, u8 buf[],
+		const struct _arg_LPEND *arg)
+{
+	enum pl330_cond cond = arg->cond;
+	bool forever = arg->forever;
+	unsigned loop = arg->loop;
+	u8 bjump = arg->bjump;
+
+	if (dry_run)
+		return SZ_DMALPEND;
+
+	buf[0] = CMD_DMALPEND;
+
+	if (loop)
+		buf[0] |= (1 << 2);
+
+	if (!forever)
+		buf[0] |= (1 << 4);
+
+	if (cond == SINGLE)
+		buf[0] |= (0 << 1) | (1 << 0);
+	else if (cond == BURST)
+		buf[0] |= (1 << 1) | (1 << 0);
+
+	buf[1] = bjump;
+
+	PL330_DBGCMD_DUMP(SZ_DMALPEND, "\tDMALP%s%c_%c bjmpto_%x\n",
+			forever ? "FE" : "END",
+			cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'),
+			loop ? '1' : '0',
+			bjump);
+
+	return SZ_DMALPEND;
+}
+
+static inline u32 _emit_KILL(unsigned dry_run, u8 buf[])
+{
+	if (dry_run)
+		return SZ_DMAKILL;
+
+	buf[0] = CMD_DMAKILL;
+
+	return SZ_DMAKILL;
+}
+
+static inline u32 _emit_MOV(unsigned dry_run, u8 buf[],
+		enum dmamov_dst dst, u32 val)
+{
+	if (dry_run)
+		return SZ_DMAMOV;
+
+	buf[0] = CMD_DMAMOV;
+	buf[1] = dst;
+	*((u32 *)&buf[2]) = val;
+
+	PL330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n",
+		dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val);
+
+	return SZ_DMAMOV;
+}
+
+static inline u32 _emit_NOP(unsigned dry_run, u8 buf[])
+{
+	if (dry_run)
+		return SZ_DMANOP;
+
+	buf[0] = CMD_DMANOP;
+
+	PL330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n");
+
+	return SZ_DMANOP;
+}
+
+static inline u32 _emit_RMB(unsigned dry_run, u8 buf[])
+{
+	if (dry_run)
+		return SZ_DMARMB;
+
+	buf[0] = CMD_DMARMB;
+
+	PL330_DBGCMD_DUMP(SZ_DMARMB, "\tDMARMB\n");
+
+	return SZ_DMARMB;
+}
+
+static inline u32 _emit_SEV(unsigned dry_run, u8 buf[], u8 ev)
+{
+	if (dry_run)
+		return SZ_DMASEV;
+
+	buf[0] = CMD_DMASEV;
+
+	ev &= 0x1f;
+	ev <<= 3;
+	buf[1] = ev;
+
+	PL330_DBGCMD_DUMP(SZ_DMASEV, "\tDMASEV %u\n", ev >> 3);
+
+	return SZ_DMASEV;
+}
+
+static inline u32 _emit_ST(unsigned dry_run, u8 buf[], enum pl330_cond cond)
+{
+	if (dry_run)
+		return SZ_DMAST;
+
+	buf[0] = CMD_DMAST;
+
+	if (cond == SINGLE)
+		buf[0] |= (0 << 1) | (1 << 0);
+	else if (cond == BURST)
+		buf[0] |= (1 << 1) | (1 << 0);
+
+	PL330_DBGCMD_DUMP(SZ_DMAST, "\tDMAST%c\n",
+		cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'));
+
+	return SZ_DMAST;
+}
+
+static inline u32 _emit_STP(unsigned dry_run, u8 buf[],
+		enum pl330_cond cond, u8 peri)
+{
+	if (dry_run)
+		return SZ_DMASTP;
+
+	buf[0] = CMD_DMASTP;
+
+	if (cond == BURST)
+		buf[0] |= (1 << 1);
+
+	peri &= 0x1f;
+	peri <<= 3;
+	buf[1] = peri;
+
+	PL330_DBGCMD_DUMP(SZ_DMASTP, "\tDMASTP%c %u\n",
+		cond == SINGLE ? 'S' : 'B', peri >> 3);
+
+	return SZ_DMASTP;
+}
+
+static inline u32 _emit_STZ(unsigned dry_run, u8 buf[])
+{
+	if (dry_run)
+		return SZ_DMASTZ;
+
+	buf[0] = CMD_DMASTZ;
+
+	PL330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n");
+
+	return SZ_DMASTZ;
+}
+
+static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev,
+		unsigned invalidate)
+{
+	if (dry_run)
+		return SZ_DMAWFE;
+
+	buf[0] = CMD_DMAWFE;
+
+	ev &= 0x1f;
+	ev <<= 3;
+	buf[1] = ev;
+
+	if (invalidate)
+		buf[1] |= (1 << 1);
+
+	PL330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n",
+		ev >> 3, invalidate ? ", I" : "");
+
+	return SZ_DMAWFE;
+}
+
+static inline u32 _emit_WFP(unsigned dry_run, u8 buf[],
+		enum pl330_cond cond, u8 peri)
+{
+	if (dry_run)
+		return SZ_DMAWFP;
+
+	buf[0] = CMD_DMAWFP;
+
+	if (cond == SINGLE)
+		buf[0] |= (0 << 1) | (0 << 0);
+	else if (cond == BURST)
+		buf[0] |= (1 << 1) | (0 << 0);
+	else
+		buf[0] |= (0 << 1) | (1 << 0);
+
+	peri &= 0x1f;
+	peri <<= 3;
+	buf[1] = peri;
+
+	PL330_DBGCMD_DUMP(SZ_DMAWFP, "\tDMAWFP%c %u\n",
+		cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'P'), peri >> 3);
+
+	return SZ_DMAWFP;
+}
+
+static inline u32 _emit_WMB(unsigned dry_run, u8 buf[])
+{
+	if (dry_run)
+		return SZ_DMAWMB;
+
+	buf[0] = CMD_DMAWMB;
+
+	PL330_DBGCMD_DUMP(SZ_DMAWMB, "\tDMAWMB\n");
+
+	return SZ_DMAWMB;
+}
+
+struct _arg_GO {
+	u8 chan;
+	u32 addr;
+	unsigned ns;
+};
+
+static inline u32 _emit_GO(unsigned dry_run, u8 buf[],
+		const struct _arg_GO *arg)
+{
+	u8 chan = arg->chan;
+	u32 addr = arg->addr;
+	unsigned ns = arg->ns;
+
+	if (dry_run)
+		return SZ_DMAGO;
+
+	buf[0] = CMD_DMAGO;
+	buf[0] |= (ns << 1);
+
+	buf[1] = chan & 0x7;
+
+	*((u32 *)&buf[2]) = addr;
+
+	return SZ_DMAGO;
+}
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
+/* Returns Time-Out */
+static bool _until_dmac_idle(struct pl330_thread *thrd)
+{
+	void __iomem *regs = thrd->dmac->pinfo->base;
+	unsigned long loops = msecs_to_loops(5);
+
+	do {
+		/* Until Manager is Idle */
+		if (!(readl(regs + DBGSTATUS) & DBG_BUSY))
+			break;
+
+		cpu_relax();
+	} while (--loops);
+
+	if (!loops)
+		return true;
+
+	return false;
+}
+
+static inline void _execute_DBGINSN(struct pl330_thread *thrd,
+		u8 insn[], bool as_manager)
+{
+	void __iomem *regs = thrd->dmac->pinfo->base;
+	u32 val;
+
+	val = (insn[0] << 16) | (insn[1] << 24);
+	if (!as_manager) {
+		val |= (1 << 0);
+		val |= (thrd->id << 8); /* Channel Number */
+	}
+	writel(val, regs + DBGINST0);
+
+	val = *((u32 *)&insn[2]);
+	writel(val, regs + DBGINST1);
+
+	/* If timed out due to halted state-machine */
+	if (_until_dmac_idle(thrd)) {
+		dev_err(thrd->dmac->pinfo->dev, "DMAC halted!\n");
+		return;
+	}
+
+	/* Get going */
+	writel(0, regs + DBGCMD);
+}
+
+static inline u32 _state(struct pl330_thread *thrd)
+{
+	void __iomem *regs = thrd->dmac->pinfo->base;
+	u32 val;
+
+	if (is_manager(thrd))
+		val = readl(regs + DS) & 0xf;
+	else
+		val = readl(regs + CS(thrd->id)) & 0xf;
+
+	switch (val) {
+	case DS_ST_STOP:
+		return PL330_STATE_STOPPED;
+	case DS_ST_EXEC:
+		return PL330_STATE_EXECUTING;
+	case DS_ST_CMISS:
+		return PL330_STATE_CACHEMISS;
+	case DS_ST_UPDTPC:
+		return PL330_STATE_UPDTPC;
+	case DS_ST_WFE:
+		return PL330_STATE_WFE;
+	case DS_ST_FAULT:
+		return PL330_STATE_FAULTING;
+	case DS_ST_ATBRR:
+		if (is_manager(thrd))
+			return PL330_STATE_INVALID;
+		else
+			return PL330_STATE_ATBARRIER;
+	case DS_ST_QBUSY:
+		if (is_manager(thrd))
+			return PL330_STATE_INVALID;
+		else
+			return PL330_STATE_QUEUEBUSY;
+	case DS_ST_WFP:
+		if (is_manager(thrd))
+			return PL330_STATE_INVALID;
+		else
+			return PL330_STATE_WFP;
+	case DS_ST_KILL:
+		if (is_manager(thrd))
+			return PL330_STATE_INVALID;
+		else
+			return PL330_STATE_KILLING;
+	case DS_ST_CMPLT:
+		if (is_manager(thrd))
+			return PL330_STATE_INVALID;
+		else
+			return PL330_STATE_COMPLETING;
+	case DS_ST_FLTCMP:
+		if (is_manager(thrd))
+			return PL330_STATE_INVALID;
+		else
+			return PL330_STATE_FAULT_COMPLETING;
+	default:
+		return PL330_STATE_INVALID;
+	}
+}
+
+/* If the request 'req' of thread 'thrd' is currently active */
+static inline bool _req_active(struct pl330_thread *thrd,
+		struct _pl330_req *req)
+{
+	void __iomem *regs = thrd->dmac->pinfo->base;
+	u32 buf = req->mc_bus, pc = readl(regs + CPC(thrd->id));
+
+	if (IS_FREE(req))
+		return false;
+
+	return (pc >= buf && pc <= buf + req->mc_len) ? true : false;
+}
+
+/* Returns 0 if the thread is inactive, ID of active req + 1 otherwise */
+static inline unsigned _thrd_active(struct pl330_thread *thrd)
+{
+	if (_req_active(thrd, &thrd->req[0]))
+		return 1; /* First req active */
+
+	if (_req_active(thrd, &thrd->req[1]))
+		return 2; /* Second req active */
+
+	return 0;
+}
+
+static void _stop(struct pl330_thread *thrd)
+{
+	void __iomem *regs = thrd->dmac->pinfo->base;
+	u8 insn[6] = {0, 0, 0, 0, 0, 0};
+
+	if (_state(thrd) == PL330_STATE_FAULT_COMPLETING)
+		UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
+
+	/* Return if nothing needs to be done */
+	if (_state(thrd) == PL330_STATE_COMPLETING
+		  || _state(thrd) == PL330_STATE_KILLING
+		  || _state(thrd) == PL330_STATE_STOPPED)
+		return;
+
+	_emit_KILL(0, insn);
+
+	/* Stop generating interrupts for SEV */
+	writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN);
+
+	_execute_DBGINSN(thrd, insn, is_manager(thrd));
+}
+
+/* Start doing req 'idx' of thread 'thrd' */
+static bool _trigger(struct pl330_thread *thrd)
+{
+	void __iomem *regs = thrd->dmac->pinfo->base;
+	struct _pl330_req *req;
+	struct pl330_req *r;
+	struct _arg_GO go;
+	unsigned ns;
+	u8 insn[6] = {0, 0, 0, 0, 0, 0};
+
+	/* Return if already ACTIVE */
+	if (_state(thrd) != PL330_STATE_STOPPED)
+		return true;
+
+	if (!IS_FREE(&thrd->req[1 - thrd->lstenq]))
+		req = &thrd->req[1 - thrd->lstenq];
+	else if (!IS_FREE(&thrd->req[thrd->lstenq]))
+		req = &thrd->req[thrd->lstenq];
+	else
+		req = NULL;
+
+	/* Return if no request */
+	if (!req || !req->r)
+		return true;
+
+	r = req->r;
+
+	if (r->cfg)
+		ns = r->cfg->nonsecure ? 1 : 0;
+	else if (readl(regs + CS(thrd->id)) & CS_CNS)
+		ns = 1;
+	else
+		ns = 0;
+
+	/* See 'Abort Sources' point-4 at Page 2-25 */
+	if (_manager_ns(thrd) && !ns)
+		dev_info(thrd->dmac->pinfo->dev, "%s:%d Recipe for ABORT!\n",
+			__func__, __LINE__);
+
+	go.chan = thrd->id;
+	go.addr = req->mc_bus;
+	go.ns = ns;
+	_emit_GO(0, insn, &go);
+
+	/* Set to generate interrupts for SEV */
+	writel(readl(regs + INTEN) | (1 << thrd->ev), regs + INTEN);
+
+	/* Only manager can execute GO */
+	_execute_DBGINSN(thrd, insn, true);
+
+	return true;
+}
+
+static bool _start(struct pl330_thread *thrd)
+{
+	switch (_state(thrd)) {
+	case PL330_STATE_FAULT_COMPLETING:
+		UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
+
+		if (_state(thrd) == PL330_STATE_KILLING)
+			UNTIL(thrd, PL330_STATE_STOPPED)
+
+	case PL330_STATE_FAULTING:
+		_stop(thrd);
+
+	case PL330_STATE_KILLING:
+	case PL330_STATE_COMPLETING:
+		UNTIL(thrd, PL330_STATE_STOPPED)
+
+	case PL330_STATE_STOPPED:
+		return _trigger(thrd);
+
+	case PL330_STATE_WFP:
+	case PL330_STATE_QUEUEBUSY:
+	case PL330_STATE_ATBARRIER:
+	case PL330_STATE_UPDTPC:
+	case PL330_STATE_CACHEMISS:
+	case PL330_STATE_EXECUTING:
+		return true;
+
+	case PL330_STATE_WFE: /* For RESUME, nothing yet */
+	default:
+		return false;
+	}
+}
+
+static inline int _ldst_memtomem(unsigned dry_run, u8 buf[],
+		const struct _xfer_spec *pxs, int cyc)
+{
+	int off = 0;
+
+	while (cyc--) {
+		off += _emit_LD(dry_run, &buf[off], ALWAYS);
+		off += _emit_RMB(dry_run, &buf[off]);
+		off += _emit_ST(dry_run, &buf[off], ALWAYS);
+		off += _emit_WMB(dry_run, &buf[off]);
+	}
+
+	return off;
+}
+
+static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
+		const struct _xfer_spec *pxs, int cyc)
+{
+	int off = 0;
+
+	while (cyc--) {
+		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+		off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+		off += _emit_ST(dry_run, &buf[off], ALWAYS);
+		off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
+	}
+
+	return off;
+}
+
+static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
+		const struct _xfer_spec *pxs, int cyc)
+{
+	int off = 0;
+
+	while (cyc--) {
+		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+		off += _emit_LD(dry_run, &buf[off], ALWAYS);
+		off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+		off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
+	}
+
+	return off;
+}
+
+static int _bursts(unsigned dry_run, u8 buf[],
+		const struct _xfer_spec *pxs, int cyc)
+{
+	int off = 0;
+
+	switch (pxs->r->rqtype) {
+	case MEMTODEV:
+		off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc);
+		break;
+	case DEVTOMEM:
+		off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc);
+		break;
+	case MEMTOMEM:
+		off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc);
+		break;
+	default:
+		off += 0x40000000; /* Scare off the Client */
+		break;
+	}
+
+	return off;
+}
+
+/* Returns bytes consumed and updates bursts */
+static inline int _loop(unsigned dry_run, u8 buf[],
+		unsigned long *bursts, const struct _xfer_spec *pxs)
+{
+	int cyc, cycmax, szlp, szlpend, szbrst, off;
+	unsigned lcnt0, lcnt1, ljmp0, ljmp1;
+	struct _arg_LPEND lpend;
+
+	/* Max iterations possibile in DMALP is 256 */
+	if (*bursts >= 256*256) {
+		lcnt1 = 256;
+		lcnt0 = 256;
+		cyc = *bursts / lcnt1 / lcnt0;
+	} else if (*bursts > 256) {
+		lcnt1 = 256;
+		lcnt0 = *bursts / lcnt1;
+		cyc = 1;
+	} else {
+		lcnt1 = *bursts;
+		lcnt0 = 0;
+		cyc = 1;
+	}
+
+	szlp = _emit_LP(1, buf, 0, 0);
+	szbrst = _bursts(1, buf, pxs, 1);
+
+	lpend.cond = ALWAYS;
+	lpend.forever = false;
+	lpend.loop = 0;
+	lpend.bjump = 0;
+	szlpend = _emit_LPEND(1, buf, &lpend);
+
+	if (lcnt0) {
+		szlp *= 2;
+		szlpend *= 2;
+	}
+
+	/*
+	 * Max bursts that we can unroll due to limit on the
+	 * size of backward jump that can be encoded in DMALPEND
+	 * which is 8-bits and hence 255
+	 */
+	cycmax = (255 - (szlp + szlpend)) / szbrst;
+
+	cyc = (cycmax < cyc) ? cycmax : cyc;
+
+	off = 0;
+
+	if (lcnt0) {
+		off += _emit_LP(dry_run, &buf[off], 0, lcnt0);
+		ljmp0 = off;
+	}
+
+	off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
+	ljmp1 = off;
+
+	off += _bursts(dry_run, &buf[off], pxs, cyc);
+
+	lpend.cond = ALWAYS;
+	lpend.forever = false;
+	lpend.loop = 1;
+	lpend.bjump = off - ljmp1;
+	off += _emit_LPEND(dry_run, &buf[off], &lpend);
+
+	if (lcnt0) {
+		lpend.cond = ALWAYS;
+		lpend.forever = false;
+		lpend.loop = 0;
+		lpend.bjump = off - ljmp0;
+		off += _emit_LPEND(dry_run, &buf[off], &lpend);
+	}
+
+	*bursts = lcnt1 * cyc;
+	if (lcnt0)
+		*bursts *= lcnt0;
+
+	return off;
+}
+
+static inline int _setup_loops(unsigned dry_run, u8 buf[],
+		const struct _xfer_spec *pxs)
+{
+	struct pl330_xfer *x = pxs->x;
+	u32 ccr = pxs->ccr;
+	unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr);
+	int off = 0;
+
+	while (bursts) {
+		c = bursts;
+		off += _loop(dry_run, &buf[off], &c, pxs);
+		bursts -= c;
+	}
+
+	return off;
+}
+
+static inline int _setup_xfer(unsigned dry_run, u8 buf[],
+		const struct _xfer_spec *pxs)
+{
+	struct pl330_xfer *x = pxs->x;
+	int off = 0;
+
+	/* DMAMOV SAR, x->src_addr */
+	off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr);
+	/* DMAMOV DAR, x->dst_addr */
+	off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
+
+	/* Setup Loop(s) */
+	off += _setup_loops(dry_run, &buf[off], pxs);
+
+	return off;
+}
+
+/*
+ * A req is a sequence of one or more xfer units.
+ * Returns the number of bytes taken to setup the MC for the req.
+ */
+static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
+		unsigned index, struct _xfer_spec *pxs)
+{
+	struct _pl330_req *req = &thrd->req[index];
+	struct pl330_xfer *x;
+	u8 *buf = req->mc_cpu;
+	int off = 0;
+
+	PL330_DBGMC_START(req->mc_bus);
+
+	/* DMAMOV CCR, ccr */
+	off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
+
+	x = pxs->r->x;
+	do {
+		/* Error if xfer length is not aligned at burst size */
+		if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
+			return -EINVAL;
+
+		pxs->x = x;
+		off += _setup_xfer(dry_run, &buf[off], pxs);
+
+		x = x->next;
+	} while (x);
+
+	/* DMASEV peripheral/event */
+	off += _emit_SEV(dry_run, &buf[off], thrd->ev);
+	/* DMAEND */
+	off += _emit_END(dry_run, &buf[off]);
+
+	return off;
+}
+
+static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc)
+{
+	u32 ccr = 0;
+
+	if (rqc->src_inc)
+		ccr |= CC_SRCINC;
+
+	if (rqc->dst_inc)
+		ccr |= CC_DSTINC;
+
+	/* We set same protection levels for Src and DST for now */
+	if (rqc->privileged)
+		ccr |= CC_SRCPRI | CC_DSTPRI;
+	if (rqc->nonsecure)
+		ccr |= CC_SRCNS | CC_DSTNS;
+	if (rqc->insnaccess)
+		ccr |= CC_SRCIA | CC_DSTIA;
+
+	ccr |= (((rqc->brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT);
+	ccr |= (((rqc->brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT);
+
+	ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT);
+	ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT);
+
+	ccr |= (rqc->dcctl << CC_SRCCCTRL_SHFT);
+	ccr |= (rqc->scctl << CC_DSTCCTRL_SHFT);
+
+	ccr |= (rqc->swap << CC_SWAP_SHFT);
+
+	return ccr;
+}
+
+static inline bool _is_valid(u32 ccr)
+{
+	enum pl330_dstcachectrl dcctl;
+	enum pl330_srccachectrl scctl;
+
+	dcctl = (ccr >> CC_DSTCCTRL_SHFT) & CC_DRCCCTRL_MASK;
+	scctl = (ccr >> CC_SRCCCTRL_SHFT) & CC_SRCCCTRL_MASK;
+
+	if (dcctl == DINVALID1 || dcctl == DINVALID2
+			|| scctl == SINVALID1 || scctl == SINVALID2)
+		return false;
+	else
+		return true;
+}
+
+/*
+ * Submit a list of xfers after which the client wants notification.
+ * Client is not notified after each xfer unit, just once after all
+ * xfer units are done or some error occurs.
+ */
+int pl330_submit_req(void *ch_id, struct pl330_req *r)
+{
+	struct pl330_thread *thrd = ch_id;
+	struct pl330_dmac *pl330;
+	struct pl330_info *pi;
+	struct _xfer_spec xs;
+	unsigned long flags;
+	void __iomem *regs;
+	unsigned idx;
+	u32 ccr;
+	int ret = 0;
+
+	/* No Req or Unacquired Channel or DMAC */
+	if (!r || !thrd || thrd->free)
+		return -EINVAL;
+
+	pl330 = thrd->dmac;
+	pi = pl330->pinfo;
+	regs = pi->base;
+
+	if (pl330->state == DYING
+		|| pl330->dmac_tbd.reset_chan & (1 << thrd->id)) {
+		dev_info(thrd->dmac->pinfo->dev, "%s:%d\n",
+			__func__, __LINE__);
+		return -EAGAIN;
+	}
+
+	/* If request for non-existing peripheral */
+	if (r->rqtype != MEMTOMEM && r->peri >= pi->pcfg.num_peri) {
+		dev_info(thrd->dmac->pinfo->dev,
+				"%s:%d Invalid peripheral(%u)!\n",
+				__func__, __LINE__, r->peri);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&pl330->lock, flags);
+
+	if (_queue_full(thrd)) {
+		ret = -EAGAIN;
+		goto xfer_exit;
+	}
+
+	/* Prefer Secure Channel */
+	if (!_manager_ns(thrd))
+		r->cfg->nonsecure = 0;
+	else
+		r->cfg->nonsecure = 1;
+
+	/* Use last settings, if not provided */
+	if (r->cfg)
+		ccr = _prepare_ccr(r->cfg);
+	else
+		ccr = readl(regs + CC(thrd->id));
+
+	/* If this req doesn't have valid xfer settings */
+	if (!_is_valid(ccr)) {
+		ret = -EINVAL;
+		dev_info(thrd->dmac->pinfo->dev, "%s:%d Invalid CCR(%x)!\n",
+			__func__, __LINE__, ccr);
+		goto xfer_exit;
+	}
+
+	idx = IS_FREE(&thrd->req[0]) ? 0 : 1;
+
+	xs.ccr = ccr;
+	xs.r = r;
+
+	/* First dry run to check if req is acceptable */
+	ret = _setup_req(1, thrd, idx, &xs);
+	if (ret < 0)
+		goto xfer_exit;
+
+	if (ret > pi->mcbufsz / 2) {
+		dev_info(thrd->dmac->pinfo->dev,
+			"%s:%d Trying increasing mcbufsz\n",
+				__func__, __LINE__);
+		ret = -ENOMEM;
+		goto xfer_exit;
+	}
+
+	/* Hook the request */
+	thrd->lstenq = idx;
+	thrd->req[idx].mc_len = _setup_req(0, thrd, idx, &xs);
+	thrd->req[idx].r = r;
+
+	ret = 0;
+
+xfer_exit:
+	spin_unlock_irqrestore(&pl330->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(pl330_submit_req);
+
+static void pl330_dotask(unsigned long data)
+{
+	struct pl330_dmac *pl330 = (struct pl330_dmac *) data;
+	struct pl330_info *pi = pl330->pinfo;
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&pl330->lock, flags);
+
+	/* The DMAC itself gone nuts */
+	if (pl330->dmac_tbd.reset_dmac) {
+		pl330->state = DYING;
+		/* Reset the manager too */
+		pl330->dmac_tbd.reset_mngr = true;
+		/* Clear the reset flag */
+		pl330->dmac_tbd.reset_dmac = false;
+	}
+
+	if (pl330->dmac_tbd.reset_mngr) {
+		_stop(pl330->manager);
+		/* Reset all channels */
+		pl330->dmac_tbd.reset_chan = (1 << pi->pcfg.num_chan) - 1;
+		/* Clear the reset flag */
+		pl330->dmac_tbd.reset_mngr = false;
+	}
+
+	for (i = 0; i < pi->pcfg.num_chan; i++) {
+
+		if (pl330->dmac_tbd.reset_chan & (1 << i)) {
+			struct pl330_thread *thrd = &pl330->channels[i];
+			void __iomem *regs = pi->base;
+			enum pl330_op_err err;
+
+			_stop(thrd);
+
+			if (readl(regs + FSC) & (1 << thrd->id))
+				err = PL330_ERR_FAIL;
+			else
+				err = PL330_ERR_ABORT;
+
+			spin_unlock_irqrestore(&pl330->lock, flags);
+
+			_callback(thrd->req[1 - thrd->lstenq].r, err);
+			_callback(thrd->req[thrd->lstenq].r, err);
+
+			spin_lock_irqsave(&pl330->lock, flags);
+
+			thrd->req[0].r = NULL;
+			thrd->req[1].r = NULL;
+			MARK_FREE(&thrd->req[0]);
+			MARK_FREE(&thrd->req[1]);
+
+			/* Clear the reset flag */
+			pl330->dmac_tbd.reset_chan &= ~(1 << i);
+		}
+	}
+
+	spin_unlock_irqrestore(&pl330->lock, flags);
+
+	return;
+}
+
+/* Returns 1 if state was updated, 0 otherwise */
+int pl330_update(const struct pl330_info *pi)
+{
+	struct _pl330_req *rqdone;
+	struct pl330_dmac *pl330;
+	unsigned long flags;
+	void __iomem *regs;
+	u32 val;
+	int id, ev, ret = 0;
+
+	if (!pi || !pi->pl330_data)
+		return 0;
+
+	regs = pi->base;
+	pl330 = pi->pl330_data;
+
+	spin_lock_irqsave(&pl330->lock, flags);
+
+	val = readl(regs + FSM) & 0x1;
+	if (val)
+		pl330->dmac_tbd.reset_mngr = true;
+	else
+		pl330->dmac_tbd.reset_mngr = false;
+
+	val = readl(regs + FSC) & ((1 << pi->pcfg.num_chan) - 1);
+	pl330->dmac_tbd.reset_chan |= val;
+	if (val) {
+		int i = 0;
+		while (i < pi->pcfg.num_chan) {
+			if (val & (1 << i)) {
+				dev_info(pi->dev,
+					"Reset Channel-%d\t CS-%x FTC-%x\n",
+						i, readl(regs + CS(i)),
+						readl(regs + FTC(i)));
+				_stop(&pl330->channels[i]);
+			}
+			i++;
+		}
+	}
+
+	/* Check which event happened i.e, thread notified */
+	val = readl(regs + ES);
+	if (pi->pcfg.num_events < 32
+			&& val & ~((1 << pi->pcfg.num_events) - 1)) {
+		pl330->dmac_tbd.reset_dmac = true;
+		dev_err(pi->dev, "%s:%d Unexpected!\n", __func__, __LINE__);
+		ret = 1;
+		goto updt_exit;
+	}
+
+	for (ev = 0; ev < pi->pcfg.num_events; ev++) {
+		if (val & (1 << ev)) { /* Event occured */
+			struct pl330_thread *thrd;
+			u32 inten = readl(regs + INTEN);
+			int active;
+
+			/* Clear the event */
+			if (inten & (1 << ev))
+				writel(1 << ev, regs + INTCLR);
+
+			ret = 1;
+
+			id = pl330->events[ev];
+
+			thrd = &pl330->channels[id];
+
+			active = _thrd_active(thrd);
+			if (!active) /* Aborted */
+				continue;
+
+			active -= 1;
+
+			rqdone = &thrd->req[active];
+			MARK_FREE(rqdone);
+
+			/* Get going again ASAP */
+			_start(thrd);
+
+			/* For now, just make a list of callbacks to be done */
+			list_add_tail(&rqdone->rqd, &pl330->req_done);
+		}
+	}
+
+	/* Now that we are in no hurry, do the callbacks */
+	while (!list_empty(&pl330->req_done)) {
+		rqdone = container_of(pl330->req_done.next,
+					struct _pl330_req, rqd);
+
+		list_del_init(&rqdone->rqd);
+
+		spin_unlock_irqrestore(&pl330->lock, flags);
+		_callback(rqdone->r, PL330_ERR_NONE);
+		spin_lock_irqsave(&pl330->lock, flags);
+	}
+
+updt_exit:
+	spin_unlock_irqrestore(&pl330->lock, flags);
+
+	if (pl330->dmac_tbd.reset_dmac
+			|| pl330->dmac_tbd.reset_mngr
+			|| pl330->dmac_tbd.reset_chan) {
+		ret = 1;
+		tasklet_schedule(&pl330->tasks);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(pl330_update);
+
+int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op)
+{
+	struct pl330_thread *thrd = ch_id;
+	struct pl330_dmac *pl330;
+	unsigned long flags;
+	int ret = 0, active;
+
+	if (!thrd || thrd->free || thrd->dmac->state == DYING)
+		return -EINVAL;
+
+	pl330 = thrd->dmac;
+
+	spin_lock_irqsave(&pl330->lock, flags);
+
+	switch (op) {
+	case PL330_OP_FLUSH:
+		/* Make sure the channel is stopped */
+		_stop(thrd);
+
+		thrd->req[0].r = NULL;
+		thrd->req[1].r = NULL;
+		MARK_FREE(&thrd->req[0]);
+		MARK_FREE(&thrd->req[1]);
+		break;
+
+	case PL330_OP_ABORT:
+		active = _thrd_active(thrd);
+
+		/* Make sure the channel is stopped */
+		_stop(thrd);
+
+		/* ABORT is only for the active req */
+		if (!active)
+			break;
+
+		active--;
+
+		thrd->req[active].r = NULL;
+		MARK_FREE(&thrd->req[active]);
+
+		/* Start the next */
+	case PL330_OP_START:
+		if (!_start(thrd))
+			ret = -EIO;
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	spin_unlock_irqrestore(&pl330->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(pl330_chan_ctrl);
+
+int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus)
+{
+	struct pl330_thread *thrd = ch_id;
+	struct pl330_dmac *pl330;
+	struct pl330_info *pi;
+	void __iomem *regs;
+	int active;
+	u32 val;
+
+	if (!pstatus || !thrd || thrd->free)
+		return -EINVAL;
+
+	pl330 = thrd->dmac;
+	pi = pl330->pinfo;
+	regs = pi->base;
+
+	/* The client should remove the DMAC and add again */
+	if (pl330->state == DYING)
+		pstatus->dmac_halted = true;
+	else
+		pstatus->dmac_halted = false;
+
+	val = readl(regs + FSC);
+	if (val & (1 << thrd->id))
+		pstatus->faulting = true;
+	else
+		pstatus->faulting = false;
+
+	active = _thrd_active(thrd);
+
+	if (!active) {
+		/* Indicate that the thread is not running */
+		pstatus->top_req = NULL;
+		pstatus->wait_req = NULL;
+	} else {
+		active--;
+		pstatus->top_req = thrd->req[active].r;
+		pstatus->wait_req = !IS_FREE(&thrd->req[1 - active])
+					? thrd->req[1 - active].r : NULL;
+	}
+
+	pstatus->src_addr = readl(regs + SA(thrd->id));
+	pstatus->dst_addr = readl(regs + DA(thrd->id));
+
+	return 0;
+}
+EXPORT_SYMBOL(pl330_chan_status);
+
+/* Reserve an event */
+static inline int _alloc_event(struct pl330_thread *thrd)
+{
+	struct pl330_dmac *pl330 = thrd->dmac;
+	struct pl330_info *pi = pl330->pinfo;
+	int ev;
+
+	for (ev = 0; ev < pi->pcfg.num_events; ev++)
+		if (pl330->events[ev] == -1) {
+			pl330->events[ev] = thrd->id;
+			return ev;
+		}
+
+	return -1;
+}
+
+/* Upon success, returns IdentityToken for the
+ * allocated channel, NULL otherwise.
+ */
+void *pl330_request_channel(const struct pl330_info *pi)
+{
+	struct pl330_thread *thrd = NULL;
+	struct pl330_dmac *pl330;
+	unsigned long flags;
+	int chans, i;
+
+	if (!pi || !pi->pl330_data)
+		return NULL;
+
+	pl330 = pi->pl330_data;
+
+	if (pl330->state == DYING)
+		return NULL;
+
+	chans = pi->pcfg.num_chan;
+
+	spin_lock_irqsave(&pl330->lock, flags);
+
+	for (i = 0; i < chans; i++) {
+		thrd = &pl330->channels[i];
+		if (thrd->free) {
+			thrd->ev = _alloc_event(thrd);
+			if (thrd->ev >= 0) {
+				thrd->free = false;
+				thrd->lstenq = 1;
+				thrd->req[0].r = NULL;
+				MARK_FREE(&thrd->req[0]);
+				thrd->req[1].r = NULL;
+				MARK_FREE(&thrd->req[1]);
+				break;
+			}
+		}
+		thrd = NULL;
+	}
+
+	spin_unlock_irqrestore(&pl330->lock, flags);
+
+	return thrd;
+}
+EXPORT_SYMBOL(pl330_request_channel);
+
+/* Release an event */
+static inline void _free_event(struct pl330_thread *thrd, int ev)
+{
+	struct pl330_dmac *pl330 = thrd->dmac;
+	struct pl330_info *pi = pl330->pinfo;
+
+	/* If the event is valid and was held by the thread */
+	if (ev >= 0 && ev < pi->pcfg.num_events
+			&& pl330->events[ev] == thrd->id)
+		pl330->events[ev] = -1;
+}
+
+void pl330_release_channel(void *ch_id)
+{
+	struct pl330_thread *thrd = ch_id;
+	struct pl330_dmac *pl330;
+	unsigned long flags;
+
+	if (!thrd || thrd->free)
+		return;
+
+	_stop(thrd);
+
+	_callback(thrd->req[1 - thrd->lstenq].r, PL330_ERR_ABORT);
+	_callback(thrd->req[thrd->lstenq].r, PL330_ERR_ABORT);
+
+	pl330 = thrd->dmac;
+
+	spin_lock_irqsave(&pl330->lock, flags);
+	_free_event(thrd, thrd->ev);
+	thrd->free = true;
+	spin_unlock_irqrestore(&pl330->lock, flags);
+}
+EXPORT_SYMBOL(pl330_release_channel);
+
+/* Initialize the structure for PL330 configuration, that can be used
+ * by the client driver the make best use of the DMAC
+ */
+static void read_dmac_config(struct pl330_info *pi)
+{
+	void __iomem *regs = pi->base;
+	u32 val;
+
+	val = readl(regs + CRD) >> CRD_DATA_WIDTH_SHIFT;
+	val &= CRD_DATA_WIDTH_MASK;
+	pi->pcfg.data_bus_width = 8 * (1 << val);
+
+	val = readl(regs + CRD) >> CRD_DATA_BUFF_SHIFT;
+	val &= CRD_DATA_BUFF_MASK;
+	pi->pcfg.data_buf_dep = val + 1;
+
+	val = readl(regs + CR0) >> CR0_NUM_CHANS_SHIFT;
+	val &= CR0_NUM_CHANS_MASK;
+	val += 1;
+	pi->pcfg.num_chan = val;
+
+	val = readl(regs + CR0);
+	if (val & CR0_PERIPH_REQ_SET) {
+		val = (val >> CR0_NUM_PERIPH_SHIFT) & CR0_NUM_PERIPH_MASK;
+		val += 1;
+		pi->pcfg.num_peri = val;
+		pi->pcfg.peri_ns = readl(regs + CR4);
+	} else {
+		pi->pcfg.num_peri = 0;
+	}
+
+	val = readl(regs + CR0);
+	if (val & CR0_BOOT_MAN_NS)
+		pi->pcfg.mode |= DMAC_MODE_NS;
+	else
+		pi->pcfg.mode &= ~DMAC_MODE_NS;
+
+	val = readl(regs + CR0) >> CR0_NUM_EVENTS_SHIFT;
+	val &= CR0_NUM_EVENTS_MASK;
+	val += 1;
+	pi->pcfg.num_events = val;
+
+	pi->pcfg.irq_ns = readl(regs + CR3);
+
+	pi->pcfg.periph_id = get_id(pi, PERIPH_ID);
+	pi->pcfg.pcell_id = get_id(pi, PCELL_ID);
+}
+
+static inline void _reset_thread(struct pl330_thread *thrd)
+{
+	struct pl330_dmac *pl330 = thrd->dmac;
+	struct pl330_info *pi = pl330->pinfo;
+
+	thrd->req[0].mc_cpu = pl330->mcode_cpu
+				+ (thrd->id * pi->mcbufsz);
+	thrd->req[0].mc_bus = pl330->mcode_bus
+				+ (thrd->id * pi->mcbufsz);
+	thrd->req[0].r = NULL;
+	MARK_FREE(&thrd->req[0]);
+
+	thrd->req[1].mc_cpu = thrd->req[0].mc_cpu
+				+ pi->mcbufsz / 2;
+	thrd->req[1].mc_bus = thrd->req[0].mc_bus
+				+ pi->mcbufsz / 2;
+	thrd->req[1].r = NULL;
+	MARK_FREE(&thrd->req[1]);
+}
+
+static int dmac_alloc_threads(struct pl330_dmac *pl330)
+{
+	struct pl330_info *pi = pl330->pinfo;
+	int chans = pi->pcfg.num_chan;
+	struct pl330_thread *thrd;
+	int i;
+
+	/* Allocate 1 Manager and 'chans' Channel threads */
+	pl330->channels = kzalloc((1 + chans) * sizeof(*thrd),
+					GFP_KERNEL);
+	if (!pl330->channels)
+		return -ENOMEM;
+
+	/* Init Channel threads */
+	for (i = 0; i < chans; i++) {
+		thrd = &pl330->channels[i];
+		thrd->id = i;
+		thrd->dmac = pl330;
+		_reset_thread(thrd);
+		thrd->free = true;
+	}
+
+	/* MANAGER is indexed at the end */
+	thrd = &pl330->channels[chans];
+	thrd->id = chans;
+	thrd->dmac = pl330;
+	thrd->free = false;
+	pl330->manager = thrd;
+
+	return 0;
+}
+
+static int dmac_alloc_resources(struct pl330_dmac *pl330)
+{
+	struct pl330_info *pi = pl330->pinfo;
+	int chans = pi->pcfg.num_chan;
+	int ret;
+
+	/*
+	 * Alloc MicroCode buffer for 'chans' Channel threads.
+	 * A channel's buffer offset is (Channel_Id * MCODE_BUFF_PERCHAN)
+	 */
+	pl330->mcode_cpu = dma_alloc_coherent(pi->dev,
+				chans * pi->mcbufsz,
+				&pl330->mcode_bus, GFP_KERNEL);
+	if (!pl330->mcode_cpu) {
+		dev_err(pi->dev, "%s:%d Can't allocate memory!\n",
+			__func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	ret = dmac_alloc_threads(pl330);
+	if (ret) {
+		dev_err(pi->dev, "%s:%d Can't to create channels for DMAC!\n",
+			__func__, __LINE__);
+		dma_free_coherent(pi->dev,
+				chans * pi->mcbufsz,
+				pl330->mcode_cpu, pl330->mcode_bus);
+		return ret;
+	}
+
+	return 0;
+}
+
+int pl330_add(struct pl330_info *pi)
+{
+	struct pl330_dmac *pl330;
+	void __iomem *regs;
+	int i, ret;
+
+	if (!pi || !pi->dev)
+		return -EINVAL;
+
+	/* If already added */
+	if (pi->pl330_data)
+		return -EINVAL;
+
+	/*
+	 * If the SoC can perform reset on the DMAC, then do it
+	 * before reading its configuration.
+	 */
+	if (pi->dmac_reset)
+		pi->dmac_reset(pi);
+
+	regs = pi->base;
+
+	/* Check if we can handle this DMAC */
+	if (get_id(pi, PERIPH_ID) != PERIPH_ID_VAL
+	   || get_id(pi, PCELL_ID) != PCELL_ID_VAL) {
+		dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n",
+			readl(regs + PERIPH_ID), readl(regs + PCELL_ID));
+		return -EINVAL;
+	}
+
+	/* Read the configuration of the DMAC */
+	read_dmac_config(pi);
+
+	if (pi->pcfg.num_events == 0) {
+		dev_err(pi->dev, "%s:%d Can't work without events!\n",
+			__func__, __LINE__);
+		return -EINVAL;
+	}
+
+	pl330 = kzalloc(sizeof(*pl330), GFP_KERNEL);
+	if (!pl330) {
+		dev_err(pi->dev, "%s:%d Can't allocate memory!\n",
+			__func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	/* Assign the info structure and private data */
+	pl330->pinfo = pi;
+	pi->pl330_data = pl330;
+
+	spin_lock_init(&pl330->lock);
+
+	INIT_LIST_HEAD(&pl330->req_done);
+
+	/* Use default MC buffer size if not provided */
+	if (!pi->mcbufsz)
+		pi->mcbufsz = MCODE_BUFF_PER_REQ * 2;
+
+	/* Mark all events as free */
+	for (i = 0; i < pi->pcfg.num_events; i++)
+		pl330->events[i] = -1;
+
+	/* Allocate resources needed by the DMAC */
+	ret = dmac_alloc_resources(pl330);
+	if (ret) {
+		dev_err(pi->dev, "Unable to create channels for DMAC\n");
+		kfree(pl330);
+		return ret;
+	}
+
+	tasklet_init(&pl330->tasks, pl330_dotask, (unsigned long) pl330);
+
+	pl330->state = INIT;
+
+	return 0;
+}
+EXPORT_SYMBOL(pl330_add);
+
+static int dmac_free_threads(struct pl330_dmac *pl330)
+{
+	struct pl330_info *pi = pl330->pinfo;
+	int chans = pi->pcfg.num_chan;
+	struct pl330_thread *thrd;
+	int i;
+
+	/* Release Channel threads */
+	for (i = 0; i < chans; i++) {
+		thrd = &pl330->channels[i];
+		pl330_release_channel((void *)thrd);
+	}
+
+	/* Free memory */
+	kfree(pl330->channels);
+
+	return 0;
+}
+
+static void dmac_free_resources(struct pl330_dmac *pl330)
+{
+	struct pl330_info *pi = pl330->pinfo;
+	int chans = pi->pcfg.num_chan;
+
+	dmac_free_threads(pl330);
+
+	dma_free_coherent(pi->dev, chans * pi->mcbufsz,
+				pl330->mcode_cpu, pl330->mcode_bus);
+}
+
+void pl330_del(struct pl330_info *pi)
+{
+	struct pl330_dmac *pl330;
+
+	if (!pi || !pi->pl330_data)
+		return;
+
+	pl330 = pi->pl330_data;
+
+	pl330->state = UNINIT;
+
+	tasklet_kill(&pl330->tasks);
+
+	/* Free DMAC resources */
+	dmac_free_resources(pl330);
+
+	kfree(pl330);
+	pi->pl330_data = NULL;
+}
+EXPORT_SYMBOL(pl330_del);
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 1cf999a..ba65f6e 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -266,13 +266,53 @@
 #endif /* CONFIG_PM */
 
 static struct irq_chip vic_chip = {
-	.name	= "VIC",
-	.ack	= vic_ack_irq,
-	.mask	= vic_mask_irq,
-	.unmask	= vic_unmask_irq,
-	.set_wake = vic_set_wake,
+	.name		= "VIC",
+	.ack		= vic_ack_irq,
+	.mask		= vic_mask_irq,
+	.unmask		= vic_unmask_irq,
+	.set_wake	= vic_set_wake,
 };
 
+static void __init vic_disable(void __iomem *base)
+{
+	writel(0, base + VIC_INT_SELECT);
+	writel(0, base + VIC_INT_ENABLE);
+	writel(~0, base + VIC_INT_ENABLE_CLEAR);
+	writel(0, base + VIC_IRQ_STATUS);
+	writel(0, base + VIC_ITCR);
+	writel(~0, base + VIC_INT_SOFT_CLEAR);
+}
+
+static void __init vic_clear_interrupts(void __iomem *base)
+{
+	unsigned int i;
+
+	writel(0, base + VIC_PL190_VECT_ADDR);
+	for (i = 0; i < 19; i++) {
+		unsigned int value;
+
+		value = readl(base + VIC_PL190_VECT_ADDR);
+		writel(value, base + VIC_PL190_VECT_ADDR);
+	}
+}
+
+static void __init vic_set_irq_sources(void __iomem *base,
+				unsigned int irq_start, u32 vic_sources)
+{
+	unsigned int i;
+
+	for (i = 0; i < 32; i++) {
+		if (vic_sources & (1 << i)) {
+			unsigned int irq = irq_start + i;
+
+			set_irq_chip(irq, &vic_chip);
+			set_irq_chip_data(irq, base);
+			set_irq_handler(irq, handle_level_irq);
+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+		}
+	}
+}
+
 /*
  * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
  * The original cell has 32 interrupts, while the modified one has 64,
@@ -287,13 +327,7 @@
 	int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
 
 	/* Disable all interrupts initially. */
-
-	writel(0, base + VIC_INT_SELECT);
-	writel(0, base + VIC_INT_ENABLE);
-	writel(~0, base + VIC_INT_ENABLE_CLEAR);
-	writel(0, base + VIC_IRQ_STATUS);
-	writel(0, base + VIC_ITCR);
-	writel(~0, base + VIC_INT_SOFT_CLEAR);
+	vic_disable(base);
 
 	/*
 	 * Make sure we clear all existing interrupts. The vector registers
@@ -302,13 +336,8 @@
 	 * the second base address, which is 0x20 in the page
 	 */
 	if (vic_2nd_block) {
-		writel(0, base + VIC_PL190_VECT_ADDR);
-		for (i = 0; i < 19; i++) {
-			unsigned int value;
+		vic_clear_interrupts(base);
 
-			value = readl(base + VIC_PL190_VECT_ADDR);
-			writel(value, base + VIC_PL190_VECT_ADDR);
-		}
 		/* ST has 16 vectors as well, but we don't enable them by now */
 		for (i = 0; i < 16; i++) {
 			void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
@@ -318,16 +347,7 @@
 		writel(32, base + VIC_PL190_DEF_VECT_ADDR);
 	}
 
-	for (i = 0; i < 32; i++) {
-		if (vic_sources & (1 << i)) {
-			unsigned int irq = irq_start + i;
-
-			set_irq_chip(irq, &vic_chip);
-			set_irq_chip_data(irq, base);
-			set_irq_handler(irq, handle_level_irq);
-			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-		}
-	}
+	vic_set_irq_sources(base, irq_start, vic_sources);
 }
 
 /**
@@ -365,37 +385,14 @@
 	}
 
 	/* Disable all interrupts initially. */
+	vic_disable(base);
 
-	writel(0, base + VIC_INT_SELECT);
-	writel(0, base + VIC_INT_ENABLE);
-	writel(~0, base + VIC_INT_ENABLE_CLEAR);
-	writel(0, base + VIC_IRQ_STATUS);
-	writel(0, base + VIC_ITCR);
-	writel(~0, base + VIC_INT_SOFT_CLEAR);
-
-	/*
-	 * Make sure we clear all existing interrupts
-	 */
-	writel(0, base + VIC_PL190_VECT_ADDR);
-	for (i = 0; i < 19; i++) {
-		unsigned int value;
-
-		value = readl(base + VIC_PL190_VECT_ADDR);
-		writel(value, base + VIC_PL190_VECT_ADDR);
-	}
+	/* Make sure we clear all existing interrupts */
+	vic_clear_interrupts(base);
 
 	vic_init2(base);
 
-	for (i = 0; i < 32; i++) {
-		if (vic_sources & (1 << i)) {
-			unsigned int irq = irq_start + i;
-
-			set_irq_chip(irq, &vic_chip);
-			set_irq_chip_data(irq, base);
-			set_irq_handler(irq, handle_level_irq);
-			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-		}
-	}
+	vic_set_irq_sources(base, irq_start, vic_sources);
 
 	vic_pm_register(base, irq_start, resume_sources);
 }
diff --git a/arch/arm/configs/cns3420vb_defconfig b/arch/arm/configs/cns3420vb_defconfig
new file mode 100644
index 0000000..d5c0881
--- /dev/null
+++ b/arch/arm/configs/cns3420vb_defconfig
@@ -0,0 +1,831 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34-rc6
+# Sun May  2 21:58:08 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV6=y
+CONFIG_OPROFILE_ARM11_CORE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=m
+# CONFIG_CFQ_GROUP_IOSCHED is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+CONFIG_ARCH_CNS3XXX=y
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# CNS3XXX platform type
+#
+CONFIG_MACH_CNS3420VB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_411920 is not set
+CONFIG_ARM_GIC=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,38400 mem=128M root=/dev/mmcblk0p1 ro rootwait"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=20000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
+# CONFIG_ATA_SFF is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+CONFIG_FSCACHE=y
+# CONFIG_FSCACHE_STATS is not set
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+# CONFIG_FSCACHE_OBJECT_LIST is not set
+# CONFIG_CACHEFILES is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig
index 03f76cf..4b55dcb 100644
--- a/arch/arm/configs/mmp2_defconfig
+++ b/arch/arm/configs/mmp2_defconfig
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Tue Jan  5 13:55:22 2010
+# Linux kernel version: 2.6.34-rc5
+# Wed Apr 28 11:23:19 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,6 +19,7 @@
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -32,6 +34,12 @@
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -52,7 +60,6 @@
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -85,10 +92,14 @@
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -104,6 +115,7 @@
 #
 # GCOV-based kernel profiling
 #
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
@@ -170,6 +182,7 @@
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
@@ -179,7 +192,6 @@
 # CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -196,21 +208,26 @@
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
 # CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_BCMRING is not set
-# CONFIG_ARCH_U8500 is not set
 # CONFIG_MACH_TAVOREVB is not set
 
 #
@@ -218,8 +235,10 @@
 #
 # CONFIG_MACH_ASPENITE is not set
 # CONFIG_MACH_ZYLONITE2 is not set
+# CONFIG_MACH_AVENGERS_LITE is not set
 # CONFIG_MACH_TTC_DKB is not set
 CONFIG_MACH_FLINT=y
+CONFIG_MACH_MARVELL_JASPER=y
 CONFIG_CPU_MMP2=y
 CONFIG_PLAT_PXA=y
 
@@ -246,7 +265,10 @@
 # CONFIG_CPU_ICACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_TAUROS2=y
 CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_CPU_HAS_PMU=y
 # CONFIG_ARM_ERRATA_411920 is not set
 CONFIG_COMMON_CLKDEV=y
 
@@ -298,7 +320,7 @@
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M user_debug=255"
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS2,38400 mem=128M user_debug=255"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
@@ -338,7 +360,6 @@
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -532,6 +553,7 @@
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -640,6 +662,7 @@
 CONFIG_SERIAL_PXA_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -667,6 +690,7 @@
 CONFIG_I2C_PXA=y
 # CONFIG_I2C_PXA_SLAVE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -679,15 +703,9 @@
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -702,13 +720,16 @@
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -737,10 +758,12 @@
 # Multifunction device drivers
 #
 CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
@@ -749,24 +772,27 @@
 # CONFIG_MFD_TC6393XB is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+CONFIG_MFD_MAX8925=y
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-CONFIG_MFD_88PM8607=y
 CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_DUMMY is not set
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
 # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
 # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
 # CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_REGULATOR_MAX1586 is not set
-CONFIG_REGULATOR_MAX8660=y
+CONFIG_REGULATOR_MAX8649=y
+# CONFIG_REGULATOR_MAX8660 is not set
+CONFIG_REGULATOR_MAX8925=y
 # CONFIG_REGULATOR_LP3971 is not set
 # CONFIG_REGULATOR_TPS65023 is not set
 # CONFIG_REGULATOR_TPS6507X is not set
-CONFIG_REGULATOR_88PM8607=y
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -781,6 +807,7 @@
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_GENERIC=y
+CONFIG_BACKLIGHT_MAX8925=y
 
 #
 # Display device support
@@ -821,6 +848,7 @@
 # CONFIG_RTC_DRV_DS1374 is not set
 # CONFIG_RTC_DRV_DS1672 is not set
 # CONFIG_RTC_DRV_MAX6900 is not set
+CONFIG_RTC_DRV_MAX8925=y
 # CONFIG_RTC_DRV_RS5C372 is not set
 # CONFIG_RTC_DRV_ISL1208 is not set
 # CONFIG_RTC_DRV_X1205 is not set
@@ -872,7 +900,6 @@
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
@@ -883,7 +910,7 @@
 # CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
-CONFIG_DNOTIFY=y
+# CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
@@ -940,6 +967,7 @@
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -967,6 +995,7 @@
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -990,7 +1019,7 @@
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
@@ -1032,6 +1061,7 @@
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1052,6 +1082,7 @@
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_DYNAMIC_DEBUG=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1059,9 +1090,7 @@
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
-CONFIG_DEBUG_LL=y
-# CONFIG_EARLY_PRINTK is not set
-# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_LL is not set
 # CONFIG_OC_ETM is not set
 
 #
diff --git a/arch/arm/configs/spear300_defconfig b/arch/arm/configs/spear300_defconfig
new file mode 100644
index 0000000..35e64d1
--- /dev/null
+++ b/arch/arm/configs/spear300_defconfig
@@ -0,0 +1,773 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue Mar 23 14:36:23 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR3XX=y
+# CONFIG_ARCH_SPEAR6XX is not set
+CONFIG_MACH_SPEAR300=y
+# CONFIG_MACH_SPEAR310 is not set
+# CONFIG_MACH_SPEAR320 is not set
+CONFIG_BOARD_SPEAR300_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/spear310_defconfig b/arch/arm/configs/spear310_defconfig
new file mode 100644
index 0000000..cbbfd29
--- /dev/null
+++ b/arch/arm/configs/spear310_defconfig
@@ -0,0 +1,775 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue Mar 23 14:37:01 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR3XX=y
+# CONFIG_ARCH_SPEAR6XX is not set
+# CONFIG_MACH_SPEAR300 is not set
+CONFIG_MACH_SPEAR310=y
+# CONFIG_MACH_SPEAR320 is not set
+# CONFIG_BOARD_SPEAR300_EVB is not set
+CONFIG_BOARD_SPEAR310_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/spear320_defconfig b/arch/arm/configs/spear320_defconfig
new file mode 100644
index 0000000..2ae3c11
--- /dev/null
+++ b/arch/arm/configs/spear320_defconfig
@@ -0,0 +1,775 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue Mar 23 14:37:12 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR3XX=y
+# CONFIG_ARCH_SPEAR6XX is not set
+# CONFIG_MACH_SPEAR300 is not set
+# CONFIG_MACH_SPEAR310 is not set
+CONFIG_MACH_SPEAR320=y
+# CONFIG_BOARD_SPEAR300_EVB is not set
+CONFIG_BOARD_SPEAR320_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/spear600_defconfig b/arch/arm/configs/spear600_defconfig
new file mode 100644
index 0000000..c85a029
--- /dev/null
+++ b/arch/arm/configs/spear600_defconfig
@@ -0,0 +1,760 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue Mar 23 14:37:26 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+# CONFIG_ARCH_SPEAR3XX is not set
+CONFIG_ARCH_SPEAR6XX=y
+# CONFIG_MACH_SPEAR300 is not set
+# CONFIG_MACH_SPEAR310 is not set
+# CONFIG_MACH_SPEAR320 is not set
+# CONFIG_BOARD_SPEAR300_EVB is not set
+CONFIG_MACH_SPEAR600=y
+CONFIG_BOARD_SPEAR600_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/stamp9g20_defconfig b/arch/arm/configs/stamp9g20_defconfig
new file mode 100644
index 0000000..06a8293
--- /dev/null
+++ b/arch/arm/configs/stamp9g20_defconfig
@@ -0,0 +1,1456 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 17 16:38:03 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_HAVE_AT91_USART3=y
+CONFIG_HAVE_AT91_USART4=y
+CONFIG_HAVE_AT91_USART5=y
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9G10 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+CONFIG_ARCH_AT91SAM9G20=y
+# CONFIG_ARCH_AT91SAM9G45 is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT572D940HF is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9G20 Board Type
+#
+# CONFIG_MACH_AT91SAM9G20EK is not set
+# CONFIG_MACH_AT91SAM9G20EK_2MMC is not set
+# CONFIG_MACH_CPU9G20 is not set
+CONFIG_MACH_PORTUXG20=y
+CONFIG_MACH_STAMP9G20=y
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_SLOW_CLOCK=y
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+CONFIG_W1=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+CONFIG_W1_MASTER_GPIO=y
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=y
+# CONFIG_W1_SLAVE_SMEM is not set
+CONFIG_W1_SLAVE_DS2431=y
+# CONFIG_W1_SLAVE_DS2433 is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
+# CONFIG_W1_SLAVE_BQ27000 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_AT91SAM9X_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=m
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_RTC_DRV_AT91SAM9_RTT=0
+CONFIG_RTC_DRV_AT91SAM9_GPBR=0
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h
index 04be3bd..c0f4e7b 100644
--- a/arch/arm/include/asm/hardware/arm_timer.h
+++ b/arch/arm/include/asm/hardware/arm_timer.h
@@ -1,21 +1,30 @@
 #ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
 #define __ASM_ARM_HARDWARE_ARM_TIMER_H
 
-#define TIMER_LOAD	0x00
-#define TIMER_VALUE	0x04
-#define TIMER_CTRL	0x08
-#define TIMER_CTRL_ONESHOT	(1 << 0)
-#define TIMER_CTRL_32BIT	(1 << 1)
-#define TIMER_CTRL_DIV1		(0 << 2)
-#define TIMER_CTRL_DIV16	(1 << 2)
-#define TIMER_CTRL_DIV256	(2 << 2)
-#define TIMER_CTRL_IE		(1 << 5)	/* Interrupt Enable (versatile only) */
-#define TIMER_CTRL_PERIODIC	(1 << 6)
-#define TIMER_CTRL_ENABLE	(1 << 7)
+/*
+ * ARM timer implementation, found in Integrator, Versatile and Realview
+ * platforms.  Not all platforms support all registers and bits in these
+ * registers, so we mark them with A for Integrator AP, C for Integrator
+ * CP, V for Versatile and R for Realview.
+ *
+ * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
+ * can have 16-bit or 32-bit selectable via a bit in the control register.
+ */
+#define TIMER_LOAD	0x00			/* ACVR rw */
+#define TIMER_VALUE	0x04			/* ACVR ro */
+#define TIMER_CTRL	0x08			/* ACVR rw */
+#define TIMER_CTRL_ONESHOT	(1 << 0)	/*  CVR */
+#define TIMER_CTRL_32BIT	(1 << 1)	/*  CVR */
+#define TIMER_CTRL_DIV1		(0 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV16	(1 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV256	(2 << 2)	/* ACVR */
+#define TIMER_CTRL_IE		(1 << 5)	/*   VR */
+#define TIMER_CTRL_PERIODIC	(1 << 6)	/* ACVR */
+#define TIMER_CTRL_ENABLE	(1 << 7)	/* ACVR */
 
-#define TIMER_INTCLR	0x0c
-#define TIMER_RIS	0x10
-#define TIMER_MIS	0x14
-#define TIMER_BGLOAD	0x18
+#define TIMER_INTCLR	0x0c			/* ACVR wo */
+#define TIMER_RIS	0x10			/*  CVR ro */
+#define TIMER_MIS	0x14			/*  CVR ro */
+#define TIMER_BGLOAD	0x18			/*  CVR rw */
 
 #endif
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index cdb9022..6bcba48 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -21,6 +21,9 @@
 #define __ASM_ARM_HARDWARE_L2X0_H
 
 #define L2X0_CACHE_ID			0x000
+#define   L2X0_CACHE_ID_PART_MASK	(0xf << 6)
+#define   L2X0_CACHE_ID_PART_L210	(1 << 6)
+#define   L2X0_CACHE_ID_PART_L310	(3 << 6)
 #define L2X0_CACHE_TYPE			0x004
 #define L2X0_CTRL			0x100
 #define L2X0_AUX_CTRL			0x104
diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h
new file mode 100644
index 0000000..10382a3
--- /dev/null
+++ b/arch/arm/include/asm/hardware/icst.h
@@ -0,0 +1,59 @@
+/*
+ *  arch/arm/include/asm/hardware/icst.h
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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.
+ *
+ *  Support functions for calculating clocks/divisors for the ICST
+ *  clock generators.  See http://www.icst.com/ for more information
+ *  on these devices.
+ */
+#ifndef ASMARM_HARDWARE_ICST_H
+#define ASMARM_HARDWARE_ICST_H
+
+struct icst_params {
+	unsigned long	ref;
+	unsigned long	vco_max;	/* inclusive */
+	unsigned long	vco_min;	/* exclusive */
+	unsigned short	vd_min;		/* inclusive */
+	unsigned short	vd_max;		/* inclusive */
+	unsigned char	rd_min;		/* inclusive */
+	unsigned char	rd_max;		/* inclusive */
+	const unsigned char *s2div;	/* chip specific s2div array */
+	const unsigned char *idx2s;	/* chip specific idx2s array */
+};
+
+struct icst_vco {
+	unsigned short	v;
+	unsigned char	r;
+	unsigned char	s;
+};
+
+unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco);
+struct icst_vco icst_hz_to_vco(const struct icst_params *p, unsigned long freq);
+
+/*
+ * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V).
+ * This frequency is pre-output divider.
+ */
+#define ICST307_VCO_MIN	6000000
+#define ICST307_VCO_MAX	200000000
+
+extern const unsigned char icst307_s2div[];
+extern const unsigned char icst307_idx2s[];
+
+/*
+ * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V).
+ * This frequency is pre-output divider.
+ */
+#define ICST525_VCO_MIN		10000000
+#define ICST525_VCO_MAX_3V	200000000
+#define ICST525_VCO_MAX_5V	320000000
+
+extern const unsigned char icst525_s2div[];
+extern const unsigned char icst525_idx2s[];
+
+#endif
diff --git a/arch/arm/include/asm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h
deleted file mode 100644
index 554f128..0000000
--- a/arch/arm/include/asm/hardware/icst307.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *  arch/arm/include/asm/hardware/icst307.h
- *
- *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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.
- *
- *  Support functions for calculating clocks/divisors for the ICS307
- *  clock generators.  See http://www.icst.com/ for more information
- *  on these devices.
- *
- *  This file is similar to the icst525.h file
- */
-#ifndef ASMARM_HARDWARE_ICST307_H
-#define ASMARM_HARDWARE_ICST307_H
-
-struct icst307_params {
-	unsigned long	ref;
-	unsigned long	vco_max;	/* inclusive */
-	unsigned short	vd_min;		/* inclusive */
-	unsigned short	vd_max;		/* inclusive */
-	unsigned char	rd_min;		/* inclusive */
-	unsigned char	rd_max;		/* inclusive */
-};
-
-struct icst307_vco {
-	unsigned short	v;
-	unsigned char	r;
-	unsigned char	s;
-};
-
-unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco);
-struct icst307_vco icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq);
-struct icst307_vco icst307_ps_to_vco(const struct icst307_params *p, unsigned long period);
-
-#endif
diff --git a/arch/arm/include/asm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h
deleted file mode 100644
index 58f0dc4..0000000
--- a/arch/arm/include/asm/hardware/icst525.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  arch/arm/include/asm/hardware/icst525.h
- *
- *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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.
- *
- *  Support functions for calculating clocks/divisors for the ICST525
- *  clock generators.  See http://www.icst.com/ for more information
- *  on these devices.
- */
-#ifndef ASMARM_HARDWARE_ICST525_H
-#define ASMARM_HARDWARE_ICST525_H
-
-struct icst525_params {
-	unsigned long	ref;
-	unsigned long	vco_max;	/* inclusive */
-	unsigned short	vd_min;		/* inclusive */
-	unsigned short	vd_max;		/* inclusive */
-	unsigned char	rd_min;		/* inclusive */
-	unsigned char	rd_max;		/* inclusive */
-};
-
-struct icst525_vco {
-	unsigned short	v;
-	unsigned char	r;
-	unsigned char	s;
-};
-
-unsigned long icst525_khz(const struct icst525_params *p, struct icst525_vco vco);
-struct icst525_vco icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq);
-struct icst525_vco icst525_ps_to_vco(const struct icst525_params *p, unsigned long period);
-
-#endif
diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h
new file mode 100644
index 0000000..575fa81
--- /dev/null
+++ b/arch/arm/include/asm/hardware/pl330.h
@@ -0,0 +1,217 @@
+/* linux/include/asm/hardware/pl330.h
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *	Jaswinder Singh <jassi.brar@samsung.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PL330_CORE_H
+#define __PL330_CORE_H
+
+#define PL330_MAX_CHAN		8
+#define PL330_MAX_IRQS		32
+#define PL330_MAX_PERI		32
+
+enum pl330_srccachectrl {
+	SCCTRL0 = 0, /* Noncacheable and nonbufferable */
+	SCCTRL1, /* Bufferable only */
+	SCCTRL2, /* Cacheable, but do not allocate */
+	SCCTRL3, /* Cacheable and bufferable, but do not allocate */
+	SINVALID1,
+	SINVALID2,
+	SCCTRL6, /* Cacheable write-through, allocate on reads only */
+	SCCTRL7, /* Cacheable write-back, allocate on reads only */
+};
+
+enum pl330_dstcachectrl {
+	DCCTRL0 = 0, /* Noncacheable and nonbufferable */
+	DCCTRL1, /* Bufferable only */
+	DCCTRL2, /* Cacheable, but do not allocate */
+	DCCTRL3, /* Cacheable and bufferable, but do not allocate */
+	DINVALID1 = 8,
+	DINVALID2,
+	DCCTRL6, /* Cacheable write-through, allocate on writes only */
+	DCCTRL7, /* Cacheable write-back, allocate on writes only */
+};
+
+/* Populated by the PL330 core driver for DMA API driver's info */
+struct pl330_config {
+	u32	periph_id;
+	u32	pcell_id;
+#define DMAC_MODE_NS	(1 << 0)
+	unsigned int	mode;
+	unsigned int	data_bus_width:10; /* In number of bits */
+	unsigned int	data_buf_dep:10;
+	unsigned int	num_chan:4;
+	unsigned int	num_peri:6;
+	u32		peri_ns;
+	unsigned int	num_events:6;
+	u32		irq_ns;
+};
+
+/* Handle to the DMAC provided to the PL330 core */
+struct pl330_info {
+	/* Owning device */
+	struct device *dev;
+	/* Size of MicroCode buffers for each channel. */
+	unsigned mcbufsz;
+	/* ioremap'ed address of PL330 registers. */
+	void __iomem	*base;
+	/* Client can freely use it. */
+	void	*client_data;
+	/* PL330 core data, Client must not touch it. */
+	void	*pl330_data;
+	/* Populated by the PL330 core driver during pl330_add */
+	struct pl330_config	pcfg;
+	/*
+	 * If the DMAC has some reset mechanism, then the
+	 * client may want to provide pointer to the method.
+	 */
+	void (*dmac_reset)(struct pl330_info *pi);
+};
+
+enum pl330_byteswap {
+	SWAP_NO = 0,
+	SWAP_2,
+	SWAP_4,
+	SWAP_8,
+	SWAP_16,
+};
+
+/**
+ * Request Configuration.
+ * The PL330 core does not modify this and uses the last
+ * working configuration if the request doesn't provide any.
+ *
+ * The Client may want to provide this info only for the
+ * first request and a request with new settings.
+ */
+struct pl330_reqcfg {
+	/* Address Incrementing */
+	unsigned dst_inc:1;
+	unsigned src_inc:1;
+
+	/*
+	 * For now, the SRC & DST protection levels
+	 * and burst size/length are assumed same.
+	 */
+	bool nonsecure;
+	bool privileged;
+	bool insnaccess;
+	unsigned brst_len:5;
+	unsigned brst_size:3; /* in power of 2 */
+
+	enum pl330_dstcachectrl dcctl;
+	enum pl330_srccachectrl scctl;
+	enum pl330_byteswap swap;
+};
+
+/*
+ * One cycle of DMAC operation.
+ * There may be more than one xfer in a request.
+ */
+struct pl330_xfer {
+	u32 src_addr;
+	u32 dst_addr;
+	/* Size to xfer */
+	u32 bytes;
+	/*
+	 * Pointer to next xfer in the list.
+	 * The last xfer in the req must point to NULL.
+	 */
+	struct pl330_xfer *next;
+};
+
+/* The xfer callbacks are made with one of these arguments. */
+enum pl330_op_err {
+	/* The all xfers in the request were success. */
+	PL330_ERR_NONE,
+	/* If req aborted due to global error. */
+	PL330_ERR_ABORT,
+	/* If req failed due to problem with Channel. */
+	PL330_ERR_FAIL,
+};
+
+enum pl330_reqtype {
+	MEMTOMEM,
+	MEMTODEV,
+	DEVTOMEM,
+	DEVTODEV,
+};
+
+/* A request defining Scatter-Gather List ending with NULL xfer. */
+struct pl330_req {
+	enum pl330_reqtype rqtype;
+	/* Index of peripheral for the xfer. */
+	unsigned peri:5;
+	/* Unique token for this xfer, set by the client. */
+	void *token;
+	/* Callback to be called after xfer. */
+	void (*xfer_cb)(void *token, enum pl330_op_err err);
+	/* If NULL, req will be done at last set parameters. */
+	struct pl330_reqcfg *cfg;
+	/* Pointer to first xfer in the request. */
+	struct pl330_xfer *x;
+};
+
+/*
+ * To know the status of the channel and DMAC, the client
+ * provides a pointer to this structure. The PL330 core
+ * fills it with current information.
+ */
+struct pl330_chanstatus {
+	/*
+	 * If the DMAC engine halted due to some error,
+	 * the client should remove-add DMAC.
+	 */
+	bool dmac_halted;
+	/*
+	 * If channel is halted due to some error,
+	 * the client should ABORT/FLUSH and START the channel.
+	 */
+	bool faulting;
+	/* Location of last load */
+	u32 src_addr;
+	/* Location of last store */
+	u32 dst_addr;
+	/*
+	 * Pointer to the currently active req, NULL if channel is
+	 * inactive, even though the requests may be present.
+	 */
+	struct pl330_req *top_req;
+	/* Pointer to req waiting second in the queue if any. */
+	struct pl330_req *wait_req;
+};
+
+enum pl330_chan_op {
+	/* Start the channel */
+	PL330_OP_START,
+	/* Abort the active xfer */
+	PL330_OP_ABORT,
+	/* Stop xfer and flush queue */
+	PL330_OP_FLUSH,
+};
+
+extern int pl330_add(struct pl330_info *);
+extern void pl330_del(struct pl330_info *pi);
+extern int pl330_update(const struct pl330_info *pi);
+extern void pl330_release_channel(void *ch_id);
+extern void *pl330_request_channel(const struct pl330_info *pi);
+extern int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus);
+extern int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op);
+extern int pl330_submit_req(void *ch_id, struct pl330_req *r);
+
+#endif	/* __PL330_CORE_H */
diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h
new file mode 100644
index 0000000..a101f10
--- /dev/null
+++ b/arch/arm/include/asm/hardware/sp810.h
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/include/asm/hardware/sp810.h
+ *
+ * ARM PrimeXsys System Controller SP810 header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __ASM_ARM_SP810_H
+#define __ASM_ARM_SP810_H
+
+#include <linux/io.h>
+
+/* sysctl registers offset */
+#define SCCTRL			0x000
+#define SCSYSSTAT		0x004
+#define SCIMCTRL		0x008
+#define SCIMSTAT		0x00C
+#define SCXTALCTRL		0x010
+#define SCPLLCTRL		0x014
+#define SCPLLFCTRL		0x018
+#define SCPERCTRL0		0x01C
+#define SCPERCTRL1		0x020
+#define SCPEREN			0x024
+#define SCPERDIS		0x028
+#define SCPERCLKEN		0x02C
+#define SCPERSTAT		0x030
+#define SCSYSID0		0xEE0
+#define SCSYSID1		0xEE4
+#define SCSYSID2		0xEE8
+#define SCSYSID3		0xEEC
+#define SCITCR			0xF00
+#define SCITIR0			0xF04
+#define SCITIR1			0xF08
+#define SCITOR			0xF0C
+#define SCCNTCTRL		0xF10
+#define SCCNTDATA		0xF14
+#define SCCNTSTEP		0xF18
+#define SCPERIPHID0		0xFE0
+#define SCPERIPHID1		0xFE4
+#define SCPERIPHID2		0xFE8
+#define SCPERIPHID3		0xFEC
+#define SCPCELLID0		0xFF0
+#define SCPCELLID1		0xFF4
+#define SCPCELLID2		0xFF8
+#define SCPCELLID3		0xFFC
+
+static inline void sysctl_soft_reset(void __iomem *base)
+{
+	/* writing any value to SCSYSSTAT reg will reset system */
+	writel(0, base + SCSYSSTAT);
+}
+
+#endif	/* __ASM_ARM_SP810_H */
diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h
index a91d8a1..7f0b6d1 100644
--- a/arch/arm/include/asm/ioctls.h
+++ b/arch/arm/include/asm/ioctls.h
@@ -53,6 +53,9 @@
 #define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
 #define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
 
+#define TIOCGRS485      0x542E
+#define TIOCSRS485      0x542F
+
 #define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
 #define FIOCLEX		0x5451
 #define FIOASYNC	0x5452
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index a38bdc7..52f0da1 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -8,10 +8,16 @@
  * published by the Free Software Foundation.
  */
 
+#ifndef __ASM_MACH_PCI_H
+#define __ASM_MACH_PCI_H
+
 struct pci_sys_data;
 struct pci_bus;
 
 struct hw_pci {
+#ifdef CONFIG_PCI_DOMAINS
+	int		domain;
+#endif
 	struct list_head buses;
 	int		nr_controllers;
 	int		(*setup)(int nr, struct pci_sys_data *);
@@ -26,6 +32,9 @@
  * Per-controller structure
  */
 struct pci_sys_data {
+#ifdef CONFIG_PCI_DOMAINS
+	int		domain;
+#endif
 	struct list_head node;
 	int		busnr;		/* primary bus number			*/
 	u64		mem_offset;	/* bus->cpu memory mapping offset	*/
@@ -70,3 +79,5 @@
 extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *);
 extern void pci_v3_preinit(void);
 extern void pci_v3_postinit(void);
+
+#endif /* __ASM_MACH_PCI_H */
diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
index 8bffc3f..35d408f 100644
--- a/arch/arm/include/asm/mach/time.h
+++ b/arch/arm/include/asm/mach/time.h
@@ -38,7 +38,7 @@
 	void			(*init)(void);
 	void			(*suspend)(void);
 	void			(*resume)(void);
-#ifndef CONFIG_GENERIC_TIME
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
 	unsigned long		(*offset)(void);
 #endif
 };
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 4798011..92e2a83 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -4,8 +4,23 @@
 #ifdef __KERNEL__
 #include <asm-generic/pci-dma-compat.h>
 
+#include <asm/mach/pci.h> /* for pci_sys_data */
 #include <mach/hardware.h> /* for PCIBIOS_MIN_* */
 
+#ifdef CONFIG_PCI_DOMAINS
+static inline int pci_domain_nr(struct pci_bus *bus)
+{
+	struct pci_sys_data *root = bus->sysdata;
+
+	return root->domain;
+}
+
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+	return pci_domain_nr(bus);
+}
+#endif /* CONFIG_PCI_DOMAINS */
+
 #ifdef CONFIG_PCI_HOST_ITE8152
 /* ITE bridge requires setting latency timer to avoid early bus access
    termination by PIC bus mater devices
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index 49e3049..48837e6 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -28,4 +28,21 @@
  * same indexes here for consistency. */
 #define PERF_EVENT_INDEX_OFFSET 1
 
+/* ARM perf PMU IDs for use by internal perf clients. */
+enum arm_perf_pmu_ids {
+	ARM_PERF_PMU_ID_XSCALE1	= 0,
+	ARM_PERF_PMU_ID_XSCALE2,
+	ARM_PERF_PMU_ID_V6,
+	ARM_PERF_PMU_ID_V6MP,
+	ARM_PERF_PMU_ID_CA8,
+	ARM_PERF_PMU_ID_CA9,
+	ARM_NUM_PMU_IDS,
+};
+
+extern enum arm_perf_pmu_ids
+armpmu_get_pmu_id(void);
+
+extern int
+armpmu_get_max_events(void);
+
 #endif /* __ARM_PERF_EVENT_H__ */
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 1139768..ab68cf1 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -314,7 +314,7 @@
 	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
 #define pgprot_writecombine(prot) \
 	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
-#if __LINUX_ARM_ARCH__ >= 7
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
 #define pgprot_dmacoherent(prot) \
 	__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
 #else
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 2829b9f..8ccea01 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -12,33 +12,33 @@
 #ifndef __ARM_PMU_H__
 #define __ARM_PMU_H__
 
-#ifdef CONFIG_CPU_HAS_PMU
-
-struct pmu_irqs {
-	const int   *irqs;
-	int	    num_irqs;
+enum arm_pmu_type {
+	ARM_PMU_DEVICE_CPU	= 0,
+	ARM_NUM_PMU_DEVICES,
 };
 
+#ifdef CONFIG_CPU_HAS_PMU
+
 /**
  * reserve_pmu() - reserve the hardware performance counters
  *
  * Reserve the hardware performance counters in the system for exclusive use.
- * The 'struct pmu_irqs' for the system is returned on success, ERR_PTR()
+ * The platform_device for the system is returned on success, ERR_PTR()
  * encoded error on failure.
  */
-extern const struct pmu_irqs *
-reserve_pmu(void);
+extern struct platform_device *
+reserve_pmu(enum arm_pmu_type device);
 
 /**
  * release_pmu() - Relinquish control of the performance counters
  *
  * Release the performance counters and allow someone else to use them.
  * Callers must have disabled the counters and released IRQs before calling
- * this. The 'struct pmu_irqs' returned from reserve_pmu() must be passed as
+ * this. The platform_device returned from reserve_pmu() must be passed as
  * a cookie.
  */
 extern int
-release_pmu(const struct pmu_irqs *irqs);
+release_pmu(struct platform_device *pdev);
 
 /**
  * init_pmu() - Initialise the PMU.
@@ -48,24 +48,26 @@
  * the actual hardware initialisation.
  */
 extern int
-init_pmu(void);
+init_pmu(enum arm_pmu_type device);
 
 #else /* CONFIG_CPU_HAS_PMU */
 
-static inline const struct pmu_irqs *
-reserve_pmu(void)
+#include <linux/err.h>
+
+static inline struct platform_device *
+reserve_pmu(enum arm_pmu_type device)
 {
 	return ERR_PTR(-ENODEV);
 }
 
 static inline int
-release_pmu(const struct pmu_irqs *irqs)
+release_pmu(struct platform_device *pdev)
 {
 	return -ENODEV;
 }
 
 static inline int
-init_pmu(void)
+init_pmu(enum arm_pmu_type device)
 {
 	return -ENODEV;
 }
diff --git a/arch/arm/include/asm/scatterlist.h b/arch/arm/include/asm/scatterlist.h
index ca0a37d..bcda59f 100644
--- a/arch/arm/include/asm/scatterlist.h
+++ b/arch/arm/include/asm/scatterlist.h
@@ -4,24 +4,8 @@
 #include <asm/memory.h>
 #include <asm/types.h>
 
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
-	unsigned long	sg_magic;
-#endif
-	unsigned long	page_link;
-	unsigned int	offset;		/* buffer offset		 */
-	dma_addr_t	dma_address;	/* dma address			 */
-	unsigned int	length;		/* length			 */
-};
+#include <asm-generic/scatterlist.h>
 
-/*
- * These macros should be used after a pci_map_sg call has been done
- * to get bus addresses of each of the SG entries and their lengths.
- * You should only work with the number of sg entries pci_map_sg
- * returns, or alternatively stop on the first sg_dma_len(sg) which
- * is 0.
- */
-#define sg_dma_address(sg)      ((sg)->dma_address)
-#define sg_dma_len(sg)          ((sg)->length)
+#undef ARCH_HAS_SG_CHAIN
 
 #endif /* _ASMARM_SCATTERLIST_H */
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index e0d763b..3d05190 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -82,7 +82,7 @@
 extern struct secondary_data secondary_data;
 
 extern int __cpu_disable(void);
-extern int mach_cpu_disable(unsigned int cpu);
+extern int platform_cpu_disable(unsigned int cpu);
 
 extern void __cpu_die(unsigned int cpu);
 extern void cpu_die(void);
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 4ace45e..5f4f480 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -141,7 +141,7 @@
 
 #ifdef CONFIG_ARCH_HAS_BARRIERS
 #include <mach/barriers.h>
-#elif __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
+#elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP)
 #define mb()		do { dsb(); outer_sync(); } while (0)
 #define rmb()		dmb()
 #define wmb()		mb()
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index bd397e0..c6273a3 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -527,6 +527,9 @@
 		if (!sys)
 			panic("PCI: unable to allocate sys data!");
 
+#ifdef CONFIG_PCI_DOMAINS
+		sys->domain  = hw->domain;
+#endif
 		sys->hw      = hw;
 		sys->busnr   = busnr;
 		sys->swizzle = hw->swizzle;
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 7d5b9fb..2c4a185 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -16,6 +16,8 @@
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/scatterlist.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
 
 #include <asm/dma.h>
 
@@ -264,3 +266,37 @@
 	return ret;
 }
 EXPORT_SYMBOL(get_dma_residue);
+
+#ifdef CONFIG_PROC_FS
+static int proc_dma_show(struct seq_file *m, void *v)
+{
+	int i;
+
+	for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
+		dma_t *dma = dma_channel(i);
+		if (dma && dma->lock)
+			seq_printf(m, "%2d: %s\n", i, dma->device_id);
+	}
+	return 0;
+}
+
+static int proc_dma_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_dma_show, NULL);
+}
+
+static const struct file_operations proc_dma_operations = {
+	.open		= proc_dma_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init proc_dma_init(void)
+{
+	proc_create("dma", 0, NULL, &proc_dma_operations);
+	return 0;
+}
+
+__initcall(proc_dma_init);
+#endif
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 9e70f20..c457686 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -16,7 +16,9 @@
 
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/perf_event.h>
+#include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
 
@@ -26,7 +28,7 @@
 #include <asm/pmu.h>
 #include <asm/stacktrace.h>
 
-static const struct pmu_irqs *pmu_irqs;
+static struct platform_device *pmu_device;
 
 /*
  * Hardware lock to serialize accesses to PMU registers. Needed for the
@@ -67,8 +69,18 @@
 };
 DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
 
+/* PMU names. */
+static const char *arm_pmu_names[] = {
+	[ARM_PERF_PMU_ID_XSCALE1] = "xscale1",
+	[ARM_PERF_PMU_ID_XSCALE2] = "xscale2",
+	[ARM_PERF_PMU_ID_V6]	  = "v6",
+	[ARM_PERF_PMU_ID_V6MP]	  = "v6mpcore",
+	[ARM_PERF_PMU_ID_CA8]	  = "ARMv7 Cortex-A8",
+	[ARM_PERF_PMU_ID_CA9]	  = "ARMv7 Cortex-A9",
+};
+
 struct arm_pmu {
-	char		*name;
+	enum arm_perf_pmu_ids id;
 	irqreturn_t	(*handle_irq)(int irq_num, void *dev);
 	void		(*enable)(struct hw_perf_event *evt, int idx);
 	void		(*disable)(struct hw_perf_event *evt, int idx);
@@ -87,6 +99,30 @@
 /* Set at runtime when we know what CPU type we are. */
 static const struct arm_pmu *armpmu;
 
+enum arm_perf_pmu_ids
+armpmu_get_pmu_id(void)
+{
+	int id = -ENODEV;
+
+	if (armpmu != NULL)
+		id = armpmu->id;
+
+	return id;
+}
+EXPORT_SYMBOL_GPL(armpmu_get_pmu_id);
+
+int
+armpmu_get_max_events(void)
+{
+	int max_events = 0;
+
+	if (armpmu != NULL)
+		max_events = armpmu->num_events;
+
+	return max_events;
+}
+EXPORT_SYMBOL_GPL(armpmu_get_max_events);
+
 #define HW_OP_UNSUPPORTED		0xFFFF
 
 #define C(_x) \
@@ -314,38 +350,44 @@
 static int
 armpmu_reserve_hardware(void)
 {
-	int i;
-	int err;
+	int i, err = -ENODEV, irq;
 
-	pmu_irqs = reserve_pmu();
-	if (IS_ERR(pmu_irqs)) {
+	pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU);
+	if (IS_ERR(pmu_device)) {
 		pr_warning("unable to reserve pmu\n");
-		return PTR_ERR(pmu_irqs);
+		return PTR_ERR(pmu_device);
 	}
 
-	init_pmu();
+	init_pmu(ARM_PMU_DEVICE_CPU);
 
-	if (pmu_irqs->num_irqs < 1) {
+	if (pmu_device->num_resources < 1) {
 		pr_err("no irqs for PMUs defined\n");
 		return -ENODEV;
 	}
 
-	for (i = 0; i < pmu_irqs->num_irqs; ++i) {
-		err = request_irq(pmu_irqs->irqs[i], armpmu->handle_irq,
+	for (i = 0; i < pmu_device->num_resources; ++i) {
+		irq = platform_get_irq(pmu_device, i);
+		if (irq < 0)
+			continue;
+
+		err = request_irq(irq, armpmu->handle_irq,
 				  IRQF_DISABLED | IRQF_NOBALANCING,
 				  "armpmu", NULL);
 		if (err) {
-			pr_warning("unable to request IRQ%d for ARM "
-				   "perf counters\n", pmu_irqs->irqs[i]);
+			pr_warning("unable to request IRQ%d for ARM perf "
+				"counters\n", irq);
 			break;
 		}
 	}
 
 	if (err) {
-		for (i = i - 1; i >= 0; --i)
-			free_irq(pmu_irqs->irqs[i], NULL);
-		release_pmu(pmu_irqs);
-		pmu_irqs = NULL;
+		for (i = i - 1; i >= 0; --i) {
+			irq = platform_get_irq(pmu_device, i);
+			if (irq >= 0)
+				free_irq(irq, NULL);
+		}
+		release_pmu(pmu_device);
+		pmu_device = NULL;
 	}
 
 	return err;
@@ -354,14 +396,17 @@
 static void
 armpmu_release_hardware(void)
 {
-	int i;
+	int i, irq;
 
-	for (i = pmu_irqs->num_irqs - 1; i >= 0; --i)
-		free_irq(pmu_irqs->irqs[i], NULL);
+	for (i = pmu_device->num_resources - 1; i >= 0; --i) {
+		irq = platform_get_irq(pmu_device, i);
+		if (irq >= 0)
+			free_irq(irq, NULL);
+	}
 	armpmu->stop();
 
-	release_pmu(pmu_irqs);
-	pmu_irqs = NULL;
+	release_pmu(pmu_device);
+	pmu_device = NULL;
 }
 
 static atomic_t active_events = ATOMIC_INIT(0);
@@ -1144,7 +1189,7 @@
 }
 
 static const struct arm_pmu armv6pmu = {
-	.name			= "v6",
+	.id			= ARM_PERF_PMU_ID_V6,
 	.handle_irq		= armv6pmu_handle_irq,
 	.enable			= armv6pmu_enable_event,
 	.disable		= armv6pmu_disable_event,
@@ -1167,7 +1212,7 @@
  * reset the period and enable the interrupt reporting.
  */
 static const struct arm_pmu armv6mpcore_pmu = {
-	.name			= "v6mpcore",
+	.id			= ARM_PERF_PMU_ID_V6MP,
 	.handle_irq		= armv6pmu_handle_irq,
 	.enable			= armv6pmu_enable_event,
 	.disable		= armv6mpcore_pmu_disable_event,
@@ -1197,10 +1242,6 @@
  *  counter and all 4 performance counters together can be reset separately.
  */
 
-#define ARMV7_PMU_CORTEX_A8_NAME		"ARMv7 Cortex-A8"
-
-#define ARMV7_PMU_CORTEX_A9_NAME		"ARMv7 Cortex-A9"
-
 /* Common ARMv7 event types */
 enum armv7_perf_types {
 	ARMV7_PERFCTR_PMNC_SW_INCR		= 0x00,
@@ -2079,6 +2120,803 @@
 	return nb_cnt + 1;
 }
 
+/*
+ * ARMv5 [xscale] Performance counter handling code.
+ *
+ * Based on xscale OProfile code.
+ *
+ * There are two variants of the xscale PMU that we support:
+ * 	- xscale1pmu: 2 event counters and a cycle counter
+ * 	- xscale2pmu: 4 event counters and a cycle counter
+ * The two variants share event definitions, but have different
+ * PMU structures.
+ */
+
+enum xscale_perf_types {
+	XSCALE_PERFCTR_ICACHE_MISS		= 0x00,
+	XSCALE_PERFCTR_ICACHE_NO_DELIVER	= 0x01,
+	XSCALE_PERFCTR_DATA_STALL		= 0x02,
+	XSCALE_PERFCTR_ITLB_MISS		= 0x03,
+	XSCALE_PERFCTR_DTLB_MISS		= 0x04,
+	XSCALE_PERFCTR_BRANCH			= 0x05,
+	XSCALE_PERFCTR_BRANCH_MISS		= 0x06,
+	XSCALE_PERFCTR_INSTRUCTION		= 0x07,
+	XSCALE_PERFCTR_DCACHE_FULL_STALL	= 0x08,
+	XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG	= 0x09,
+	XSCALE_PERFCTR_DCACHE_ACCESS		= 0x0A,
+	XSCALE_PERFCTR_DCACHE_MISS		= 0x0B,
+	XSCALE_PERFCTR_DCACHE_WRITE_BACK	= 0x0C,
+	XSCALE_PERFCTR_PC_CHANGED		= 0x0D,
+	XSCALE_PERFCTR_BCU_REQUEST		= 0x10,
+	XSCALE_PERFCTR_BCU_FULL			= 0x11,
+	XSCALE_PERFCTR_BCU_DRAIN		= 0x12,
+	XSCALE_PERFCTR_BCU_ECC_NO_ELOG		= 0x14,
+	XSCALE_PERFCTR_BCU_1_BIT_ERR		= 0x15,
+	XSCALE_PERFCTR_RMW			= 0x16,
+	/* XSCALE_PERFCTR_CCNT is not hardware defined */
+	XSCALE_PERFCTR_CCNT			= 0xFE,
+	XSCALE_PERFCTR_UNUSED			= 0xFF,
+};
+
+enum xscale_counters {
+	XSCALE_CYCLE_COUNTER	= 1,
+	XSCALE_COUNTER0,
+	XSCALE_COUNTER1,
+	XSCALE_COUNTER2,
+	XSCALE_COUNTER3,
+};
+
+static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES]	    = XSCALE_PERFCTR_CCNT,
+	[PERF_COUNT_HW_INSTRUCTIONS]	    = XSCALE_PERFCTR_INSTRUCTION,
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_CACHE_MISSES]	    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
+	[PERF_COUNT_HW_BRANCH_MISSES]	    = XSCALE_PERFCTR_BRANCH_MISS,
+	[PERF_COUNT_HW_BUS_CYCLES]	    = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+					   [PERF_COUNT_HW_CACHE_OP_MAX]
+					   [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	[C(L1D)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= XSCALE_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= XSCALE_PERFCTR_DCACHE_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= XSCALE_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= XSCALE_PERFCTR_DCACHE_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(L1I)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= XSCALE_PERFCTR_ICACHE_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= XSCALE_PERFCTR_ICACHE_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(LL)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(DTLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= XSCALE_PERFCTR_DTLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= XSCALE_PERFCTR_DTLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(ITLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= XSCALE_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= XSCALE_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(BPU)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+};
+
+#define	XSCALE_PMU_ENABLE	0x001
+#define XSCALE_PMN_RESET	0x002
+#define	XSCALE_CCNT_RESET	0x004
+#define	XSCALE_PMU_RESET	(CCNT_RESET | PMN_RESET)
+#define XSCALE_PMU_CNT64	0x008
+
+static inline int
+xscalepmu_event_map(int config)
+{
+	int mapping = xscale_perf_map[config];
+	if (HW_OP_UNSUPPORTED == mapping)
+		mapping = -EOPNOTSUPP;
+	return mapping;
+}
+
+static u64
+xscalepmu_raw_event(u64 config)
+{
+	return config & 0xff;
+}
+
+#define XSCALE1_OVERFLOWED_MASK	0x700
+#define XSCALE1_CCOUNT_OVERFLOW	0x400
+#define XSCALE1_COUNT0_OVERFLOW	0x100
+#define XSCALE1_COUNT1_OVERFLOW	0x200
+#define XSCALE1_CCOUNT_INT_EN	0x040
+#define XSCALE1_COUNT0_INT_EN	0x010
+#define XSCALE1_COUNT1_INT_EN	0x020
+#define XSCALE1_COUNT0_EVT_SHFT	12
+#define XSCALE1_COUNT0_EVT_MASK	(0xff << XSCALE1_COUNT0_EVT_SHFT)
+#define XSCALE1_COUNT1_EVT_SHFT	20
+#define XSCALE1_COUNT1_EVT_MASK	(0xff << XSCALE1_COUNT1_EVT_SHFT)
+
+static inline u32
+xscale1pmu_read_pmnc(void)
+{
+	u32 val;
+	asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
+	return val;
+}
+
+static inline void
+xscale1pmu_write_pmnc(u32 val)
+{
+	/* upper 4bits and 7, 11 are write-as-0 */
+	val &= 0xffff77f;
+	asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
+}
+
+static inline int
+xscale1_pmnc_counter_has_overflowed(unsigned long pmnc,
+					enum xscale_counters counter)
+{
+	int ret = 0;
+
+	switch (counter) {
+	case XSCALE_CYCLE_COUNTER:
+		ret = pmnc & XSCALE1_CCOUNT_OVERFLOW;
+		break;
+	case XSCALE_COUNTER0:
+		ret = pmnc & XSCALE1_COUNT0_OVERFLOW;
+		break;
+	case XSCALE_COUNTER1:
+		ret = pmnc & XSCALE1_COUNT1_OVERFLOW;
+		break;
+	default:
+		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+	}
+
+	return ret;
+}
+
+static irqreturn_t
+xscale1pmu_handle_irq(int irq_num, void *dev)
+{
+	unsigned long pmnc;
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	struct pt_regs *regs;
+	int idx;
+
+	/*
+	 * NOTE: there's an A stepping erratum that states if an overflow
+	 *       bit already exists and another occurs, the previous
+	 *       Overflow bit gets cleared. There's no workaround.
+	 *	 Fixed in B stepping or later.
+	 */
+	pmnc = xscale1pmu_read_pmnc();
+
+	/*
+	 * Write the value back to clear the overflow flags. Overflow
+	 * flags remain in pmnc for use below. We also disable the PMU
+	 * while we process the interrupt.
+	 */
+	xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
+
+	if (!(pmnc & XSCALE1_OVERFLOWED_MASK))
+		return IRQ_NONE;
+
+	regs = get_irq_regs();
+
+	perf_sample_data_init(&data, 0);
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+	for (idx = 0; idx <= armpmu->num_events; ++idx) {
+		struct perf_event *event = cpuc->events[idx];
+		struct hw_perf_event *hwc;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+
+		if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
+			continue;
+
+		hwc = &event->hw;
+		armpmu_event_update(event, hwc, idx);
+		data.period = event->hw.last_period;
+		if (!armpmu_event_set_period(event, hwc, idx))
+			continue;
+
+		if (perf_event_overflow(event, 0, &data, regs))
+			armpmu->disable(hwc, idx);
+	}
+
+	perf_event_do_pending();
+
+	/*
+	 * Re-enable the PMU.
+	 */
+	pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
+	xscale1pmu_write_pmnc(pmnc);
+
+	return IRQ_HANDLED;
+}
+
+static void
+xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+	unsigned long val, mask, evt, flags;
+
+	switch (idx) {
+	case XSCALE_CYCLE_COUNTER:
+		mask = 0;
+		evt = XSCALE1_CCOUNT_INT_EN;
+		break;
+	case XSCALE_COUNTER0:
+		mask = XSCALE1_COUNT0_EVT_MASK;
+		evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
+			XSCALE1_COUNT0_INT_EN;
+		break;
+	case XSCALE_COUNTER1:
+		mask = XSCALE1_COUNT1_EVT_MASK;
+		evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
+			XSCALE1_COUNT1_INT_EN;
+		break;
+	default:
+		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+		return;
+	}
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = xscale1pmu_read_pmnc();
+	val &= ~mask;
+	val |= evt;
+	xscale1pmu_write_pmnc(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+	unsigned long val, mask, evt, flags;
+
+	switch (idx) {
+	case XSCALE_CYCLE_COUNTER:
+		mask = XSCALE1_CCOUNT_INT_EN;
+		evt = 0;
+		break;
+	case XSCALE_COUNTER0:
+		mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
+		evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
+		break;
+	case XSCALE_COUNTER1:
+		mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
+		evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
+		break;
+	default:
+		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+		return;
+	}
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = xscale1pmu_read_pmnc();
+	val &= ~mask;
+	val |= evt;
+	xscale1pmu_write_pmnc(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc,
+			struct hw_perf_event *event)
+{
+	if (XSCALE_PERFCTR_CCNT == event->config_base) {
+		if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
+			return -EAGAIN;
+
+		return XSCALE_CYCLE_COUNTER;
+	} else {
+		if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask)) {
+			return XSCALE_COUNTER1;
+		}
+
+		if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask)) {
+			return XSCALE_COUNTER0;
+		}
+
+		return -EAGAIN;
+	}
+}
+
+static void
+xscale1pmu_start(void)
+{
+	unsigned long flags, val;
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = xscale1pmu_read_pmnc();
+	val |= XSCALE_PMU_ENABLE;
+	xscale1pmu_write_pmnc(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale1pmu_stop(void)
+{
+	unsigned long flags, val;
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = xscale1pmu_read_pmnc();
+	val &= ~XSCALE_PMU_ENABLE;
+	xscale1pmu_write_pmnc(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline u32
+xscale1pmu_read_counter(int counter)
+{
+	u32 val = 0;
+
+	switch (counter) {
+	case XSCALE_CYCLE_COUNTER:
+		asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
+		break;
+	case XSCALE_COUNTER0:
+		asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
+		break;
+	case XSCALE_COUNTER1:
+		asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
+		break;
+	}
+
+	return val;
+}
+
+static inline void
+xscale1pmu_write_counter(int counter, u32 val)
+{
+	switch (counter) {
+	case XSCALE_CYCLE_COUNTER:
+		asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
+		break;
+	case XSCALE_COUNTER0:
+		asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
+		break;
+	case XSCALE_COUNTER1:
+		asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
+		break;
+	}
+}
+
+static const struct arm_pmu xscale1pmu = {
+	.id		= ARM_PERF_PMU_ID_XSCALE1,
+	.handle_irq	= xscale1pmu_handle_irq,
+	.enable		= xscale1pmu_enable_event,
+	.disable	= xscale1pmu_disable_event,
+	.event_map	= xscalepmu_event_map,
+	.raw_event	= xscalepmu_raw_event,
+	.read_counter	= xscale1pmu_read_counter,
+	.write_counter	= xscale1pmu_write_counter,
+	.get_event_idx	= xscale1pmu_get_event_idx,
+	.start		= xscale1pmu_start,
+	.stop		= xscale1pmu_stop,
+	.num_events	= 3,
+	.max_period	= (1LLU << 32) - 1,
+};
+
+#define XSCALE2_OVERFLOWED_MASK	0x01f
+#define XSCALE2_CCOUNT_OVERFLOW	0x001
+#define XSCALE2_COUNT0_OVERFLOW	0x002
+#define XSCALE2_COUNT1_OVERFLOW	0x004
+#define XSCALE2_COUNT2_OVERFLOW	0x008
+#define XSCALE2_COUNT3_OVERFLOW	0x010
+#define XSCALE2_CCOUNT_INT_EN	0x001
+#define XSCALE2_COUNT0_INT_EN	0x002
+#define XSCALE2_COUNT1_INT_EN	0x004
+#define XSCALE2_COUNT2_INT_EN	0x008
+#define XSCALE2_COUNT3_INT_EN	0x010
+#define XSCALE2_COUNT0_EVT_SHFT	0
+#define XSCALE2_COUNT0_EVT_MASK	(0xff << XSCALE2_COUNT0_EVT_SHFT)
+#define XSCALE2_COUNT1_EVT_SHFT	8
+#define XSCALE2_COUNT1_EVT_MASK	(0xff << XSCALE2_COUNT1_EVT_SHFT)
+#define XSCALE2_COUNT2_EVT_SHFT	16
+#define XSCALE2_COUNT2_EVT_MASK	(0xff << XSCALE2_COUNT2_EVT_SHFT)
+#define XSCALE2_COUNT3_EVT_SHFT	24
+#define XSCALE2_COUNT3_EVT_MASK	(0xff << XSCALE2_COUNT3_EVT_SHFT)
+
+static inline u32
+xscale2pmu_read_pmnc(void)
+{
+	u32 val;
+	asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
+	/* bits 1-2 and 4-23 are read-unpredictable */
+	return val & 0xff000009;
+}
+
+static inline void
+xscale2pmu_write_pmnc(u32 val)
+{
+	/* bits 4-23 are write-as-0, 24-31 are write ignored */
+	val &= 0xf;
+	asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
+}
+
+static inline u32
+xscale2pmu_read_overflow_flags(void)
+{
+	u32 val;
+	asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
+	return val;
+}
+
+static inline void
+xscale2pmu_write_overflow_flags(u32 val)
+{
+	asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
+}
+
+static inline u32
+xscale2pmu_read_event_select(void)
+{
+	u32 val;
+	asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
+	return val;
+}
+
+static inline void
+xscale2pmu_write_event_select(u32 val)
+{
+	asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
+}
+
+static inline u32
+xscale2pmu_read_int_enable(void)
+{
+	u32 val;
+	asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
+	return val;
+}
+
+static void
+xscale2pmu_write_int_enable(u32 val)
+{
+	asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
+}
+
+static inline int
+xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
+					enum xscale_counters counter)
+{
+	int ret = 0;
+
+	switch (counter) {
+	case XSCALE_CYCLE_COUNTER:
+		ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
+		break;
+	case XSCALE_COUNTER0:
+		ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
+		break;
+	case XSCALE_COUNTER1:
+		ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
+		break;
+	case XSCALE_COUNTER2:
+		ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
+		break;
+	case XSCALE_COUNTER3:
+		ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
+		break;
+	default:
+		WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+	}
+
+	return ret;
+}
+
+static irqreturn_t
+xscale2pmu_handle_irq(int irq_num, void *dev)
+{
+	unsigned long pmnc, of_flags;
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	struct pt_regs *regs;
+	int idx;
+
+	/* Disable the PMU. */
+	pmnc = xscale2pmu_read_pmnc();
+	xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
+
+	/* Check the overflow flag register. */
+	of_flags = xscale2pmu_read_overflow_flags();
+	if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
+		return IRQ_NONE;
+
+	/* Clear the overflow bits. */
+	xscale2pmu_write_overflow_flags(of_flags);
+
+	regs = get_irq_regs();
+
+	perf_sample_data_init(&data, 0);
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+	for (idx = 0; idx <= armpmu->num_events; ++idx) {
+		struct perf_event *event = cpuc->events[idx];
+		struct hw_perf_event *hwc;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+
+		if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx))
+			continue;
+
+		hwc = &event->hw;
+		armpmu_event_update(event, hwc, idx);
+		data.period = event->hw.last_period;
+		if (!armpmu_event_set_period(event, hwc, idx))
+			continue;
+
+		if (perf_event_overflow(event, 0, &data, regs))
+			armpmu->disable(hwc, idx);
+	}
+
+	perf_event_do_pending();
+
+	/*
+	 * Re-enable the PMU.
+	 */
+	pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
+	xscale2pmu_write_pmnc(pmnc);
+
+	return IRQ_HANDLED;
+}
+
+static void
+xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+	unsigned long flags, ien, evtsel;
+
+	ien = xscale2pmu_read_int_enable();
+	evtsel = xscale2pmu_read_event_select();
+
+	switch (idx) {
+	case XSCALE_CYCLE_COUNTER:
+		ien |= XSCALE2_CCOUNT_INT_EN;
+		break;
+	case XSCALE_COUNTER0:
+		ien |= XSCALE2_COUNT0_INT_EN;
+		evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
+		evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
+		break;
+	case XSCALE_COUNTER1:
+		ien |= XSCALE2_COUNT1_INT_EN;
+		evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
+		evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
+		break;
+	case XSCALE_COUNTER2:
+		ien |= XSCALE2_COUNT2_INT_EN;
+		evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
+		evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
+		break;
+	case XSCALE_COUNTER3:
+		ien |= XSCALE2_COUNT3_INT_EN;
+		evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
+		evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
+		break;
+	default:
+		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+		return;
+	}
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	xscale2pmu_write_event_select(evtsel);
+	xscale2pmu_write_int_enable(ien);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+	unsigned long flags, ien, evtsel;
+
+	ien = xscale2pmu_read_int_enable();
+	evtsel = xscale2pmu_read_event_select();
+
+	switch (idx) {
+	case XSCALE_CYCLE_COUNTER:
+		ien &= ~XSCALE2_CCOUNT_INT_EN;
+		break;
+	case XSCALE_COUNTER0:
+		ien &= ~XSCALE2_COUNT0_INT_EN;
+		evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
+		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
+		break;
+	case XSCALE_COUNTER1:
+		ien &= ~XSCALE2_COUNT1_INT_EN;
+		evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
+		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
+		break;
+	case XSCALE_COUNTER2:
+		ien &= ~XSCALE2_COUNT2_INT_EN;
+		evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
+		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
+		break;
+	case XSCALE_COUNTER3:
+		ien &= ~XSCALE2_COUNT3_INT_EN;
+		evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
+		evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
+		break;
+	default:
+		WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+		return;
+	}
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	xscale2pmu_write_event_select(evtsel);
+	xscale2pmu_write_int_enable(ien);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc,
+			struct hw_perf_event *event)
+{
+	int idx = xscale1pmu_get_event_idx(cpuc, event);
+	if (idx >= 0)
+		goto out;
+
+	if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
+		idx = XSCALE_COUNTER3;
+	else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
+		idx = XSCALE_COUNTER2;
+out:
+	return idx;
+}
+
+static void
+xscale2pmu_start(void)
+{
+	unsigned long flags, val;
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
+	val |= XSCALE_PMU_ENABLE;
+	xscale2pmu_write_pmnc(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale2pmu_stop(void)
+{
+	unsigned long flags, val;
+
+	spin_lock_irqsave(&pmu_lock, flags);
+	val = xscale2pmu_read_pmnc();
+	val &= ~XSCALE_PMU_ENABLE;
+	xscale2pmu_write_pmnc(val);
+	spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline u32
+xscale2pmu_read_counter(int counter)
+{
+	u32 val = 0;
+
+	switch (counter) {
+	case XSCALE_CYCLE_COUNTER:
+		asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
+		break;
+	case XSCALE_COUNTER0:
+		asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
+		break;
+	case XSCALE_COUNTER1:
+		asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
+		break;
+	case XSCALE_COUNTER2:
+		asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
+		break;
+	case XSCALE_COUNTER3:
+		asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
+		break;
+	}
+
+	return val;
+}
+
+static inline void
+xscale2pmu_write_counter(int counter, u32 val)
+{
+	switch (counter) {
+	case XSCALE_CYCLE_COUNTER:
+		asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
+		break;
+	case XSCALE_COUNTER0:
+		asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
+		break;
+	case XSCALE_COUNTER1:
+		asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
+		break;
+	case XSCALE_COUNTER2:
+		asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
+		break;
+	case XSCALE_COUNTER3:
+		asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
+		break;
+	}
+}
+
+static const struct arm_pmu xscale2pmu = {
+	.id		= ARM_PERF_PMU_ID_XSCALE2,
+	.handle_irq	= xscale2pmu_handle_irq,
+	.enable		= xscale2pmu_enable_event,
+	.disable	= xscale2pmu_disable_event,
+	.event_map	= xscalepmu_event_map,
+	.raw_event	= xscalepmu_raw_event,
+	.read_counter	= xscale2pmu_read_counter,
+	.write_counter	= xscale2pmu_write_counter,
+	.get_event_idx	= xscale2pmu_get_event_idx,
+	.start		= xscale2pmu_start,
+	.stop		= xscale2pmu_stop,
+	.num_events	= 5,
+	.max_period	= (1LLU << 32) - 1,
+};
+
 static int __init
 init_hw_perf_events(void)
 {
@@ -2086,7 +2924,7 @@
 	unsigned long implementor = (cpuid & 0xFF000000) >> 24;
 	unsigned long part_number = (cpuid & 0xFFF0);
 
-	/* We only support ARM CPUs implemented by ARM at the moment. */
+	/* ARM Ltd CPUs. */
 	if (0x41 == implementor) {
 		switch (part_number) {
 		case 0xB360:	/* ARM1136 */
@@ -2105,7 +2943,7 @@
 			perf_max_events = armv6mpcore_pmu.num_events;
 			break;
 		case 0xC080:	/* Cortex-A8 */
-			armv7pmu.name = ARMV7_PMU_CORTEX_A8_NAME;
+			armv7pmu.id = ARM_PERF_PMU_ID_CA8;
 			memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map,
 				sizeof(armv7_a8_perf_cache_map));
 			armv7pmu.event_map = armv7_a8_pmu_event_map;
@@ -2117,7 +2955,7 @@
 			perf_max_events = armv7pmu.num_events;
 			break;
 		case 0xC090:	/* Cortex-A9 */
-			armv7pmu.name = ARMV7_PMU_CORTEX_A9_NAME;
+			armv7pmu.id = ARM_PERF_PMU_ID_CA9;
 			memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map,
 				sizeof(armv7_a9_perf_cache_map));
 			armv7pmu.event_map = armv7_a9_pmu_event_map;
@@ -2128,15 +2966,33 @@
 			armv7pmu.num_events = armv7_reset_read_pmnc();
 			perf_max_events = armv7pmu.num_events;
 			break;
-		default:
-			pr_info("no hardware support available\n");
-			perf_max_events = -1;
+		}
+	/* Intel CPUs [xscale]. */
+	} else if (0x69 == implementor) {
+		part_number = (cpuid >> 13) & 0x7;
+		switch (part_number) {
+		case 1:
+			armpmu = &xscale1pmu;
+			memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
+					sizeof(xscale_perf_cache_map));
+			perf_max_events	= xscale1pmu.num_events;
+			break;
+		case 2:
+			armpmu = &xscale2pmu;
+			memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
+					sizeof(xscale_perf_cache_map));
+			perf_max_events	= xscale2pmu.num_events;
+			break;
 		}
 	}
 
-	if (armpmu)
+	if (armpmu) {
 		pr_info("enabled with %s PMU driver, %d counters available\n",
-			armpmu->name, armpmu->num_events);
+				arm_pmu_names[armpmu->id], armpmu->num_events);
+	} else {
+		pr_info("no hardware support available\n");
+		perf_max_events = -1;
+	}
 
 	return 0;
 }
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
index a124312..b8af96e 100644
--- a/arch/arm/kernel/pmu.c
+++ b/arch/arm/kernel/pmu.c
@@ -2,6 +2,7 @@
  *  linux/arch/arm/kernel/pmu.c
  *
  *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *  Copyright (C) 2010 ARM Ltd, Will Deacon
  *
  * 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
@@ -9,65 +10,78 @@
  *
  */
 
+#define pr_fmt(fmt) "PMU: " fmt
+
 #include <linux/cpumask.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include <asm/pmu.h>
 
-/*
- * Define the IRQs for the system. We could use something like a platform
- * device but that seems fairly heavyweight for this. Also, the performance
- * counters can't be removed or hotplugged.
- *
- * Ordering is important: init_pmu() will use the ordering to set the affinity
- * to the corresponding core. e.g. the first interrupt will go to cpu 0, the
- * second goes to cpu 1 etc.
- */
-static const int irqs[] = {
-#if defined(CONFIG_ARCH_OMAP2)
-	3,
-#elif defined(CONFIG_ARCH_BCMRING)
-	IRQ_PMUIRQ,
-#elif defined(CONFIG_MACH_REALVIEW_EB)
-	IRQ_EB11MP_PMU_CPU0,
-	IRQ_EB11MP_PMU_CPU1,
-	IRQ_EB11MP_PMU_CPU2,
-	IRQ_EB11MP_PMU_CPU3,
-#elif defined(CONFIG_ARCH_OMAP3)
-	INT_34XX_BENCH_MPU_EMUL,
-#elif defined(CONFIG_ARCH_IOP32X)
-	IRQ_IOP32X_CORE_PMU,
-#elif defined(CONFIG_ARCH_IOP33X)
-	IRQ_IOP33X_CORE_PMU,
-#elif defined(CONFIG_ARCH_PXA)
-	IRQ_PMU,
-#endif
-};
-
-static const struct pmu_irqs pmu_irqs = {
-	.irqs	    = irqs,
-	.num_irqs   = ARRAY_SIZE(irqs),
-};
-
 static volatile long pmu_lock;
 
-const struct pmu_irqs *
-reserve_pmu(void)
+static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES];
+
+static int __devinit pmu_device_probe(struct platform_device *pdev)
 {
-	return test_and_set_bit_lock(0, &pmu_lock) ? ERR_PTR(-EBUSY) :
-		&pmu_irqs;
+
+	if (pdev->id < 0 || pdev->id >= ARM_NUM_PMU_DEVICES) {
+		pr_warning("received registration request for unknown "
+				"device %d\n", pdev->id);
+		return -EINVAL;
+	}
+
+	if (pmu_devices[pdev->id])
+		pr_warning("registering new PMU device type %d overwrites "
+				"previous registration!\n", pdev->id);
+	else
+		pr_info("registered new PMU device of type %d\n",
+				pdev->id);
+
+	pmu_devices[pdev->id] = pdev;
+	return 0;
+}
+
+static struct platform_driver pmu_driver = {
+	.driver		= {
+		.name	= "arm-pmu",
+	},
+	.probe		= pmu_device_probe,
+};
+
+static int __init register_pmu_driver(void)
+{
+	return platform_driver_register(&pmu_driver);
+}
+device_initcall(register_pmu_driver);
+
+struct platform_device *
+reserve_pmu(enum arm_pmu_type device)
+{
+	struct platform_device *pdev;
+
+	if (test_and_set_bit_lock(device, &pmu_lock)) {
+		pdev = ERR_PTR(-EBUSY);
+	} else if (pmu_devices[device] == NULL) {
+		clear_bit_unlock(device, &pmu_lock);
+		pdev = ERR_PTR(-ENODEV);
+	} else {
+		pdev = pmu_devices[device];
+	}
+
+	return pdev;
 }
 EXPORT_SYMBOL_GPL(reserve_pmu);
 
 int
-release_pmu(const struct pmu_irqs *irqs)
+release_pmu(struct platform_device *pdev)
 {
-	if (WARN_ON(irqs != &pmu_irqs))
+	if (WARN_ON(pdev != pmu_devices[pdev->id]))
 		return -EINVAL;
-	clear_bit_unlock(0, &pmu_lock);
+	clear_bit_unlock(pdev->id, &pmu_lock);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(release_pmu);
@@ -87,17 +101,42 @@
 #endif
 }
 
-int
-init_pmu(void)
+static int
+init_cpu_pmu(void)
 {
 	int i, err = 0;
+	struct platform_device *pdev = pmu_devices[ARM_PMU_DEVICE_CPU];
 
-	for (i = 0; i < pmu_irqs.num_irqs; ++i) {
-		err = set_irq_affinity(pmu_irqs.irqs[i], i);
+	if (!pdev) {
+		err = -ENODEV;
+		goto out;
+	}
+
+	for (i = 0; i < pdev->num_resources; ++i) {
+		err = set_irq_affinity(platform_get_irq(pdev, i), i);
 		if (err)
 			break;
 	}
 
+out:
+	return err;
+}
+
+int
+init_pmu(enum arm_pmu_type device)
+{
+	int err = 0;
+
+	switch (device) {
+	case ARM_PMU_DEVICE_CPU:
+		err = init_cpu_pmu();
+		break;
+	default:
+		pr_warning("attempt to initialise unknown device %d\n",
+				device);
+		err = -EINVAL;
+	}
+
 	return err;
 }
 EXPORT_SYMBOL_GPL(init_pmu);
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index a01194e..b8c3d0f 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -168,7 +168,7 @@
 	struct task_struct *p;
 	int ret;
 
-	ret = mach_cpu_disable(cpu);
+	ret = platform_cpu_disable(cpu);
 	if (ret)
 		return ret;
 
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 2875380..38c261f 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -72,12 +72,15 @@
 EXPORT_SYMBOL(profile_pc);
 #endif
 
-#ifndef CONFIG_GENERIC_TIME
-static unsigned long dummy_gettimeoffset(void)
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+u32 arch_gettimeoffset(void)
 {
+	if (system_timer->offset != NULL)
+		return system_timer->offset() * 1000;
+
 	return 0;
 }
-#endif
+#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
 
 #ifdef CONFIG_LEDS_TIMER
 static inline void do_leds(void)
@@ -93,63 +96,6 @@
 #define	do_leds()
 #endif
 
-#ifndef CONFIG_GENERIC_TIME
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned long flags;
-	unsigned long seq;
-	unsigned long usec, sec;
-
-	do {
-		seq = read_seqbegin_irqsave(&xtime_lock, flags);
-		usec = system_timer->offset();
-		sec = xtime.tv_sec;
-		usec += xtime.tv_nsec / 1000;
-	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-	/* usec may have gone up a lot: be safe */
-	while (usec >= 1000000) {
-		usec -= 1000000;
-		sec++;
-	}
-
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
-	time_t wtm_sec, sec = tv->tv_sec;
-	long wtm_nsec, nsec = tv->tv_nsec;
-
-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-		return -EINVAL;
-
-	write_seqlock_irq(&xtime_lock);
-	/*
-	 * This is revolting. We need to set "xtime" correctly. However, the
-	 * value in this location is the value at the most recent update of
-	 * wall time.  Discover what correction gettimeofday() would have
-	 * done, and then undo it!
-	 */
-	nsec -= system_timer->offset() * NSEC_PER_USEC;
-
-	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-	set_normalized_timespec(&xtime, sec, nsec);
-	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-	ntp_clear();
-	write_sequnlock_irq(&xtime_lock);
-	clock_was_set();
-	return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-#endif /* !CONFIG_GENERIC_TIME */
 
 #ifndef CONFIG_GENERIC_CLOCKEVENTS
 /*
@@ -214,10 +160,6 @@
 
 void __init time_init(void)
 {
-#ifndef CONFIG_GENERIC_TIME
-	if (system_timer->offset == NULL)
-		system_timer->offset = dummy_gettimeoffset;
-#endif
 	system_timer->init();
 }
 
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 2db43a5..841eaf8 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -23,14 +23,12 @@
 config ARCH_AT91RM9200
 	bool "AT91RM9200"
 	select CPU_ARM920T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_AT91_USART3
 
 config ARCH_AT91SAM9260
 	bool "AT91SAM9260 or AT91SAM9XE"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_AT91_USART3
 	select HAVE_AT91_USART4
@@ -39,28 +37,24 @@
 config ARCH_AT91SAM9261
 	bool "AT91SAM9261"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9G10
 	bool "AT91SAM9G10"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9263
 	bool "AT91SAM9263"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9RL
 	bool "AT91SAM9RL"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_AT91_USART3
 	select HAVE_FB_ATMEL
@@ -68,7 +62,6 @@
 config ARCH_AT91SAM9G20
 	bool "AT91SAM9G20"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_AT91_USART3
 	select HAVE_AT91_USART4
@@ -77,7 +70,6 @@
 config ARCH_AT91SAM9G45
 	bool "AT91SAM9G45"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_AT91_USART3
 	select HAVE_FB_ATMEL
@@ -85,18 +77,17 @@
 config ARCH_AT91CAP9
 	bool "AT91CAP9"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select HAVE_FB_ATMEL
 
 config ARCH_AT572D940HF
 	bool "AT572D940HF"
 	select CPU_ARM926T
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 
 config ARCH_AT91X40
 	bool "AT91x40"
+	select ARCH_USES_GETTIMEOFFSET
 
 endchoice
 
@@ -360,6 +351,19 @@
 	  Select this if you are using a Eukrea Electromatique's
 	  CPU9G20 Board <http://www.eukrea.com/>
 
+config MACH_PORTUXG20
+	bool "taskit PortuxG20"
+	help
+	  Select this if you are using taskit's PortuxG20.
+	  <http://www.taskit.de/en/>
+
+config MACH_STAMP9G20
+	bool "taskit Stamp9G20 CPU module"
+	help
+	  Select this if you are using taskit's Stamp9G20 CPU module on its
+	  evaluation board.
+	  <http://www.taskit.de/en/>
+
 endif
 
 # ----------------------------------------------------------
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index d400455..c1f821e 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -63,6 +63,8 @@
 obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
 obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o
 obj-$(CONFIG_MACH_CPU9G20)	+= board-cpu9krea.o
+obj-$(CONFIG_MACH_STAMP9G20)	+= board-stamp9g20.o
+obj-$(CONFIG_MACH_PORTUXG20)	+= board-stamp9g20.o
 
 # AT91SAM9G45 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
new file mode 100644
index 0000000..8795827
--- /dev/null
+++ b/arch/arm/mach-at91/board-stamp9g20.c
@@ -0,0 +1,315 @@
+/*
+ *  Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de>
+ *                     taskit GmbH
+ *
+ * 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/mm.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/w1-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init portuxg20_map_io(void)
+{
+	/* Initialize processor: 18.432 MHz crystal */
+	at91sam9260_initialize(18432000);
+
+	/* DGBU on ttyS0. (Rx & Tx only) */
+	at91_register_uart(0, 0, 0);
+
+	/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+	at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+						| ATMEL_UART_DTR | ATMEL_UART_DSR
+						| ATMEL_UART_DCD | ATMEL_UART_RI);
+
+	/* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */
+	at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+	/* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */
+	at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+	/* USART4 on ttyS5. (Rx, Tx only) */
+	at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
+
+	/* USART5 on ttyS6. (Rx, Tx only) */
+	at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
+
+	/* set serial console to ttyS0 (ie, DBGU) */
+	at91_set_serial_console(0);
+}
+
+static void __init stamp9g20_map_io(void)
+{
+	/* Initialize processor: 18.432 MHz crystal */
+	at91sam9260_initialize(18432000);
+
+	/* DGBU on ttyS0. (Rx & Tx only) */
+	at91_register_uart(0, 0, 0);
+
+	/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+	at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+						| ATMEL_UART_DTR | ATMEL_UART_DSR
+						| ATMEL_UART_DCD | ATMEL_UART_RI);
+
+	/* set serial console to ttyS0 (ie, DBGU) */
+	at91_set_serial_console(0);
+}
+
+static void __init init_irq(void)
+{
+	at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * NAND flash
+ */
+static struct atmel_nand_data __initdata nand_data = {
+	.ale		= 21,
+	.cle		= 22,
+	.rdy_pin	= AT91_PIN_PC13,
+	.enable_pin	= AT91_PIN_PC14,
+	.bus_width_16	= 0,
+};
+
+static struct sam9_smc_config __initdata nand_smc_config = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 2,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 2,
+
+	.ncs_read_pulse		= 4,
+	.nrd_pulse		= 4,
+	.ncs_write_pulse	= 4,
+	.nwe_pulse		= 4,
+
+	.read_cycle		= 7,
+	.write_cycle		= 7,
+
+	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+	.tdf_cycles		= 3,
+};
+
+static void __init add_device_nand(void)
+{
+	/* configure chip-select 3 (NAND) */
+	sam9_smc_configure(3, &nand_smc_config);
+
+	at91_add_device_nand(&nand_data);
+}
+
+
+/*
+ * MCI (SD/MMC)
+ * det_pin, wp_pin and vcc_pin are not connected
+ */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static struct mci_platform_data __initdata mmc_data = {
+	.slot[0] = {
+		.bus_width	= 4,
+	},
+};
+#else
+static struct at91_mmc_data __initdata mmc_data = {
+	.slot_b		= 0,
+	.wire4		= 1,
+};
+#endif
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata usbh_data = {
+	.ports		= 2,
+};
+
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata portuxg20_udc_data = {
+	.vbus_pin	= AT91_PIN_PC7,
+	.pullup_pin	= 0,		/* pull-up driven by UDC */
+};
+
+static struct at91_udc_data __initdata stamp9g20_udc_data = {
+	.vbus_pin	= AT91_PIN_PA22,
+	.pullup_pin	= 0,		/* pull-up driven by UDC */
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata macb_data = {
+	.phy_irq_pin	= AT91_PIN_PA28,
+	.is_rmii	= 1,
+};
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led portuxg20_leds[] = {
+	{
+		.name			= "LED2",
+		.gpio			= AT91_PIN_PC5,
+		.default_trigger	= "none",
+	}, {
+		.name			= "LED3",
+		.gpio			= AT91_PIN_PC4,
+		.default_trigger	= "none",
+	}, {
+		.name			= "LED4",
+		.gpio			= AT91_PIN_PC10,
+		.default_trigger	= "heartbeat",
+	}
+};
+
+static struct gpio_led stamp9g20_leds[] = {
+	{
+		.name			= "D8",
+		.gpio			= AT91_PIN_PB18,
+		.active_low		= 1,
+		.default_trigger	= "none",
+	}, {
+		.name			= "D9",
+		.gpio			= AT91_PIN_PB19,
+		.active_low		= 1,
+		.default_trigger	= "none",
+	}, {
+		.name			= "D10",
+		.gpio			= AT91_PIN_PB20,
+		.active_low		= 1,
+		.default_trigger	= "heartbeat",
+	}
+};
+
+
+/*
+ * SPI devices
+ */
+static struct spi_board_info portuxg20_spi_devices[] = {
+	{
+		.modalias	= "spidev",
+		.chip_select	= 0,
+		.max_speed_hz	= 1 * 1000 * 1000,
+		.bus_num	= 0,
+	}, {
+		.modalias	= "spidev",
+		.chip_select	= 0,
+		.max_speed_hz	= 1 * 1000 * 1000,
+		.bus_num	= 1,
+	},
+};
+
+
+/*
+ * Dallas 1-Wire
+ */
+static struct w1_gpio_platform_data w1_gpio_pdata = {
+	.pin		= AT91_PIN_PA29,
+	.is_open_drain	= 1,
+};
+
+static struct platform_device w1_device = {
+	.name			= "w1-gpio",
+	.id			= -1,
+	.dev.platform_data	= &w1_gpio_pdata,
+};
+
+void add_w1(void)
+{
+	at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
+	at91_set_multi_drive(w1_gpio_pdata.pin, 1);
+	platform_device_register(&w1_device);
+}
+
+
+static void __init generic_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* NAND */
+	add_device_nand();
+	/* MMC */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+	at91_add_device_mci(0, &mmc_data);
+#else
+	at91_add_device_mmc(0, &mmc_data);
+#endif
+	/* USB Host */
+	at91_add_device_usbh(&usbh_data);
+	/* Ethernet */
+	at91_add_device_eth(&macb_data);
+	/* I2C */
+	at91_add_device_i2c(NULL, 0);
+	/* W1 */
+	add_w1();
+}
+
+static void __init portuxg20_board_init(void)
+{
+	generic_board_init();
+	/* SPI */
+	at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
+	/* USB Device */
+	at91_add_device_udc(&portuxg20_udc_data);
+	/* LEDs */
+	at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds));
+}
+
+static void __init stamp9g20_board_init(void)
+{
+	generic_board_init();
+	/* USB Device */
+	at91_add_device_udc(&stamp9g20_udc_data);
+	/* LEDs */
+	at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds));
+}
+
+MACHINE_START(PORTUXG20, "taskit PortuxG20")
+	/* Maintainer: taskit GmbH */
+	.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		= portuxg20_map_io,
+	.init_irq	= init_irq,
+	.init_machine	= portuxg20_board_init,
+MACHINE_END
+
+MACHINE_START(STAMP9G20, "taskit Stamp9G20")
+	/* Maintainer: taskit GmbH */
+	.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		= stamp9g20_map_io,
+	.init_irq	= init_irq,
+	.init_machine	= stamp9g20_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index ceaec6c..df2ed84 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -39,6 +39,7 @@
 #include <linux/usb/atmel_usba_udc.h>
 #include <linux/atmel-mci.h>
 #include <sound/atmel-ac97c.h>
+#include <linux/serial.h>
 
  /* USB Device */
 struct at91_udc_data {
@@ -143,9 +144,10 @@
 extern void __init __deprecated at91_init_serial(struct at91_uart_config *config);
 
 struct atmel_uart_data {
-	short		use_dma_tx;	/* use transmit DMA? */
-	short		use_dma_rx;	/* use receive DMA? */
-	void __iomem	*regs;		/* virtual base address, if any */
+	short			use_dma_tx;	/* use transmit DMA? */
+	short			use_dma_rx;	/* use receive DMA? */
+	void __iomem		*regs;		/* virt. base address, if any */
+	struct serial_rs485	rs485;		/* rs485 settings */
 };
 extern void __init at91_add_device_serial(void);
 
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 5a06501..833659d 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -21,7 +21,7 @@
 #define ARCH_ID_AT91SAM9260	0x019803a0
 #define ARCH_ID_AT91SAM9261	0x019703a0
 #define ARCH_ID_AT91SAM9263	0x019607a0
-#define ARCH_ID_AT91SAM9G10	0x819903a0
+#define ARCH_ID_AT91SAM9G10	0x019903a0
 #define ARCH_ID_AT91SAM9G20	0x019905a0
 #define ARCH_ID_AT91SAM9RL64	0x019b03a0
 #define ARCH_ID_AT91SAM9G45	0x819b05a0
@@ -108,7 +108,7 @@
 #endif
 
 #ifdef CONFIG_ARCH_AT91SAM9G10
-#define cpu_is_at91sam9g10()	(at91_cpu_identify() == ARCH_ID_AT91SAM9G10)
+#define cpu_is_at91sam9g10()	((at91_cpu_identify() & ~AT91_CIDR_EXT)	== ARCH_ID_AT91SAM9G10)
 #else
 #define cpu_is_at91sam9g10()	(0)
 #endif
diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h
index 5268af3..c80e090 100644
--- a/arch/arm/mach-at91/include/mach/system.h
+++ b/arch/arm/mach-at91/include/mach/system.h
@@ -24,21 +24,24 @@
 #include <mach/hardware.h>
 #include <mach/at91_st.h>
 #include <mach/at91_dbgu.h>
+#include <mach/at91_pmc.h>
 
 static inline void arch_idle(void)
 {
+#ifndef CONFIG_DEBUG_KERNEL
 	/*
 	 * Disable the processor clock.  The processor will be automatically
 	 * re-enabled by an interrupt or by a reset.
 	 */
-//	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-
+	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+#else
 	/*
 	 * Set the processor (CP15) into 'Wait for Interrupt' mode.
 	 * Unlike disabling the processor clock via the PMC (above)
 	 *  this allows the processor to be woken via JTAG.
 	 */
 	cpu_do_idle();
+#endif
 }
 
 void (*at91_arch_reset)(void);
diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c
index 53dd2a9..2f13919 100644
--- a/arch/arm/mach-bcmring/arch.c
+++ b/arch/arm/mach-bcmring/arch.c
@@ -29,6 +29,7 @@
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/time.h>
+#include <asm/pmu.h>
 
 #include <asm/mach/arch.h>
 #include <mach/dma.h>
@@ -85,8 +86,23 @@
 	.num_resources	= ARRAY_SIZE(nand_resource),
 };
 
+static struct resource pmu_resource = {
+	.start	= IRQ_PMUIRQ,
+	.end	= IRQ_PMUIRQ,
+	.flags	= IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+	.name		= "arm-pmu",
+	.id		= ARM_PMU_DEVICE_CPU,
+	.resource	= &pmu_resource,
+	.num_resources	= 1,
+};
+
+
 static struct platform_device *devices[] __initdata = {
 	&nand_device,
+	&pmu_device,
 };
 
 /****************************************************************************
diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
index a7b4591..9865921 100644
--- a/arch/arm/mach-clps711x/mm.c
+++ b/arch/arm/mach-clps711x/mm.c
@@ -22,7 +22,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/sizes.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig
new file mode 100644
index 0000000..9ebfcc4
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Kconfig
@@ -0,0 +1,12 @@
+menu "CNS3XXX platform type"
+	depends on ARCH_CNS3XXX
+
+config MACH_CNS3420VB
+	bool "Support for CNS3420 Validation Board"
+	help
+	  Include support for the Cavium Networks CNS3420 MPCore Platform
+	  Baseboard.
+	  This is a platform with an on-board ARM11 MPCore and has support
+	  for USB, USB-OTG, MMC/SD/SDIO, SATA, PCI-E, etc.
+
+endmenu
diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile
new file mode 100644
index 0000000..427507a
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARCH_CNS3XXX)		+= core.o pm.o
+obj-$(CONFIG_MACH_CNS3420VB)		+= cns3420vb.o
diff --git a/arch/arm/mach-cns3xxx/Makefile.boot b/arch/arm/mach-cns3xxx/Makefile.boot
new file mode 100644
index 0000000..7770128
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00C00000
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c
new file mode 100644
index 0000000..2e30c82
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
@@ -0,0 +1,148 @@
+/*
+ * Cavium Networks CNS3420 Validation Board
+ *
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2008 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *		  Scott Shu
+ * Copyright 2010 MontaVista Software, LLC.
+ *		  Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/io.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/hardware.h>
+#include <mach/cns3xxx.h>
+#include <mach/irqs.h>
+#include "core.h"
+
+/*
+ * NOR Flash
+ */
+static struct mtd_partition cns3420_nor_partitions[] = {
+	{
+		.name		= "uboot",
+		.size		= 0x00040000,
+		.offset		= 0,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "kernel",
+		.size		= 0x004C0000,
+		.offset		= MTDPART_OFS_APPEND,
+	}, {
+		.name		= "filesystem",
+		.size		= 0x7000000,
+		.offset		= MTDPART_OFS_APPEND,
+	}, {
+		.name		= "filesystem2",
+		.size		= 0x0AE0000,
+		.offset		= MTDPART_OFS_APPEND,
+	}, {
+		.name		= "ubootenv",
+		.size		= MTDPART_SIZ_FULL,
+		.offset		= MTDPART_OFS_APPEND,
+	},
+};
+
+static struct physmap_flash_data cns3420_nor_pdata = {
+	.width = 2,
+	.parts = cns3420_nor_partitions,
+	.nr_parts = ARRAY_SIZE(cns3420_nor_partitions),
+};
+
+static struct resource cns3420_nor_res = {
+	.start = CNS3XXX_FLASH_BASE,
+	.end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
+	.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+};
+
+static struct platform_device cns3420_nor_pdev = {
+	.name = "physmap-flash",
+	.id = 0,
+	.resource = &cns3420_nor_res,
+	.num_resources = 1,
+	.dev = {
+		.platform_data = &cns3420_nor_pdata,
+	},
+};
+
+/*
+ * UART
+ */
+static void __init cns3420_early_serial_setup(void)
+{
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	static struct uart_port cns3420_serial_port = {
+		.membase        = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
+		.mapbase        = CNS3XXX_UART0_BASE,
+		.irq            = IRQ_CNS3XXX_UART0,
+		.iotype         = UPIO_MEM,
+		.flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+		.regshift       = 2,
+		.uartclk        = 24000000,
+		.line           = 0,
+		.type           = PORT_16550A,
+		.fifosize       = 16,
+	};
+
+	early_serial_setup(&cns3420_serial_port);
+#endif
+}
+
+/*
+ * Initialization
+ */
+static struct platform_device *cns3420_pdevs[] __initdata = {
+	&cns3420_nor_pdev,
+};
+
+static void __init cns3420_init(void)
+{
+	platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs));
+
+	pm_power_off = cns3xxx_power_off;
+}
+
+static struct map_desc cns3420_io_desc[] __initdata = {
+	{
+		.virtual	= CNS3XXX_UART0_BASE_VIRT,
+		.pfn		= __phys_to_pfn(CNS3XXX_UART0_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+static void __init cns3420_map_io(void)
+{
+	cns3xxx_map_io();
+	iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc));
+
+	cns3420_early_serial_setup();
+}
+
+MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board")
+	.phys_io	= CNS3XXX_UART0_BASE,
+	.io_pg_offst	= (CNS3XXX_UART0_BASE_VIRT >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= cns3420_map_io,
+	.init_irq	= cns3xxx_init_irq,
+	.timer		= &cns3xxx_timer,
+	.init_machine	= cns3420_init,
+MACHINE_END
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
new file mode 100644
index 0000000..9ca4d58
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/core.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright 1999 - 2003 ARM Limited
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware/gic.h>
+#include <mach/cns3xxx.h>
+#include "core.h"
+
+static struct map_desc cns3xxx_io_desc[] __initdata = {
+	{
+		.virtual	= CNS3XXX_TC11MP_TWD_BASE_VIRT,
+		.pfn		= __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT,
+		.pfn		= __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT,
+		.pfn		= __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= CNS3XXX_TIMER1_2_3_BASE_VIRT,
+		.pfn		= __phys_to_pfn(CNS3XXX_TIMER1_2_3_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= CNS3XXX_GPIOA_BASE_VIRT,
+		.pfn		= __phys_to_pfn(CNS3XXX_GPIOA_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= CNS3XXX_GPIOB_BASE_VIRT,
+		.pfn		= __phys_to_pfn(CNS3XXX_GPIOB_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= CNS3XXX_MISC_BASE_VIRT,
+		.pfn		= __phys_to_pfn(CNS3XXX_MISC_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= CNS3XXX_PM_BASE_VIRT,
+		.pfn		= __phys_to_pfn(CNS3XXX_PM_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init cns3xxx_map_io(void)
+{
+	iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
+}
+
+/* used by entry-macro.S */
+void __iomem *gic_cpu_base_addr;
+
+void __init cns3xxx_init_irq(void)
+{
+	gic_cpu_base_addr = __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT);
+	gic_dist_init(0, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), 29);
+	gic_cpu_init(0, gic_cpu_base_addr);
+}
+
+void cns3xxx_power_off(void)
+{
+	u32 __iomem *pm_base = __io(CNS3XXX_PM_BASE_VIRT);
+	u32 clkctrl;
+
+	printk(KERN_INFO "powering system down...\n");
+
+	clkctrl = readl(pm_base + PM_SYS_CLK_CTRL_OFFSET);
+	clkctrl &= 0xfffff1ff;
+	clkctrl |= (0x5 << 9);		/* Hibernate */
+	writel(clkctrl, pm_base + PM_SYS_CLK_CTRL_OFFSET);
+
+}
+
+/*
+ * Timer
+ */
+static void __iomem *cns3xxx_tmr1;
+
+static void cns3xxx_timer_set_mode(enum clock_event_mode mode,
+				   struct clock_event_device *clk)
+{
+	unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+	int pclk = cns3xxx_cpu_clock() / 8;
+	int reload;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		reload = pclk * 20 / (3 * HZ) * 0x25000;
+		writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+		ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* period set, and timer enabled in 'next_event' hook */
+		ctrl |= (1 << 2) | (1 << 9);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	default:
+		ctrl = 0;
+	}
+
+	writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+}
+
+static int cns3xxx_timer_set_next_event(unsigned long evt,
+					struct clock_event_device *unused)
+{
+	unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+	writel(evt, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+	writel(ctrl | (1 << 0), cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+	return 0;
+}
+
+static struct clock_event_device cns3xxx_tmr1_clockevent = {
+	.name		= "cns3xxx timer1",
+	.shift		= 8,
+	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode	= cns3xxx_timer_set_mode,
+	.set_next_event	= cns3xxx_timer_set_next_event,
+	.rating		= 350,
+	.cpumask	= cpu_all_mask,
+};
+
+static void __init cns3xxx_clockevents_init(unsigned int timer_irq)
+{
+	cns3xxx_tmr1_clockevent.irq = timer_irq;
+	cns3xxx_tmr1_clockevent.mult =
+		div_sc((cns3xxx_cpu_clock() >> 3) * 1000000, NSEC_PER_SEC,
+		       cns3xxx_tmr1_clockevent.shift);
+	cns3xxx_tmr1_clockevent.max_delta_ns =
+		clockevent_delta2ns(0xffffffff, &cns3xxx_tmr1_clockevent);
+	cns3xxx_tmr1_clockevent.min_delta_ns =
+		clockevent_delta2ns(0xf, &cns3xxx_tmr1_clockevent);
+
+	clockevents_register_device(&cns3xxx_tmr1_clockevent);
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &cns3xxx_tmr1_clockevent;
+	u32 __iomem *stat = cns3xxx_tmr1 + TIMER1_2_INTERRUPT_STATUS_OFFSET;
+	u32 val;
+
+	/* Clear the interrupt */
+	val = readl(stat);
+	writel(val & ~(1 << 2), stat);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction cns3xxx_timer_irq = {
+	.name		= "timer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= cns3xxx_timer_interrupt,
+};
+
+/*
+ * Set up the clock source and clock events devices
+ */
+static void __init __cns3xxx_timer_init(unsigned int timer_irq)
+{
+	u32 val;
+	u32 irq_mask;
+
+	/*
+	 * Initialise to a known state (all timers off)
+	 */
+
+	/* disable timer1 and timer2 */
+	writel(0, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+	/* stop free running timer3 */
+	writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
+
+	/* timer1 */
+	writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
+	writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+
+	writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET);
+	writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET);
+
+	/* mask irq, non-mask timer1 overflow */
+	irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+	irq_mask &= ~(1 << 2);
+	irq_mask |= 0x03;
+	writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+
+	/* down counter */
+	val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+	val |= (1 << 9);
+	writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+	/* timer2 */
+	writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET);
+	writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET);
+
+	/* mask irq */
+	irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+	irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5));
+	writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+
+	/* down counter */
+	val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+	val |= (1 << 10);
+	writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+	/* Make irqs happen for the system timer */
+	setup_irq(timer_irq, &cns3xxx_timer_irq);
+
+	cns3xxx_clockevents_init(timer_irq);
+}
+
+static void __init cns3xxx_timer_init(void)
+{
+	cns3xxx_tmr1 = __io(CNS3XXX_TIMER1_2_3_BASE_VIRT);
+
+	__cns3xxx_timer_init(IRQ_CNS3XXX_TIMER0);
+}
+
+struct sys_timer cns3xxx_timer = {
+	.init = cns3xxx_timer_init,
+};
diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h
new file mode 100644
index 0000000..6b33ec1
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/core.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2004 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __CNS3XXX_CORE_H
+#define __CNS3XXX_CORE_H
+
+extern void __iomem *gic_cpu_base_addr;
+extern struct sys_timer cns3xxx_timer;
+
+void __init cns3xxx_map_io(void);
+void __init cns3xxx_init_irq(void);
+void cns3xxx_power_off(void);
+void cns3xxx_pwr_power_up(unsigned int block);
+void cns3xxx_pwr_power_down(unsigned int block);
+
+#endif /* __CNS3XXX_CORE_H */
diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
new file mode 100644
index 0000000..8a2f5a2
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
@@ -0,0 +1,635 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_BOARD_CNS3XXXH
+#define __MACH_BOARD_CNS3XXXH
+
+/*
+ * Memory map
+ */
+#define CNS3XXX_FLASH_BASE			0x10000000	/* Flash/SRAM Memory Bank 0 */
+#define CNS3XXX_FLASH_SIZE			SZ_256M
+
+#define CNS3XXX_DDR2SDRAM_BASE			0x20000000	/* DDR2 SDRAM Memory */
+
+#define CNS3XXX_SPI_FLASH_BASE			0x60000000	/* SPI Serial Flash Memory */
+
+#define CNS3XXX_SWITCH_BASE			0x70000000	/* Switch and HNAT Control */
+#define CNS3XXX_SWITCH_BASE_VIRT		0xFFF00000
+
+#define CNS3XXX_PPE_BASE			0x70001000	/* HANT	*/
+#define CNS3XXX_PPE_BASE_VIRT			0xFFF50000
+
+#define CNS3XXX_EMBEDDED_SRAM_BASE		0x70002000	/* HANT Embedded SRAM */
+#define CNS3XXX_EMBEDDED_SRAM_BASE_VIRT		0xFFF60000
+
+#define CNS3XXX_SSP_BASE			0x71000000	/* Synchronous Serial Port - SPI/PCM/I2C */
+#define CNS3XXX_SSP_BASE_VIRT			0xFFF01000
+
+#define CNS3XXX_DMC_BASE			0x72000000	/* DMC Control (DDR2 SDRAM) */
+#define CNS3XXX_DMC_BASE_VIRT			0xFFF02000
+
+#define CNS3XXX_SMC_BASE			0x73000000	/* SMC Control */
+#define CNS3XXX_SMC_BASE_VIRT			0xFFF03000
+
+#define SMC_MEMC_STATUS_OFFSET			0x000
+#define SMC_MEMIF_CFG_OFFSET			0x004
+#define SMC_MEMC_CFG_SET_OFFSET			0x008
+#define SMC_MEMC_CFG_CLR_OFFSET			0x00C
+#define SMC_DIRECT_CMD_OFFSET			0x010
+#define SMC_SET_CYCLES_OFFSET			0x014
+#define SMC_SET_OPMODE_OFFSET			0x018
+#define SMC_REFRESH_PERIOD_0_OFFSET		0x020
+#define SMC_REFRESH_PERIOD_1_OFFSET		0x024
+#define SMC_SRAM_CYCLES0_0_OFFSET		0x100
+#define SMC_NAND_CYCLES0_0_OFFSET		0x100
+#define SMC_OPMODE0_0_OFFSET			0x104
+#define SMC_SRAM_CYCLES0_1_OFFSET		0x120
+#define SMC_NAND_CYCLES0_1_OFFSET		0x120
+#define SMC_OPMODE0_1_OFFSET			0x124
+#define SMC_USER_STATUS_OFFSET			0x200
+#define SMC_USER_CONFIG_OFFSET			0x204
+#define SMC_ECC_STATUS_OFFSET			0x300
+#define SMC_ECC_MEMCFG_OFFSET			0x304
+#define SMC_ECC_MEMCOMMAND1_OFFSET		0x308
+#define SMC_ECC_MEMCOMMAND2_OFFSET		0x30C
+#define SMC_ECC_ADDR0_OFFSET			0x310
+#define SMC_ECC_ADDR1_OFFSET			0x314
+#define SMC_ECC_VALUE0_OFFSET			0x318
+#define SMC_ECC_VALUE1_OFFSET			0x31C
+#define SMC_ECC_VALUE2_OFFSET			0x320
+#define SMC_ECC_VALUE3_OFFSET			0x324
+#define SMC_PERIPH_ID_0_OFFSET			0xFE0
+#define SMC_PERIPH_ID_1_OFFSET			0xFE4
+#define SMC_PERIPH_ID_2_OFFSET			0xFE8
+#define SMC_PERIPH_ID_3_OFFSET			0xFEC
+#define SMC_PCELL_ID_0_OFFSET			0xFF0
+#define SMC_PCELL_ID_1_OFFSET			0xFF4
+#define SMC_PCELL_ID_2_OFFSET			0xFF8
+#define SMC_PCELL_ID_3_OFFSET			0xFFC
+
+#define CNS3XXX_GPIOA_BASE			0x74000000	/* GPIO port A */
+#define CNS3XXX_GPIOA_BASE_VIRT			0xFFF04000
+
+#define CNS3XXX_GPIOB_BASE			0x74800000	/* GPIO port B */
+#define CNS3XXX_GPIOB_BASE_VIRT			0xFFF05000
+
+#define CNS3XXX_RTC_BASE			0x75000000	/* Real Time Clock */
+#define CNS3XXX_RTC_BASE_VIRT			0xFFF06000
+
+#define RTC_SEC_OFFSET				0x00
+#define RTC_MIN_OFFSET				0x04
+#define RTC_HOUR_OFFSET				0x08
+#define RTC_DAY_OFFSET				0x0C
+#define RTC_SEC_ALM_OFFSET			0x10
+#define RTC_MIN_ALM_OFFSET			0x14
+#define RTC_HOUR_ALM_OFFSET			0x18
+#define RTC_REC_OFFSET				0x1C
+#define RTC_CTRL_OFFSET				0x20
+#define RTC_INTR_STS_OFFSET			0x34
+
+#define CNS3XXX_MISC_BASE			0x76000000	/* Misc Control */
+#define CNS3XXX_MISC_BASE_VIRT			0xFFF07000	/* Misc Control */
+
+#define CNS3XXX_PM_BASE				0x77000000	/* Power Management Control */
+#define CNS3XXX_PM_BASE_VIRT			0xFFF08000
+
+#define PM_CLK_GATE_OFFSET			0x00
+#define PM_SOFT_RST_OFFSET			0x04
+#define PM_HS_CFG_OFFSET			0x08
+#define PM_CACTIVE_STA_OFFSET			0x0C
+#define PM_PWR_STA_OFFSET			0x10
+#define PM_SYS_CLK_CTRL_OFFSET			0x14
+#define PM_PLL_LCD_I2S_CTRL_OFFSET		0x18
+#define PM_PLL_HM_PD_OFFSET			0x1C
+
+#define CNS3XXX_UART0_BASE			0x78000000	/* UART 0 */
+#define CNS3XXX_UART0_BASE_VIRT			0xFFF09000
+
+#define CNS3XXX_UART1_BASE			0x78400000	/* UART 1 */
+#define CNS3XXX_UART1_BASE_VIRT			0xFFF0A000
+
+#define CNS3XXX_UART2_BASE			0x78800000	/* UART 2 */
+#define CNS3XXX_UART2_BASE_VIRT			0xFFF0B000
+
+#define CNS3XXX_DMAC_BASE			0x79000000	/* Generic DMA Control */
+#define CNS3XXX_DMAC_BASE_VIRT			0xFFF0D000
+
+#define CNS3XXX_CORESIGHT_BASE			0x7A000000	/* CoreSight */
+#define CNS3XXX_CORESIGHT_BASE_VIRT		0xFFF0E000
+
+#define CNS3XXX_CRYPTO_BASE			0x7B000000	/* Crypto */
+#define CNS3XXX_CRYPTO_BASE_VIRT		0xFFF0F000
+
+#define CNS3XXX_I2S_BASE			0x7C000000	/* I2S */
+#define CNS3XXX_I2S_BASE_VIRT			0xFFF10000
+
+#define CNS3XXX_TIMER1_2_3_BASE			0x7C800000	/* Timer */
+#define CNS3XXX_TIMER1_2_3_BASE_VIRT		0xFFF10800
+
+#define TIMER1_COUNTER_OFFSET			0x00
+#define TIMER1_AUTO_RELOAD_OFFSET		0x04
+#define TIMER1_MATCH_V1_OFFSET			0x08
+#define TIMER1_MATCH_V2_OFFSET			0x0C
+
+#define TIMER2_COUNTER_OFFSET			0x10
+#define TIMER2_AUTO_RELOAD_OFFSET		0x14
+#define TIMER2_MATCH_V1_OFFSET			0x18
+#define TIMER2_MATCH_V2_OFFSET			0x1C
+
+#define TIMER1_2_CONTROL_OFFSET			0x30
+#define TIMER1_2_INTERRUPT_STATUS_OFFSET	0x34
+#define TIMER1_2_INTERRUPT_MASK_OFFSET		0x38
+
+#define TIMER_FREERUN_OFFSET			0x40
+#define TIMER_FREERUN_CONTROL_OFFSET		0x44
+
+#define CNS3XXX_HCIE_BASE			0x7D000000	/* HCIE Control */
+#define CNS3XXX_HCIE_BASE_VIRT			0xFFF30000
+
+#define CNS3XXX_RAID_BASE			0x7E000000	/* RAID Control */
+#define CNS3XXX_RAID_BASE_VIRT			0xFFF12000
+
+#define CNS3XXX_AXI_IXC_BASE			0x7F000000	/* AXI IXC */
+#define CNS3XXX_AXI_IXC_BASE_VIRT		0xFFF13000
+
+#define CNS3XXX_CLCD_BASE			0x80000000	/* LCD Control */
+#define CNS3XXX_CLCD_BASE_VIRT			0xFFF14000
+
+#define CNS3XXX_USBOTG_BASE			0x81000000	/* USB OTG Control */
+#define CNS3XXX_USBOTG_BASE_VIRT		0xFFF15000
+
+#define CNS3XXX_USB_BASE			0x82000000	/* USB Host Control */
+#define CNS3XXX_USB_BASE_VIRT			0xFFF16000
+
+#define CNS3XXX_SATA2_BASE			0x83000000	/* SATA */
+#define CNS3XXX_SATA2_SIZE			SZ_16M
+#define CNS3XXX_SATA2_BASE_VIRT			0xFFF17000
+
+#define CNS3XXX_CAMERA_BASE			0x84000000	/* Camera Interface */
+#define CNS3XXX_CAMERA_BASE_VIRT		0xFFF18000
+
+#define CNS3XXX_SDIO_BASE			0x85000000	/* SDIO */
+#define CNS3XXX_SDIO_BASE_VIRT			0xFFF19000
+
+#define CNS3XXX_I2S_TDM_BASE			0x86000000	/* I2S TDM */
+#define CNS3XXX_I2S_TDM_BASE_VIRT		0xFFF1A000
+
+#define CNS3XXX_2DG_BASE			0x87000000	/* 2D Graphic Control */
+#define CNS3XXX_2DG_BASE_VIRT			0xFFF1B000
+
+#define CNS3XXX_USB_OHCI_BASE			0x88000000	/* USB OHCI */
+#define CNS3XXX_USB_OHCI_BASE_VIRT		0xFFF1C000
+
+#define CNS3XXX_L2C_BASE			0x92000000	/* L2 Cache Control */
+#define CNS3XXX_L2C_BASE_VIRT			0xFFF27000
+
+#define CNS3XXX_PCIE0_MEM_BASE			0xA0000000	/* PCIe Port 0 IO/Memory Space */
+#define CNS3XXX_PCIE0_MEM_BASE_VIRT		0xE0000000
+
+#define CNS3XXX_PCIE0_HOST_BASE			0xAB000000	/* PCIe Port 0 RC Base */
+#define CNS3XXX_PCIE0_HOST_BASE_VIRT		0xE1000000
+
+#define CNS3XXX_PCIE0_IO_BASE			0xAC000000	/* PCIe Port 0 */
+#define CNS3XXX_PCIE0_IO_BASE_VIRT		0xE2000000
+
+#define CNS3XXX_PCIE0_CFG0_BASE			0xAD000000	/* PCIe Port 0 CFG Type 0 */
+#define CNS3XXX_PCIE0_CFG0_BASE_VIRT		0xE3000000
+
+#define CNS3XXX_PCIE0_CFG1_BASE			0xAE000000	/* PCIe Port 0 CFG Type 1 */
+#define CNS3XXX_PCIE0_CFG1_BASE_VIRT		0xE4000000
+
+#define CNS3XXX_PCIE0_MSG_BASE			0xAF000000	/* PCIe Port 0 Message Space */
+#define CNS3XXX_PCIE0_MSG_BASE_VIRT		0xE5000000
+
+#define CNS3XXX_PCIE1_MEM_BASE			0xB0000000	/* PCIe Port 1 IO/Memory Space */
+#define CNS3XXX_PCIE1_MEM_BASE_VIRT		0xE8000000
+
+#define CNS3XXX_PCIE1_HOST_BASE			0xBB000000	/* PCIe Port 1 RC Base */
+#define CNS3XXX_PCIE1_HOST_BASE_VIRT		0xE9000000
+
+#define CNS3XXX_PCIE1_IO_BASE			0xBC000000	/* PCIe Port 1 */
+#define CNS3XXX_PCIE1_IO_BASE_VIRT		0xEA000000
+
+#define CNS3XXX_PCIE1_CFG0_BASE			0xBD000000	/* PCIe Port 1 CFG Type 0 */
+#define CNS3XXX_PCIE1_CFG0_BASE_VIRT		0xEB000000
+
+#define CNS3XXX_PCIE1_CFG1_BASE			0xBE000000	/* PCIe Port 1 CFG Type 1 */
+#define CNS3XXX_PCIE1_CFG1_BASE_VIRT		0xEC000000
+
+#define CNS3XXX_PCIE1_MSG_BASE			0xBF000000	/* PCIe Port 1 Message Space */
+#define CNS3XXX_PCIE1_MSG_BASE_VIRT		0xED000000
+
+/*
+ * Testchip peripheral and fpga gic regions
+ */
+#define CNS3XXX_TC11MP_SCU_BASE			0x90000000	/* IRQ, Test chip */
+#define CNS3XXX_TC11MP_SCU_BASE_VIRT		0xFF000000
+
+#define CNS3XXX_TC11MP_GIC_CPU_BASE		0x90000100	/* Test chip interrupt controller CPU interface */
+#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT	0xFF000100
+
+#define CNS3XXX_TC11MP_TWD_BASE			0x90000600
+#define CNS3XXX_TC11MP_TWD_BASE_VIRT		0xFF000600
+
+#define CNS3XXX_TC11MP_GIC_DIST_BASE		0x90001000	/* Test chip interrupt controller distributor */
+#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT	0xFF001000
+
+#define CNS3XXX_TC11MP_L220_BASE		0x92002000	/* L220 registers */
+#define CNS3XXX_TC11MP_L220_BASE_VIRT		0xFF002000
+
+/*
+ * Misc block
+ */
+#define MISC_MEM_MAP(offs) (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + (offs))
+#define MISC_MEM_MAP_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_MISC_BASE_VIRT + (offset))))
+
+#define MISC_MEMORY_REMAP_REG			MISC_MEM_MAP_VALUE(0x00)
+#define MISC_CHIP_CONFIG_REG			MISC_MEM_MAP_VALUE(0x04)
+#define MISC_DEBUG_PROBE_DATA_REG		MISC_MEM_MAP_VALUE(0x08)
+#define MISC_DEBUG_PROBE_SELECTION_REG		MISC_MEM_MAP_VALUE(0x0C)
+#define MISC_IO_PIN_FUNC_SELECTION_REG		MISC_MEM_MAP_VALUE(0x10)
+#define MISC_GPIOA_PIN_ENABLE_REG		MISC_MEM_MAP_VALUE(0x14)
+#define MISC_GPIOB_PIN_ENABLE_REG		MISC_MEM_MAP_VALUE(0x18)
+#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_A	MISC_MEM_MAP_VALUE(0x1C)
+#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_B	MISC_MEM_MAP_VALUE(0x20)
+#define MISC_GPIOA_15_0_PULL_CTRL_REG		MISC_MEM_MAP_VALUE(0x24)
+#define MISC_GPIOA_16_31_PULL_CTRL_REG		MISC_MEM_MAP_VALUE(0x28)
+#define MISC_GPIOB_15_0_PULL_CTRL_REG		MISC_MEM_MAP_VALUE(0x2C)
+#define MISC_GPIOB_16_31_PULL_CTRL_REG		MISC_MEM_MAP_VALUE(0x30)
+#define MISC_IO_PULL_CTRL_REG			MISC_MEM_MAP_VALUE(0x34)
+#define MISC_E_FUSE_31_0_REG			MISC_MEM_MAP_VALUE(0x40)
+#define MISC_E_FUSE_63_32_REG			MISC_MEM_MAP_VALUE(0x44)
+#define MISC_E_FUSE_95_64_REG			MISC_MEM_MAP_VALUE(0x48)
+#define MISC_E_FUSE_127_96_REG			MISC_MEM_MAP_VALUE(0x4C)
+#define MISC_SOFTWARE_TEST_1_REG		MISC_MEM_MAP_VALUE(0x50)
+#define MISC_SOFTWARE_TEST_2_REG		MISC_MEM_MAP_VALUE(0x54)
+
+#define MISC_SATA_POWER_MODE			MISC_MEM_MAP_VALUE(0x310)
+
+#define MISC_USB_CFG_REG			MISC_MEM_MAP_VALUE(0x800)
+#define MISC_USB_STS_REG			MISC_MEM_MAP_VALUE(0x804)
+#define MISC_USBPHY00_CFG_REG			MISC_MEM_MAP_VALUE(0x808)
+#define MISC_USBPHY01_CFG_REG			MISC_MEM_MAP_VALUE(0x80c)
+#define MISC_USBPHY10_CFG_REG			MISC_MEM_MAP_VALUE(0x810)
+#define MISC_USBPHY11_CFG_REG			MISC_MEM_MAP_VALUE(0x814)
+
+#define MISC_PCIEPHY_CMCTL(x)			MISC_MEM_MAP(0x900 + (x) * 0x004)
+#define MISC_PCIEPHY_CTL(x)			MISC_MEM_MAP(0x940 + (x) * 0x100)
+#define MISC_PCIE_AXIS_AWMISC(x)		MISC_MEM_MAP(0x944 + (x) * 0x100)
+#define MISC_PCIE_AXIS_ARMISC(x)		MISC_MEM_MAP(0x948 + (x) * 0x100)
+#define MISC_PCIE_AXIS_RMISC(x)			MISC_MEM_MAP(0x94C + (x) * 0x100)
+#define MISC_PCIE_AXIS_BMISC(x)			MISC_MEM_MAP(0x950 + (x) * 0x100)
+#define MISC_PCIE_AXIM_RMISC(x)			MISC_MEM_MAP(0x954 + (x) * 0x100)
+#define MISC_PCIE_AXIM_BMISC(x)			MISC_MEM_MAP(0x958 + (x) * 0x100)
+#define MISC_PCIE_CTRL(x)			MISC_MEM_MAP(0x95C + (x) * 0x100)
+#define MISC_PCIE_PM_DEBUG(x)			MISC_MEM_MAP(0x960 + (x) * 0x100)
+#define MISC_PCIE_RFC_DEBUG(x)			MISC_MEM_MAP(0x964 + (x) * 0x100)
+#define MISC_PCIE_CXPL_DEBUGL(x)		MISC_MEM_MAP(0x968 + (x) * 0x100)
+#define MISC_PCIE_CXPL_DEBUGH(x)		MISC_MEM_MAP(0x96C + (x) * 0x100)
+#define MISC_PCIE_DIAG_DEBUGH(x)		MISC_MEM_MAP(0x970 + (x) * 0x100)
+#define MISC_PCIE_W1CLR(x)			MISC_MEM_MAP(0x974 + (x) * 0x100)
+#define MISC_PCIE_INT_MASK(x)			MISC_MEM_MAP(0x978 + (x) * 0x100)
+#define MISC_PCIE_INT_STATUS(x)			MISC_MEM_MAP(0x97C + (x) * 0x100)
+
+/*
+ * Power management and clock control
+ */
+#define PMU_REG_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_PM_BASE_VIRT + (offset))))
+
+#define PM_CLK_GATE_REG					PMU_REG_VALUE(0x000)
+#define PM_SOFT_RST_REG					PMU_REG_VALUE(0x004)
+#define PM_HS_CFG_REG					PMU_REG_VALUE(0x008)
+#define PM_CACTIVE_STA_REG				PMU_REG_VALUE(0x00C)
+#define PM_PWR_STA_REG					PMU_REG_VALUE(0x010)
+#define PM_CLK_CTRL_REG					PMU_REG_VALUE(0x014)
+#define PM_PLL_LCD_I2S_CTRL_REG				PMU_REG_VALUE(0x018)
+#define PM_PLL_HM_PD_CTRL_REG				PMU_REG_VALUE(0x01C)
+#define PM_REGULAT_CTRL_REG				PMU_REG_VALUE(0x020)
+#define PM_WDT_CTRL_REG					PMU_REG_VALUE(0x024)
+#define PM_WU_CTRL0_REG					PMU_REG_VALUE(0x028)
+#define PM_WU_CTRL1_REG					PMU_REG_VALUE(0x02C)
+#define PM_CSR_REG					PMU_REG_VALUE(0x030)
+
+/* PM_CLK_GATE_REG */
+#define PM_CLK_GATE_REG_OFFSET_SDIO			(25)
+#define PM_CLK_GATE_REG_OFFSET_GPU			(24)
+#define PM_CLK_GATE_REG_OFFSET_CIM			(23)
+#define PM_CLK_GATE_REG_OFFSET_LCDC			(22)
+#define PM_CLK_GATE_REG_OFFSET_I2S			(21)
+#define PM_CLK_GATE_REG_OFFSET_RAID			(20)
+#define PM_CLK_GATE_REG_OFFSET_SATA			(19)
+#define PM_CLK_GATE_REG_OFFSET_PCIE(x)			(17 + (x))
+#define PM_CLK_GATE_REG_OFFSET_USB_HOST			(16)
+#define PM_CLK_GATE_REG_OFFSET_USB_OTG			(15)
+#define PM_CLK_GATE_REG_OFFSET_TIMER			(14)
+#define PM_CLK_GATE_REG_OFFSET_CRYPTO			(13)
+#define PM_CLK_GATE_REG_OFFSET_HCIE			(12)
+#define PM_CLK_GATE_REG_OFFSET_SWITCH			(11)
+#define PM_CLK_GATE_REG_OFFSET_GPIO			(10)
+#define PM_CLK_GATE_REG_OFFSET_UART3			(9)
+#define PM_CLK_GATE_REG_OFFSET_UART2			(8)
+#define PM_CLK_GATE_REG_OFFSET_UART1			(7)
+#define PM_CLK_GATE_REG_OFFSET_RTC			(5)
+#define PM_CLK_GATE_REG_OFFSET_GDMA			(4)
+#define PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C		(3)
+#define PM_CLK_GATE_REG_OFFSET_SMC_NFI			(1)
+#define PM_CLK_GATE_REG_MASK				(0x03FFFFBA)
+
+/* PM_SOFT_RST_REG */
+#define PM_SOFT_RST_REG_OFFST_WARM_RST_FLAG		(31)
+#define PM_SOFT_RST_REG_OFFST_CPU1			(29)
+#define PM_SOFT_RST_REG_OFFST_CPU0			(28)
+#define PM_SOFT_RST_REG_OFFST_SDIO			(25)
+#define PM_SOFT_RST_REG_OFFST_GPU			(24)
+#define PM_SOFT_RST_REG_OFFST_CIM			(23)
+#define PM_SOFT_RST_REG_OFFST_LCDC			(22)
+#define PM_SOFT_RST_REG_OFFST_I2S			(21)
+#define PM_SOFT_RST_REG_OFFST_RAID			(20)
+#define PM_SOFT_RST_REG_OFFST_SATA			(19)
+#define PM_SOFT_RST_REG_OFFST_PCIE(x)			(17 + (x))
+#define PM_SOFT_RST_REG_OFFST_USB_HOST			(16)
+#define PM_SOFT_RST_REG_OFFST_USB_OTG			(15)
+#define PM_SOFT_RST_REG_OFFST_TIMER			(14)
+#define PM_SOFT_RST_REG_OFFST_CRYPTO			(13)
+#define PM_SOFT_RST_REG_OFFST_HCIE			(12)
+#define PM_SOFT_RST_REG_OFFST_SWITCH			(11)
+#define PM_SOFT_RST_REG_OFFST_GPIO			(10)
+#define PM_SOFT_RST_REG_OFFST_UART3			(9)
+#define PM_SOFT_RST_REG_OFFST_UART2			(8)
+#define PM_SOFT_RST_REG_OFFST_UART1			(7)
+#define PM_SOFT_RST_REG_OFFST_RTC			(5)
+#define PM_SOFT_RST_REG_OFFST_GDMA			(4)
+#define PM_SOFT_RST_REG_OFFST_SPI_PCM_I2C		(3)
+#define PM_SOFT_RST_REG_OFFST_DMC			(2)
+#define PM_SOFT_RST_REG_OFFST_SMC_NFI			(1)
+#define PM_SOFT_RST_REG_OFFST_GLOBAL			(0)
+#define PM_SOFT_RST_REG_MASK				(0xF3FFFFBF)
+
+/* PMHS_CFG_REG */
+#define PM_HS_CFG_REG_OFFSET_SDIO			(25)
+#define PM_HS_CFG_REG_OFFSET_GPU			(24)
+#define PM_HS_CFG_REG_OFFSET_CIM			(23)
+#define PM_HS_CFG_REG_OFFSET_LCDC			(22)
+#define PM_HS_CFG_REG_OFFSET_I2S			(21)
+#define PM_HS_CFG_REG_OFFSET_RAID			(20)
+#define PM_HS_CFG_REG_OFFSET_SATA			(19)
+#define PM_HS_CFG_REG_OFFSET_PCIE1			(18)
+#define PM_HS_CFG_REG_OFFSET_PCIE0			(17)
+#define PM_HS_CFG_REG_OFFSET_USB_HOST			(16)
+#define PM_HS_CFG_REG_OFFSET_USB_OTG			(15)
+#define PM_HS_CFG_REG_OFFSET_TIMER			(14)
+#define PM_HS_CFG_REG_OFFSET_CRYPTO			(13)
+#define PM_HS_CFG_REG_OFFSET_HCIE			(12)
+#define PM_HS_CFG_REG_OFFSET_SWITCH			(11)
+#define PM_HS_CFG_REG_OFFSET_GPIO			(10)
+#define PM_HS_CFG_REG_OFFSET_UART3			(9)
+#define PM_HS_CFG_REG_OFFSET_UART2			(8)
+#define PM_HS_CFG_REG_OFFSET_UART1			(7)
+#define PM_HS_CFG_REG_OFFSET_RTC			(5)
+#define PM_HS_CFG_REG_OFFSET_GDMA			(4)
+#define PM_HS_CFG_REG_OFFSET_SPI_PCM_I2S		(3)
+#define PM_HS_CFG_REG_OFFSET_DMC			(2)
+#define PM_HS_CFG_REG_OFFSET_SMC_NFI			(1)
+#define PM_HS_CFG_REG_MASK				(0x03FFFFBE)
+#define PM_HS_CFG_REG_MASK_SUPPORT			(0x01100806)
+
+/* PM_CACTIVE_STA_REG */
+#define PM_CACTIVE_STA_REG_OFFSET_SDIO			(25)
+#define PM_CACTIVE_STA_REG_OFFSET_GPU			(24)
+#define PM_CACTIVE_STA_REG_OFFSET_CIM			(23)
+#define PM_CACTIVE_STA_REG_OFFSET_LCDC			(22)
+#define PM_CACTIVE_STA_REG_OFFSET_I2S			(21)
+#define PM_CACTIVE_STA_REG_OFFSET_RAID			(20)
+#define PM_CACTIVE_STA_REG_OFFSET_SATA			(19)
+#define PM_CACTIVE_STA_REG_OFFSET_PCIE1			(18)
+#define PM_CACTIVE_STA_REG_OFFSET_PCIE0			(17)
+#define PM_CACTIVE_STA_REG_OFFSET_USB_HOST		(16)
+#define PM_CACTIVE_STA_REG_OFFSET_USB_OTG		(15)
+#define PM_CACTIVE_STA_REG_OFFSET_TIMER			(14)
+#define PM_CACTIVE_STA_REG_OFFSET_CRYPTO		(13)
+#define PM_CACTIVE_STA_REG_OFFSET_HCIE			(12)
+#define PM_CACTIVE_STA_REG_OFFSET_SWITCH		(11)
+#define PM_CACTIVE_STA_REG_OFFSET_GPIO			(10)
+#define PM_CACTIVE_STA_REG_OFFSET_UART3			(9)
+#define PM_CACTIVE_STA_REG_OFFSET_UART2			(8)
+#define PM_CACTIVE_STA_REG_OFFSET_UART1			(7)
+#define PM_CACTIVE_STA_REG_OFFSET_RTC			(5)
+#define PM_CACTIVE_STA_REG_OFFSET_GDMA			(4)
+#define PM_CACTIVE_STA_REG_OFFSET_SPI_PCM_I2S		(3)
+#define PM_CACTIVE_STA_REG_OFFSET_DMC			(2)
+#define PM_CACTIVE_STA_REG_OFFSET_SMC_NFI		(1)
+#define PM_CACTIVE_STA_REG_MASK				(0x03FFFFBE)
+
+/* PM_PWR_STA_REG */
+#define PM_PWR_STA_REG_REG_OFFSET_SDIO			(25)
+#define PM_PWR_STA_REG_REG_OFFSET_GPU			(24)
+#define PM_PWR_STA_REG_REG_OFFSET_CIM			(23)
+#define PM_PWR_STA_REG_REG_OFFSET_LCDC			(22)
+#define PM_PWR_STA_REG_REG_OFFSET_I2S			(21)
+#define PM_PWR_STA_REG_REG_OFFSET_RAID			(20)
+#define PM_PWR_STA_REG_REG_OFFSET_SATA			(19)
+#define PM_PWR_STA_REG_REG_OFFSET_PCIE1			(18)
+#define PM_PWR_STA_REG_REG_OFFSET_PCIE0			(17)
+#define PM_PWR_STA_REG_REG_OFFSET_USB_HOST		(16)
+#define PM_PWR_STA_REG_REG_OFFSET_USB_OTG		(15)
+#define PM_PWR_STA_REG_REG_OFFSET_TIMER			(14)
+#define PM_PWR_STA_REG_REG_OFFSET_CRYPTO		(13)
+#define PM_PWR_STA_REG_REG_OFFSET_HCIE			(12)
+#define PM_PWR_STA_REG_REG_OFFSET_SWITCH		(11)
+#define PM_PWR_STA_REG_REG_OFFSET_GPIO			(10)
+#define PM_PWR_STA_REG_REG_OFFSET_UART3			(9)
+#define PM_PWR_STA_REG_REG_OFFSET_UART2			(8)
+#define PM_PWR_STA_REG_REG_OFFSET_UART1			(7)
+#define PM_PWR_STA_REG_REG_OFFSET_RTC			(5)
+#define PM_PWR_STA_REG_REG_OFFSET_GDMA			(4)
+#define PM_PWR_STA_REG_REG_OFFSET_SPI_PCM_I2S		(3)
+#define PM_PWR_STA_REG_REG_OFFSET_DMC			(2)
+#define PM_PWR_STA_REG_REG_OFFSET_SMC_NFI		(1)
+#define PM_PWR_STA_REG_REG_MASK				(0x03FFFFBE)
+
+/* PM_CLK_CTRL_REG */
+#define PM_CLK_CTRL_REG_OFFSET_I2S_MCLK			(31)
+#define PM_CLK_CTRL_REG_OFFSET_DDR2_CHG_EN		(30)
+#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF1_EN		(29)
+#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF0_EN		(28)
+#define PM_CLK_CTRL_REG_OFFSET_TIMER_SIM_MODE		(27)
+#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_DIV		(24)
+#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_SEL		(22)
+#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_DIV		(20)
+#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_SEL		(16)
+#define PM_CLK_CTRL_REG_OFFSET_MDC_DIV			(14)
+#define PM_CLK_CTRL_REG_OFFSET_CRYPTO_CLK_SEL		(12)
+#define PM_CLK_CTRL_REG_OFFSET_CPU_PWR_MODE		(9)
+#define PM_CLK_CTRL_REG_OFFSET_PLL_DDR2_SEL		(7)
+#define PM_CLK_CTRL_REG_OFFSET_DIV_IMMEDIATE		(6)
+#define PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV		(4)
+#define PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL		(0)
+
+#define PM_CPU_CLK_DIV(DIV) { \
+	PM_CLK_CTRL_REG &= ~((0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \
+	PM_CLK_CTRL_REG |= (((DIV)&0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \
+}
+
+#define PM_PLL_CPU_SEL(CPU) { \
+	PM_CLK_CTRL_REG &= ~((0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \
+	PM_CLK_CTRL_REG |= (((CPU)&0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \
+}
+
+/* PM_PLL_LCD_I2S_CTRL_REG */
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_MCLK_SMC_DIV	(22)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_R_SEL		(17)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_P	(11)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_M	(3)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_S	(0)
+
+/* PM_PLL_HM_PD_CTRL_REG */
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1		(11)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0		(10)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2SCD		(6)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2S		(5)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_LCD		(4)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB		(3)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_RGMII		(2)
+#define PM_PLL_HM_PD_CTRL_REG_MASK			(0x00000C7C)
+
+/* PM_WDT_CTRL_REG */
+#define PM_WDT_CTRL_REG_OFFSET_RESET_CPU_ONLY		(0)
+
+/* PM_CSR_REG - Clock Scaling Register*/
+#define PM_CSR_REG_OFFSET_CSR_EN			(30)
+#define PM_CSR_REG_OFFSET_CSR_NUM			(0)
+
+#define CNS3XXX_PWR_CLK_EN(BLOCK) (0x1<<PM_CLK_GATE_REG_OFFSET_##BLOCK)
+
+/* Software reset*/
+#define CNS3XXX_PWR_SOFTWARE_RST(BLOCK) (0x1<<PM_SOFT_RST_REG_OFFST_##BLOCK)
+
+/*
+ * CNS3XXX support several power saving mode as following,
+ * DFS, IDLE, HALT, DOZE, SLEEP, Hibernate
+ */
+#define CNS3XXX_PWR_CPU_MODE_DFS			(0)
+#define CNS3XXX_PWR_CPU_MODE_IDLE			(1)
+#define CNS3XXX_PWR_CPU_MODE_HALT			(2)
+#define CNS3XXX_PWR_CPU_MODE_DOZE			(3)
+#define CNS3XXX_PWR_CPU_MODE_SLEEP			(4)
+#define CNS3XXX_PWR_CPU_MODE_HIBERNATE			(5)
+
+#define CNS3XXX_PWR_PLL(BLOCK)	(0x1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_##BLOCK)
+#define CNS3XXX_PWR_PLL_ALL	PM_PLL_HM_PD_CTRL_REG_MASK
+
+/* Change CPU frequency and divider */
+#define CNS3XXX_PWR_PLL_CPU_300MHZ			(0)
+#define CNS3XXX_PWR_PLL_CPU_333MHZ			(1)
+#define CNS3XXX_PWR_PLL_CPU_366MHZ			(2)
+#define CNS3XXX_PWR_PLL_CPU_400MHZ			(3)
+#define CNS3XXX_PWR_PLL_CPU_433MHZ			(4)
+#define CNS3XXX_PWR_PLL_CPU_466MHZ			(5)
+#define CNS3XXX_PWR_PLL_CPU_500MHZ			(6)
+#define CNS3XXX_PWR_PLL_CPU_533MHZ			(7)
+#define CNS3XXX_PWR_PLL_CPU_566MHZ			(8)
+#define CNS3XXX_PWR_PLL_CPU_600MHZ			(9)
+#define CNS3XXX_PWR_PLL_CPU_633MHZ			(10)
+#define CNS3XXX_PWR_PLL_CPU_666MHZ			(11)
+#define CNS3XXX_PWR_PLL_CPU_700MHZ			(12)
+
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY1			(0)
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY2			(1)
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY4			(2)
+
+/* Change DDR2 frequency */
+#define CNS3XXX_PWR_PLL_DDR2_200MHZ			(0)
+#define CNS3XXX_PWR_PLL_DDR2_266MHZ			(1)
+#define CNS3XXX_PWR_PLL_DDR2_333MHZ			(2)
+#define CNS3XXX_PWR_PLL_DDR2_400MHZ			(3)
+
+void cns3xxx_pwr_soft_rst(unsigned int block);
+void cns3xxx_pwr_clk_en(unsigned int block);
+int cns3xxx_cpu_clock(void);
+
+/*
+ * ARM11 MPCore interrupt sources (primary GIC)
+ */
+#define IRQ_CNS3XXX_PMU			(IRQ_TC11MP_GIC_START + 0)
+#define IRQ_CNS3XXX_SDIO		(IRQ_TC11MP_GIC_START + 1)
+#define IRQ_CNS3XXX_L2CC		(IRQ_TC11MP_GIC_START + 2)
+#define IRQ_CNS3XXX_RTC			(IRQ_TC11MP_GIC_START + 3)
+#define IRQ_CNS3XXX_I2S			(IRQ_TC11MP_GIC_START + 4)
+#define IRQ_CNS3XXX_PCM			(IRQ_TC11MP_GIC_START + 5)
+#define IRQ_CNS3XXX_SPI			(IRQ_TC11MP_GIC_START + 6)
+#define IRQ_CNS3XXX_I2C			(IRQ_TC11MP_GIC_START + 7)
+#define IRQ_CNS3XXX_CIM			(IRQ_TC11MP_GIC_START + 8)
+#define IRQ_CNS3XXX_GPU			(IRQ_TC11MP_GIC_START + 9)
+#define IRQ_CNS3XXX_LCD			(IRQ_TC11MP_GIC_START + 10)
+#define IRQ_CNS3XXX_GPIOA		(IRQ_TC11MP_GIC_START + 11)
+#define IRQ_CNS3XXX_GPIOB		(IRQ_TC11MP_GIC_START + 12)
+#define IRQ_CNS3XXX_UART0		(IRQ_TC11MP_GIC_START + 13)
+#define IRQ_CNS3XXX_UART1		(IRQ_TC11MP_GIC_START + 14)
+#define IRQ_CNS3XXX_UART2		(IRQ_TC11MP_GIC_START + 15)
+#define IRQ_CNS3XXX_ARM11		(IRQ_TC11MP_GIC_START + 16)
+
+#define IRQ_CNS3XXX_SW_STATUS		(IRQ_TC11MP_GIC_START + 17)
+#define IRQ_CNS3XXX_SW_R0TXC		(IRQ_TC11MP_GIC_START + 18)
+#define IRQ_CNS3XXX_SW_R0RXC		(IRQ_TC11MP_GIC_START + 19)
+#define IRQ_CNS3XXX_SW_R0QE		(IRQ_TC11MP_GIC_START + 20)
+#define IRQ_CNS3XXX_SW_R0QF		(IRQ_TC11MP_GIC_START + 21)
+#define IRQ_CNS3XXX_SW_R1TXC		(IRQ_TC11MP_GIC_START + 22)
+#define IRQ_CNS3XXX_SW_R1RXC		(IRQ_TC11MP_GIC_START + 23)
+#define IRQ_CNS3XXX_SW_R1QE		(IRQ_TC11MP_GIC_START + 24)
+#define IRQ_CNS3XXX_SW_R1QF		(IRQ_TC11MP_GIC_START + 25)
+#define IRQ_CNS3XXX_SW_PPE		(IRQ_TC11MP_GIC_START + 26)
+
+#define IRQ_CNS3XXX_CRYPTO		(IRQ_TC11MP_GIC_START + 27)
+#define IRQ_CNS3XXX_HCIE		(IRQ_TC11MP_GIC_START + 28)
+#define IRQ_CNS3XXX_PCIE0_DEVICE	(IRQ_TC11MP_GIC_START + 29)
+#define IRQ_CNS3XXX_PCIE1_DEVICE	(IRQ_TC11MP_GIC_START + 30)
+#define IRQ_CNS3XXX_USB_OTG		(IRQ_TC11MP_GIC_START + 31)
+#define IRQ_CNS3XXX_USB_EHCI		(IRQ_TC11MP_GIC_START + 32)
+#define IRQ_CNS3XXX_SATA		(IRQ_TC11MP_GIC_START + 33)
+#define IRQ_CNS3XXX_RAID		(IRQ_TC11MP_GIC_START + 34)
+#define IRQ_CNS3XXX_SMC			(IRQ_TC11MP_GIC_START + 35)
+
+#define IRQ_CNS3XXX_DMAC_ABORT		(IRQ_TC11MP_GIC_START + 36)
+#define IRQ_CNS3XXX_DMAC0		(IRQ_TC11MP_GIC_START + 37)
+#define IRQ_CNS3XXX_DMAC1		(IRQ_TC11MP_GIC_START + 38)
+#define IRQ_CNS3XXX_DMAC2		(IRQ_TC11MP_GIC_START + 39)
+#define IRQ_CNS3XXX_DMAC3		(IRQ_TC11MP_GIC_START + 40)
+#define IRQ_CNS3XXX_DMAC4		(IRQ_TC11MP_GIC_START + 41)
+#define IRQ_CNS3XXX_DMAC5		(IRQ_TC11MP_GIC_START + 42)
+#define IRQ_CNS3XXX_DMAC6		(IRQ_TC11MP_GIC_START + 43)
+#define IRQ_CNS3XXX_DMAC7		(IRQ_TC11MP_GIC_START + 44)
+#define IRQ_CNS3XXX_DMAC8		(IRQ_TC11MP_GIC_START + 45)
+#define IRQ_CNS3XXX_DMAC9		(IRQ_TC11MP_GIC_START + 46)
+#define IRQ_CNS3XXX_DMAC10		(IRQ_TC11MP_GIC_START + 47)
+#define IRQ_CNS3XXX_DMAC11		(IRQ_TC11MP_GIC_START + 48)
+#define IRQ_CNS3XXX_DMAC12		(IRQ_TC11MP_GIC_START + 49)
+#define IRQ_CNS3XXX_DMAC13		(IRQ_TC11MP_GIC_START + 50)
+#define IRQ_CNS3XXX_DMAC14		(IRQ_TC11MP_GIC_START + 51)
+#define IRQ_CNS3XXX_DMAC15		(IRQ_TC11MP_GIC_START + 52)
+#define IRQ_CNS3XXX_DMAC16		(IRQ_TC11MP_GIC_START + 53)
+#define IRQ_CNS3XXX_DMAC17		(IRQ_TC11MP_GIC_START + 54)
+
+#define IRQ_CNS3XXX_PCIE0_RC		(IRQ_TC11MP_GIC_START + 55)
+#define IRQ_CNS3XXX_PCIE1_RC		(IRQ_TC11MP_GIC_START + 56)
+#define IRQ_CNS3XXX_TIMER0		(IRQ_TC11MP_GIC_START + 57)
+#define IRQ_CNS3XXX_TIMER1		(IRQ_TC11MP_GIC_START + 58)
+#define IRQ_CNS3XXX_USB_OHCI		(IRQ_TC11MP_GIC_START + 59)
+#define IRQ_CNS3XXX_TIMER2		(IRQ_TC11MP_GIC_START + 60)
+#define IRQ_CNS3XXX_EXTERNAL_PIN0	(IRQ_TC11MP_GIC_START + 61)
+#define IRQ_CNS3XXX_EXTERNAL_PIN1	(IRQ_TC11MP_GIC_START + 62)
+#define IRQ_CNS3XXX_EXTERNAL_PIN2	(IRQ_TC11MP_GIC_START + 63)
+
+#define NR_IRQS_CNS3XXX			(IRQ_TC11MP_GIC_START + 64)
+
+#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_CNS3XXX)
+#undef NR_IRQS
+#define NR_IRQS				NR_IRQS_CNS3XXX
+#endif
+
+#endif	/* __MACH_BOARD_CNS3XXX_H */
diff --git a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
new file mode 100644
index 0000000..d16ce7e
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
@@ -0,0 +1,21 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright 1994-1999 Russell King
+ * Copyright 2008 Cavium Networks
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx,      #0x10000000
+		movne	\rx,      #0xf0000000	@ virtual base
+		orr	\rx, \rx, #0x00009000
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
new file mode 100644
index 0000000..5e1c554
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
@@ -0,0 +1,82 @@
+/*
+ * Low-level IRQ helper macros for Cavium Networks platforms
+ *
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 <mach/hardware.h>
+#include <asm/hardware/gic.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro  get_irqnr_preamble, base, tmp
+		ldr	\base, =gic_cpu_base_addr
+		ldr	\base, [\base]
+		.endm
+
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
+
+		/*
+		 * The interrupt numbering scheme is defined in the
+		 * interrupt controller spec.  To wit:
+		 *
+		 * Interrupts 0-15 are IPI
+		 * 16-28 are reserved
+		 * 29-31 are local.  We allow 30 to be used for the watchdog.
+		 * 32-1020 are global
+		 * 1021-1022 are reserved
+		 * 1023 is "spurious" (no interrupt)
+		 *
+		 * For now, we ignore all local interrupts so only return an interrupt if it's
+		 * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
+		 *
+		 * A simple read from the controller will tell us the number of the highest
+                 * priority enabled interrupt.  We then just need to check whether it is in the
+		 * valid range for an IRQ (30-1020 inclusive).
+		 */
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+		ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
+
+		ldr	\tmp, =1021
+
+		bic     \irqnr, \irqstat, #0x1c00
+
+		cmp     \irqnr, #29
+		cmpcc	\irqnr, \irqnr
+		cmpne	\irqnr, \tmp
+		cmpcs	\irqnr, \irqnr
+
+		.endm
+
+		/* We assume that irqstat (the raw value of the IRQ acknowledge
+		 * register) is preserved from the macro above.
+		 * If there is an IPI, we immediately signal end of interrupt on the
+		 * controller, since this requires the original irqstat value which
+		 * we won't easily be able to recreate later.
+		 */
+
+		.macro test_for_ipi, irqnr, irqstat, base, tmp
+		bic	\irqnr, \irqstat, #0x1c00
+		cmp	\irqnr, #16
+		strcc	\irqstat, [\base, #GIC_CPU_EOI]
+		cmpcs	\irqnr, \irqnr
+		.endm
+
+		/* As above, this assumes that irqstat and base are preserved.. */
+
+		.macro test_for_ltirq, irqnr, irqstat, base, tmp
+		bic	\irqnr, \irqstat, #0x1c00
+		mov 	\tmp, #0
+		cmp	\irqnr, #29
+		moveq	\tmp, #1
+		streq	\irqstat, [\base, #GIC_CPU_EOI]
+		cmp	\tmp, #0
+		.endm
diff --git a/arch/arm/mach-cns3xxx/include/mach/hardware.h b/arch/arm/mach-cns3xxx/include/mach/hardware.h
new file mode 100644
index 0000000..57e0983
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/hardware.h
@@ -0,0 +1,22 @@
+/*
+ * This file contains the hardware definitions of the Cavium Networks boards.
+ *
+ * Copyright 2003 ARM Limited.
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/* macro to get at IO space when running virtually */
+#define PCIBIOS_MIN_IO		0x00000000
+#define PCIBIOS_MIN_MEM		0x00000000
+#define pcibios_assign_all_busses()	1
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/io.h b/arch/arm/mach-cns3xxx/include/mach/io.h
new file mode 100644
index 0000000..33b6fc1
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/io.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2008 Cavium Networks
+ * Copyright 2003 ARM Limited
+ *
+ * This file 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 __MACH_IO_H
+#define __MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)			__typesafe_io(a)
+#define __mem_pci(a)		(a)
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/irqs.h b/arch/arm/mach-cns3xxx/include/mach/irqs.h
new file mode 100644
index 0000000..2ab96f8
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/irqs.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd.
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+#define IRQ_LOCALTIMER		29
+#define IRQ_LOCALWDOG		30
+#define IRQ_TC11MP_GIC_START	32
+
+#include <mach/cns3xxx.h>
+
+#ifndef NR_IRQS
+#error "NR_IRQS not defined by the board-specific files"
+#endif
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/memory.h b/arch/arm/mach-cns3xxx/include/mach/memory.h
new file mode 100644
index 0000000..3b6b769
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/memory.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET		UL(0x00000000)
+
+#define __phys_to_bus(x)	((x) + PHYS_OFFSET)
+#define __bus_to_phys(x)	((x) - PHYS_OFFSET)
+
+#define __virt_to_bus(v)	__phys_to_bus(__virt_to_phys(v))
+#define __bus_to_virt(b)	__phys_to_virt(__bus_to_phys(b))
+#define __pfn_to_bus(p)		__phys_to_bus(__pfn_to_phys(p))
+#define __bus_to_pfn(b)		__phys_to_pfn(__bus_to_phys(b))
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h
new file mode 100644
index 0000000..58bb03a
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/system.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/timex.h b/arch/arm/mach-cns3xxx/include/mach/timex.h
new file mode 100644
index 0000000..1fd0421
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/timex.h
@@ -0,0 +1,12 @@
+/*
+ * Cavium Networks architecture timex specifications
+ *
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#define CLOCK_TICK_RATE		(50000000 / 16)
diff --git a/arch/arm/mach-cns3xxx/include/mach/uncompress.h b/arch/arm/mach-cns3xxx/include/mach/uncompress.h
new file mode 100644
index 0000000..de8ead9
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/uncompress.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/cns3xxx.h>
+
+#define AMBA_UART_DR(base)	(*(volatile unsigned char *)((base) + 0x00))
+#define AMBA_UART_LCRH(base)	(*(volatile unsigned char *)((base) + 0x2c))
+#define AMBA_UART_CR(base)	(*(volatile unsigned char *)((base) + 0x30))
+#define AMBA_UART_FR(base)	(*(volatile unsigned char *)((base) + 0x18))
+
+/*
+ * Return the UART base address
+ */
+static inline unsigned long get_uart_base(void)
+{
+	if (machine_is_cns3420vb())
+		return CNS3XXX_UART0_BASE;
+	else
+		return 0;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+	unsigned long base = get_uart_base();
+
+	while (AMBA_UART_FR(base) & (1 << 5))
+		barrier();
+
+	AMBA_UART_DR(base) = c;
+}
+
+static inline void flush(void)
+{
+	unsigned long base = get_uart_base();
+
+	while (AMBA_UART_FR(base) & (1 << 3))
+		barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-cns3xxx/include/mach/vmalloc.h b/arch/arm/mach-cns3xxx/include/mach/vmalloc.h
new file mode 100644
index 0000000..4d381ec
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/vmalloc.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2000 Russell King.
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#define VMALLOC_END		0xd8000000
diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c
new file mode 100644
index 0000000..725e1a4
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/pm.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 <mach/system.h>
+#include <mach/cns3xxx.h>
+
+void cns3xxx_pwr_clk_en(unsigned int block)
+{
+	PM_CLK_GATE_REG |= (block & PM_CLK_GATE_REG_MASK);
+}
+
+void cns3xxx_pwr_power_up(unsigned int block)
+{
+	PM_PLL_HM_PD_CTRL_REG &= ~(block & CNS3XXX_PWR_PLL_ALL);
+
+	/* Wait for 300us for the PLL output clock locked. */
+	udelay(300);
+};
+
+void cns3xxx_pwr_power_down(unsigned int block)
+{
+	/* write '1' to power down */
+	PM_PLL_HM_PD_CTRL_REG |= (block & CNS3XXX_PWR_PLL_ALL);
+};
+
+static void cns3xxx_pwr_soft_rst_force(unsigned int block)
+{
+	/*
+	 * bit 0, 28, 29 => program low to reset,
+	 * the other else program low and then high
+	 */
+	if (block & 0x30000001) {
+		PM_SOFT_RST_REG &= ~(block & PM_SOFT_RST_REG_MASK);
+	} else {
+		PM_SOFT_RST_REG &= ~(block & PM_SOFT_RST_REG_MASK);
+		PM_SOFT_RST_REG |= (block & PM_SOFT_RST_REG_MASK);
+	}
+}
+
+void cns3xxx_pwr_soft_rst(unsigned int block)
+{
+	static unsigned int soft_reset;
+
+	if (soft_reset & block) {
+		/* SPI/I2C/GPIO use the same block, reset once. */
+		return;
+	} else {
+		soft_reset |= block;
+	}
+	cns3xxx_pwr_soft_rst_force(block);
+}
+
+void arch_reset(char mode, const char *cmd)
+{
+	/*
+	 * To reset, we hit the on-board reset register
+	 * in the system FPGA.
+	 */
+	cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(GLOBAL));
+}
+
+/*
+ * cns3xxx_cpu_clock - return CPU/L2 clock
+ *  aclk: cpu clock/2
+ *  hclk: cpu clock/4
+ *  pclk: cpu clock/8
+ */
+int cns3xxx_cpu_clock(void)
+{
+	int cpu;
+	int cpu_sel;
+	int div_sel;
+
+	cpu_sel = (PM_CLK_CTRL_REG >> PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL) & 0xf;
+	div_sel = (PM_CLK_CTRL_REG >> PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV) & 0x3;
+
+	cpu = (300 + ((cpu_sel / 3) * 100) + ((cpu_sel % 3) * 33)) >> div_sel;
+
+	return cpu;
+}
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index caf6d51..3a1a855 100644
--- a/arch/arm/mach-ep93xx/adssphere.c
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -41,7 +41,7 @@
 	.resource	= &adssphere_flash_resource,
 };
 
-static struct ep93xx_eth_data adssphere_eth_data = {
+static struct ep93xx_eth_data __initdata adssphere_eth_data = {
 	.phy_id		= 1,
 };
 
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 5f80092..e29bdef 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -96,6 +96,10 @@
 	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
 	.set_rate	= set_keytchclk_rate,
 };
+static struct clk clk_spi = {
+	.parent		= &clk_xtali,
+	.rate		= EP93XX_EXT_CLK_RATE,
+};
 static struct clk clk_pwm = {
 	.parent		= &clk_xtali,
 	.rate		= EP93XX_EXT_CLK_RATE,
@@ -186,6 +190,7 @@
 	INIT_CK("ep93xx-ohci",		NULL,		&clk_usb_host),
 	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
 	INIT_CK("ep93xx-fb",		NULL,		&clk_video),
+	INIT_CK("ep93xx-spi.0",		NULL,		&clk_spi),
 	INIT_CK(NULL,			"pwm_clk",	&clk_pwm),
 	INIT_CK(NULL,			"m2p0",		&clk_m2p0),
 	INIT_CK(NULL,			"m2p1",		&clk_m2p1),
@@ -473,6 +478,14 @@
 	/* Initialize the pll2 derived clocks */
 	clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
 
+	/*
+	 * EP93xx SSP clock rate was doubled in version E2. For more information
+	 * see:
+	 *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
+	 */
+	if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
+		clk_spi.rate /= 2;
+
 	pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
 		clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
 	pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 90fb591..9092677 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -31,10 +31,12 @@
 #include <linux/amba/serial.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/spi/spi.h>
 
 #include <mach/hardware.h>
 #include <mach/fb.h>
 #include <mach/ep93xx_keypad.h>
+#include <mach/ep93xx_spi.h>
 
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -222,6 +224,20 @@
 }
 EXPORT_SYMBOL(ep93xx_devcfg_set_clear);
 
+/**
+ * ep93xx_chip_revision() - returns the EP93xx chip revision
+ *
+ * See <mach/platform.h> for more information.
+ */
+unsigned int ep93xx_chip_revision(void)
+{
+	unsigned int v;
+
+	v = __raw_readl(EP93XX_SYSCON_SYSCFG);
+	v &= EP93XX_SYSCON_SYSCFG_REV_MASK;
+	v >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT;
+	return v;
+}
 
 /*************************************************************************
  * EP93xx peripheral handling
@@ -330,6 +346,10 @@
 	.resource	= ep93xx_ohci_resources,
 };
 
+
+/*************************************************************************
+ * EP93xx ethernet peripheral handling
+ *************************************************************************/
 static struct ep93xx_eth_data ep93xx_eth_data;
 
 static struct resource ep93xx_eth_resource[] = {
@@ -354,6 +374,12 @@
 	.resource	= ep93xx_eth_resource,
 };
 
+/**
+ * ep93xx_register_eth - Register the built-in ethernet platform device.
+ * @data:	platform specific ethernet configuration (__initdata)
+ * @copy_addr:	flag indicating that the MAC address should be copied
+ *		from the IndAd registers (as programmed by the bootloader)
+ */
 void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
 {
 	if (copy_addr)
@@ -370,11 +396,19 @@
 static struct i2c_gpio_platform_data ep93xx_i2c_data;
 
 static struct platform_device ep93xx_i2c_device = {
-	.name			= "i2c-gpio",
-	.id			= 0,
-	.dev.platform_data	= &ep93xx_i2c_data,
+	.name		= "i2c-gpio",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &ep93xx_i2c_data,
+	},
 };
 
+/**
+ * ep93xx_register_i2c - Register the i2c platform device.
+ * @data:	platform specific i2c-gpio configuration (__initdata)
+ * @devices:	platform specific i2c bus device information (__initdata)
+ * @num:	the number of devices on the i2c bus
+ */
 void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
 				struct i2c_board_info *devices, int num)
 {
@@ -398,17 +432,67 @@
 	platform_device_register(&ep93xx_i2c_device);
 }
 
+/*************************************************************************
+ * EP93xx SPI peripheral handling
+ *************************************************************************/
+static struct ep93xx_spi_info ep93xx_spi_master_data;
+
+static struct resource ep93xx_spi_resources[] = {
+	{
+		.start	= EP93XX_SPI_PHYS_BASE,
+		.end	= EP93XX_SPI_PHYS_BASE + 0x18 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_EP93XX_SSP,
+		.end	= IRQ_EP93XX_SSP,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ep93xx_spi_device = {
+	.name		= "ep93xx-spi",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &ep93xx_spi_master_data,
+	},
+	.num_resources	= ARRAY_SIZE(ep93xx_spi_resources),
+	.resource	= ep93xx_spi_resources,
+};
+
+/**
+ * ep93xx_register_spi() - registers spi platform device
+ * @info: ep93xx board specific spi master info (__initdata)
+ * @devices: SPI devices to register (__initdata)
+ * @num: number of SPI devices to register
+ *
+ * This function registers platform device for the EP93xx SPI controller and
+ * also makes sure that SPI pins are muxed so that I2S is not using those pins.
+ */
+void __init ep93xx_register_spi(struct ep93xx_spi_info *info,
+				struct spi_board_info *devices, int num)
+{
+	/*
+	 * When SPI is used, we need to make sure that I2S is muxed off from
+	 * SPI pins.
+	 */
+	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2SONSSP);
+
+	ep93xx_spi_master_data = *info;
+	spi_register_board_info(devices, num);
+	platform_device_register(&ep93xx_spi_device);
+}
 
 /*************************************************************************
  * EP93xx LEDs
  *************************************************************************/
 static struct gpio_led ep93xx_led_pins[] = {
 	{
-		.name			= "platform:grled",
-		.gpio			= EP93XX_GPIO_LINE_GRLED,
+		.name	= "platform:grled",
+		.gpio	= EP93XX_GPIO_LINE_GRLED,
 	}, {
-		.name			= "platform:rdled",
-		.gpio			= EP93XX_GPIO_LINE_RDLED,
+		.name	= "platform:rdled",
+		.gpio	= EP93XX_GPIO_LINE_RDLED,
 	},
 };
 
@@ -528,7 +612,7 @@
 	.name			= "ep93xx-fb",
 	.id			= -1,
 	.dev			= {
-		.platform_data	= &ep93xxfb_data,
+		.platform_data		= &ep93xxfb_data,
 		.coherent_dma_mask	= DMA_BIT_MASK(32),
 		.dma_mask		= &ep93xx_fb_device.dev.coherent_dma_mask,
 	},
@@ -536,6 +620,10 @@
 	.resource		= ep93xx_fb_resource,
 };
 
+/**
+ * ep93xx_register_fb - Register the framebuffer platform device.
+ * @data:	platform specific framebuffer configuration (__initdata)
+ */
 void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
 {
 	ep93xxfb_data = *data;
@@ -546,6 +634,8 @@
 /*************************************************************************
  * EP93xx matrix keypad peripheral handling
  *************************************************************************/
+static struct ep93xx_keypad_platform_data ep93xx_keypad_data;
+
 static struct resource ep93xx_keypad_resource[] = {
 	{
 		.start	= EP93XX_KEY_MATRIX_PHYS_BASE,
@@ -559,15 +649,22 @@
 };
 
 static struct platform_device ep93xx_keypad_device = {
-	.name			= "ep93xx-keypad",
-	.id			= -1,
-	.num_resources		= ARRAY_SIZE(ep93xx_keypad_resource),
-	.resource		= ep93xx_keypad_resource,
+	.name		= "ep93xx-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &ep93xx_keypad_data,
+	},
+	.num_resources	= ARRAY_SIZE(ep93xx_keypad_resource),
+	.resource	= ep93xx_keypad_resource,
 };
 
+/**
+ * ep93xx_register_keypad - Register the keypad platform device.
+ * @data:	platform specific keypad configuration (__initdata)
+ */
 void __init ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data)
 {
-	ep93xx_keypad_device.dev.platform_data = data;
+	ep93xx_keypad_data = *data;
 	platform_device_register(&ep93xx_keypad_device);
 }
 
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index d22d67a..3884182 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -74,7 +74,7 @@
 	}
 }
 
-static struct ep93xx_eth_data edb93xx_eth_data = {
+static struct ep93xx_eth_data __initdata edb93xx_eth_data = {
 	.phy_id		= 1,
 };
 
@@ -82,7 +82,7 @@
 /*************************************************************************
  * EDB93xx i2c peripheral handling
  *************************************************************************/
-static struct i2c_gpio_platform_data edb93xx_i2c_gpio_data = {
+static struct i2c_gpio_platform_data __initdata edb93xx_i2c_gpio_data = {
 	.sda_pin		= EP93XX_GPIO_LINE_EEDAT,
 	.sda_is_open_drain	= 0,
 	.scl_pin		= EP93XX_GPIO_LINE_EECLK,
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index 3da7ca8..a809618 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -41,7 +41,7 @@
 	.resource	= &gesbc9312_flash_resource,
 };
 
-static struct ep93xx_eth_data gesbc9312_eth_data = {
+static struct ep93xx_eth_data __initdata gesbc9312_eth_data = {
 	.phy_id		= 1,
 };
 
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index 93e2ecc..b1e096f 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -106,6 +106,7 @@
 
 #define EP93XX_AAC_BASE			EP93XX_APB_IOMEM(0x00080000)
 
+#define EP93XX_SPI_PHYS_BASE		EP93XX_APB_PHYS(0x000a0000)
 #define EP93XX_SPI_BASE			EP93XX_APB_IOMEM(0x000a0000)
 
 #define EP93XX_IRDA_BASE		EP93XX_APB_IOMEM(0x000b0000)
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index c6dc14db..9a4413d 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -6,9 +6,11 @@
 
 struct i2c_gpio_platform_data;
 struct i2c_board_info;
+struct spi_board_info;
 struct platform_device;
 struct ep93xxfb_mach_info;
 struct ep93xx_keypad_platform_data;
+struct ep93xx_spi_info;
 
 struct ep93xx_eth_data
 {
@@ -33,9 +35,19 @@
 	ep93xx_devcfg_set_clear(0x00, bits);
 }
 
+#define EP93XX_CHIP_REV_D0	3
+#define EP93XX_CHIP_REV_D1	4
+#define EP93XX_CHIP_REV_E0	5
+#define EP93XX_CHIP_REV_E1	6
+#define EP93XX_CHIP_REV_E2	7
+
+unsigned int ep93xx_chip_revision(void);
+
 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);
+void ep93xx_register_spi(struct ep93xx_spi_info *info,
+			 struct spi_board_info *devices, int num);
 void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
 void ep93xx_register_pwm(int pwm0, int pwm1);
 int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index c33360e8..1cc911b 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -80,7 +80,7 @@
 /*************************************************************************
  * Micro9 Ethernet
  *************************************************************************/
-static struct ep93xx_eth_data micro9_eth_data = {
+static struct ep93xx_eth_data __initdata micro9_eth_data = {
 	.phy_id		= 0x1f,
 };
 
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index cd93990..388aec9 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -49,17 +49,17 @@
 	},
 };
 
-static struct ep93xx_eth_data simone_eth_data = {
+static struct ep93xx_eth_data __initdata simone_eth_data = {
 	.phy_id		= 1,
 };
 
-static struct ep93xxfb_mach_info simone_fb_info = {
+static struct ep93xxfb_mach_info __initdata simone_fb_info = {
 	.num_modes	= EP93XXFB_USE_MODEDB,
 	.bpp		= 16,
 	.flags		= EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
 };
 
-static struct i2c_gpio_platform_data simone_i2c_gpio_data = {
+static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
 	.sda_pin		= EP93XX_GPIO_LINE_EEDAT,
 	.sda_is_open_drain	= 0,
 	.scl_pin		= EP93XX_GPIO_LINE_EECLK,
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
index 51134b0..38deaee 100644
--- a/arch/arm/mach-ep93xx/snappercl15.c
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -125,11 +125,11 @@
 	.num_resources		= ARRAY_SIZE(snappercl15_nand_resource),
 };
 
-static struct ep93xx_eth_data snappercl15_eth_data = {
+static struct ep93xx_eth_data __initdata snappercl15_eth_data = {
 	.phy_id			= 1,
 };
 
-static struct i2c_gpio_platform_data snappercl15_i2c_gpio_data = {
+static struct i2c_gpio_platform_data __initdata snappercl15_i2c_gpio_data = {
 	.sda_pin		= EP93XX_GPIO_LINE_EEDAT,
 	.sda_is_open_drain	= 0,
 	.scl_pin		= EP93XX_GPIO_LINE_EECLK,
@@ -145,7 +145,7 @@
 	},
 };
 
-static struct ep93xxfb_mach_info snappercl15_fb_info = {
+static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = {
 	.num_modes		= EP93XXFB_USE_MODEDB,
 	.bpp			= 16,
 };
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index fac1ec7..9553031 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -186,7 +186,7 @@
 	.resource	= ts72xx_wdt_resources,
 };
 
-static struct ep93xx_eth_data ts72xx_eth_data = {
+static struct ep93xx_eth_data __initdata ts72xx_eth_data = {
 	.phy_id		= 1,
 };
 
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index df97d16..27db275 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -11,6 +11,7 @@
 config ARCH_INTEGRATOR_CP
 	bool "Support Integrator/CP platform"
 	select ARCH_CINTEGRATOR
+	select ARM_TIMER_SP804
 	help
 	  Include support for the ARM(R) Integrator CP platform.
 
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
index 6a5ef8d..ebeef96 100644
--- a/arch/arm/mach-integrator/Makefile
+++ b/arch/arm/mach-integrator/Makefile
@@ -4,7 +4,7 @@
 
 # Object file lists.
 
-obj-y					:= clock.o core.o lm.o
+obj-y					:= core.o lm.o
 obj-$(CONFIG_ARCH_INTEGRATOR_AP)	+= integrator_ap.o
 obj-$(CONFIG_ARCH_INTEGRATOR_CP)	+= integrator_cp.o
 
diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c
deleted file mode 100644
index 989ecf5f..0000000
--- a/arch/arm/mach-integrator/clock.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  linux/arch/arm/mach-integrator/clock.c
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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/kernel.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-
-#include <asm/clkdev.h>
-#include <mach/clkdev.h>
-
-int clk_enable(struct clk *clk)
-{
-	return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	struct icst525_vco vco;
-	vco = icst525_khz_to_vco(clk->params, rate / 1000);
-	return icst525_khz(clk->params, vco) * 1000;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -EIO;
-
-	if (clk->setvco) {
-		struct icst525_vco vco;
-
-		vco = icst525_khz_to_vco(clk->params, rate / 1000);
-		clk->rate = icst525_khz(clk->params, vco) * 1000;
-		clk->setvco(clk, vco);
-		ret = 0;
-	}
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
deleted file mode 100644
index 609c49d..0000000
--- a/arch/arm/mach-integrator/common.h
+++ /dev/null
@@ -1,2 +0,0 @@
-extern void integrator_time_init(unsigned long, unsigned int);
-extern unsigned long integrator_gettimeoffset(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8b390e3..b02cfc0 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -24,15 +24,13 @@
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/irq.h>
-#include <asm/hardware/arm_timer.h>
 #include <mach/cm.h>
 #include <asm/system.h>
 #include <asm/leds.h>
 #include <asm/mach/time.h>
 
-#include "common.h"
-
 static struct amba_pl010_data integrator_uart_data;
 
 static struct amba_device rtc_device = {
@@ -163,8 +161,8 @@
  *  UART0  7    6
  *  UART1  5    4
  */
-#define SC_CTRLC	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
-#define SC_CTRLS	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+#define SC_CTRLC	IO_ADDRESS(INTEGRATOR_SC_CTRLC)
+#define SC_CTRLS	IO_ADDRESS(INTEGRATOR_SC_CTRLS)
 
 static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)
 {
@@ -196,7 +194,7 @@
 	.set_mctrl = integrator_uart_set_mctrl,
 };
 
-#define CM_CTRL	IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET
+#define CM_CTRL	IO_ADDRESS(INTEGRATOR_HDR_CTRL)
 
 static DEFINE_SPINLOCK(cm_lock);
 
@@ -217,120 +215,3 @@
 }
 
 EXPORT_SYMBOL(cm_control);
-
-/*
- * Where is the timer (VA)?
- */
-#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000)
-#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100)
-#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200)
-#define VA_IC_BASE     IO_ADDRESS(INTEGRATOR_IC_BASE) 
-
-/*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TICKS2USECS(x)	(256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)
-#else
-#define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
-#endif
-
-static unsigned long timer_reload;
-
-/*
- * Returns number of ms since last clock interrupt.  Note that interrupts
- * will have been disabled by do_gettimeoffset()
- */
-unsigned long integrator_gettimeoffset(void)
-{
-	unsigned long ticks1, ticks2, status;
-
-	/*
-	 * Get the current number of ticks.  Note that there is a race
-	 * condition between us reading the timer and checking for
-	 * an interrupt.  We get around this by ensuring that the
-	 * counter has not reloaded between our two reads.
-	 */
-	ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
-	do {
-		ticks1 = ticks2;
-		status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
-		ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
-	} while (ticks2 > ticks1);
-
-	/*
-	 * Number of ticks since last interrupt.
-	 */
-	ticks1 = timer_reload - ticks2;
-
-	/*
-	 * Interrupt pending?  If so, we've reloaded once already.
-	 */
-	if (status & (1 << IRQ_TIMERINT1))
-		ticks1 += timer_reload;
-
-	/*
-	 * Convert the ticks to usecs
-	 */
-	return TICKS2USECS(ticks1);
-}
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t
-integrator_timer_interrupt(int irq, void *dev_id)
-{
-	/*
-	 * clear the interrupt
-	 */
-	writel(1, TIMER1_VA_BASE + TIMER_INTCLR);
-
-	timer_tick();
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction integrator_timer_irq = {
-	.name		= "Integrator Timer Tick",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= integrator_timer_interrupt,
-};
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
-{
-	unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
-
-	timer_reload = reload;
-	timer_ctrl |= ctrl;
-
-	if (timer_reload > 0x100000) {
-		timer_reload >>= 8;
-		timer_ctrl |= TIMER_CTRL_DIV256;
-	} else if (timer_reload > 0x010000) {
-		timer_reload >>= 4;
-		timer_ctrl |= TIMER_CTRL_DIV16;
-	}
-
-	/*
-	 * Initialise to a known state (all timers off)
-	 */
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
-	writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD);
-	writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE);
-	writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL);
-
-	/*
-	 * Make irqs happen for the system timer
-	 */
-	setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
-}
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
index f77f202..a3fbcb3a 100644
--- a/arch/arm/mach-integrator/cpu.c
+++ b/arch/arm/mach-integrator/cpu.c
@@ -19,32 +19,39 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/icst525.h>
+#include <asm/hardware/icst.h>
 
 static struct cpufreq_driver integrator_driver;
 
-#define CM_ID  	(IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_ID_OFFSET)
-#define CM_OSC	(IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_OSC_OFFSET)
-#define CM_STAT (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_STAT_OFFSET)
-#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
+#define CM_ID  	IO_ADDRESS(INTEGRATOR_HDR_ID)
+#define CM_OSC	IO_ADDRESS(INTEGRATOR_HDR_OSC)
+#define CM_STAT IO_ADDRESS(INTEGRATOR_HDR_STAT)
+#define CM_LOCK IO_ADDRESS(INTEGRATOR_HDR_LOCK)
 
-static const struct icst525_params lclk_params = {
-	.ref		= 24000,
-	.vco_max	= 320000,
+static const struct icst_params lclk_params = {
+	.ref		= 24000000,
+	.vco_max	= ICST525_VCO_MAX_5V,
+	.vco_min	= ICST525_VCO_MIN,
 	.vd_min		= 8,
 	.vd_max		= 132,
 	.rd_min		= 24,
 	.rd_max		= 24,
+	.s2div		= icst525_s2div,
+	.idx2s		= icst525_idx2s,
 };
 
-static const struct icst525_params cclk_params = {
-	.ref		= 24000,
-	.vco_max	= 320000,
+static const struct icst_params cclk_params = {
+	.ref		= 24000000,
+	.vco_max	= ICST525_VCO_MAX_5V,
+	.vco_min	= ICST525_VCO_MIN,
 	.vd_min		= 12,
 	.vd_max		= 160,
 	.rd_min		= 24,
 	.rd_max		= 24,
+	.s2div		= icst525_s2div,
+	.idx2s		= icst525_idx2s,
 };
 
 /*
@@ -52,17 +59,17 @@
  */
 static int integrator_verify_policy(struct cpufreq_policy *policy)
 {
-	struct icst525_vco vco;
+	struct icst_vco vco;
 
 	cpufreq_verify_within_limits(policy, 
 				     policy->cpuinfo.min_freq, 
 				     policy->cpuinfo.max_freq);
 
-	vco = icst525_khz_to_vco(&cclk_params, policy->max);
-	policy->max = icst525_khz(&cclk_params, vco);
+	vco = icst_hz_to_vco(&cclk_params, policy->max * 1000);
+	policy->max = icst_hz(&cclk_params, vco) / 1000;
 
-	vco = icst525_khz_to_vco(&cclk_params, policy->min);
-	policy->min = icst525_khz(&cclk_params, vco);
+	vco = icst_hz_to_vco(&cclk_params, policy->min * 1000);
+	policy->min = icst_hz(&cclk_params, vco) / 1000;
 
 	cpufreq_verify_within_limits(policy, 
 				     policy->cpuinfo.min_freq, 
@@ -78,7 +85,7 @@
 {
 	cpumask_t cpus_allowed;
 	int cpu = policy->cpu;
-	struct icst525_vco vco;
+	struct icst_vco vco;
 	struct cpufreq_freqs freqs;
 	u_int cm_osc;
 
@@ -104,17 +111,17 @@
 	}
 	vco.v = cm_osc & 255;
 	vco.r = 22;
-	freqs.old = icst525_khz(&cclk_params, vco);
+	freqs.old = icst_hz(&cclk_params, vco) / 1000;
 
-	/* icst525_khz_to_vco rounds down -- so we need the next
+	/* icst_hz_to_vco rounds down -- so we need the next
 	 * larger freq in case of CPUFREQ_RELATION_L.
 	 */
 	if (relation == CPUFREQ_RELATION_L)
 		target_freq += 999;
 	if (target_freq > policy->max)
 		target_freq = policy->max;
-	vco = icst525_khz_to_vco(&cclk_params, target_freq);
-	freqs.new = icst525_khz(&cclk_params, vco);
+	vco = icst_hz_to_vco(&cclk_params, target_freq * 1000);
+	freqs.new = icst_hz(&cclk_params, vco) / 1000;
 
 	freqs.cpu = policy->cpu;
 
@@ -154,7 +161,7 @@
 	cpumask_t cpus_allowed;
 	unsigned int current_freq;
 	u_int cm_osc;
-	struct icst525_vco vco;
+	struct icst_vco vco;
 
 	cpus_allowed = current->cpus_allowed;
 
@@ -172,7 +179,7 @@
 	vco.v = cm_osc & 255;
 	vco.r = 22;
 
-	current_freq = icst525_khz(&cclk_params, vco); /* current freq */
+	current_freq = icst_hz(&cclk_params, vco) / 1000; /* current freq */
 
 	set_cpus_allowed(current, cpus_allowed);
 
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 41b1072..fd684bf2 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -25,7 +25,7 @@
 
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
-#include <asm/hardware/icst525.h>
+#include <asm/hardware/icst.h>
 #include <mach/lm.h>
 #include <mach/impd1.h>
 #include <asm/sizes.h>
@@ -41,32 +41,25 @@
 	struct clk_lookup *clks[3];
 };
 
-static const struct icst525_params impd1_vco_params = {
-	.ref		= 24000,	/* 24 MHz */
-	.vco_max	= 200000,	/* 200 MHz */
+static const struct icst_params impd1_vco_params = {
+	.ref		= 24000000,	/* 24 MHz */
+	.vco_max	= ICST525_VCO_MAX_3V,
+	.vco_min	= ICST525_VCO_MIN,
 	.vd_min		= 12,
 	.vd_max		= 519,
 	.rd_min		= 3,
 	.rd_max		= 120,
+	.s2div		= icst525_s2div,
+	.idx2s		= icst525_idx2s,
 };
 
-static void impd1_setvco(struct clk *clk, struct icst525_vco vco)
+static void impd1_setvco(struct clk *clk, struct icst_vco vco)
 {
 	struct impd1_module *impd1 = clk->data;
-	int vconr = clk - impd1->vcos;
-	u32 val;
-
-	val = vco.v | (vco.r << 9) | (vco.s << 16);
+	u32 val = vco.v | (vco.r << 9) | (vco.s << 16);
 
 	writel(0xa05f, impd1->base + IMPD1_LOCK);
-	switch (vconr) {
-	case 0:
-		writel(val, impd1->base + IMPD1_OSC1);
-		break;
-	case 1:
-		writel(val, impd1->base + IMPD1_OSC2);
-		break;
-	}
+	writel(val, clk->vcoreg);
 	writel(0, impd1->base + IMPD1_LOCK);
 
 #ifdef DEBUG
@@ -74,11 +67,17 @@
 	vco.r = (val >> 9) & 0x7f;
 	vco.s = (val >> 16) & 7;
 
-	pr_debug("IM-PD1: VCO%d clock is %ld kHz\n",
-		 vconr, icst525_khz(&impd1_vco_params, vco));
+	pr_debug("IM-PD1: VCO%d clock is %ld Hz\n",
+		 vconr, icst525_hz(&impd1_vco_params, vco));
 #endif
 }
 
+static const struct clk_ops impd1_clk_ops = {
+	.round	= icst_clk_round,
+	.set	= icst_clk_set,
+	.setvco	= impd1_setvco,
+};
+
 void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
 {
 	struct impd1_module *impd1 = dev_get_drvdata(dev);
@@ -374,11 +373,13 @@
 		(unsigned long)dev->resource.start);
 
 	for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) {
+		impd1->vcos[i].ops = &impd1_clk_ops,
 		impd1->vcos[i].owner = THIS_MODULE,
 		impd1->vcos[i].params = &impd1_vco_params,
-		impd1->vcos[i].data = impd1,
-		impd1->vcos[i].setvco = impd1_setvco;
+		impd1->vcos[i].data = impd1;
 	}
+	impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1;
+	impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2;
 
 	impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000",
 					dev->id);
diff --git a/arch/arm/mach-integrator/include/mach/clkdev.h b/arch/arm/mach-integrator/include/mach/clkdev.h
index 9293e41..bfe0767 100644
--- a/arch/arm/mach-integrator/include/mach/clkdev.h
+++ b/arch/arm/mach-integrator/include/mach/clkdev.h
@@ -2,14 +2,15 @@
 #define __ASM_MACH_CLKDEV_H
 
 #include <linux/module.h>
-#include <asm/hardware/icst525.h>
+#include <plat/clock.h>
 
 struct clk {
 	unsigned long		rate;
+	const struct clk_ops	*ops;
 	struct module		*owner;
-	const struct icst525_params *params;
+	const struct icst_params *params;
+	void __iomem		*vcoreg;
 	void			*data;
-	void			(*setvco)(struct clk *, struct icst525_vco vco);
 };
 
 static inline int __clk_get(struct clk *clk)
diff --git a/arch/arm/mach-integrator/include/mach/entry-macro.S b/arch/arm/mach-integrator/include/mach/entry-macro.S
index 7649c57..3d029c9 100644
--- a/arch/arm/mach-integrator/include/mach/entry-macro.S
+++ b/arch/arm/mach-integrator/include/mach/entry-macro.S
@@ -8,6 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <mach/irqs.h>
 
  		.macro	disable_fiq
diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h
index d795642..8e26360 100644
--- a/arch/arm/mach-integrator/include/mach/hardware.h
+++ b/arch/arm/mach-integrator/include/mach/hardware.h
@@ -23,7 +23,6 @@
 #define __ASM_ARCH_HARDWARE_H
 
 #include <asm/sizes.h>
-#include <mach/platform.h>
 
 /*
  * Where in virtual memory the IO devices (timers, system controllers
@@ -36,17 +35,19 @@
 #define PCIO_BASE		PCI_IO_VADDR
 #define PCIMEM_BASE		PCI_MEMORY_VADDR
 
-#ifdef CONFIG_MMU
-/* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x) (((x) >> 4) + IO_BASE) 
-#else
-#define IO_ADDRESS(x) (x)
-#endif
-
 #define pcibios_assign_all_busses()	1
 
 #define PCIBIOS_MIN_IO		0x6000
 #define PCIBIOS_MIN_MEM 	0x00100000
 
+/* macro to get at IO space when running virtually */
+#ifdef CONFIG_MMU
+#define IO_ADDRESS(x)	(((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
+#else
+#define IO_ADDRESS(x)	(x)
+#endif
+
+#define __io_address(n)		((void __iomem *)IO_ADDRESS(n))
+
 #endif
 
diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h
index e00a262..5e6ea5c 100644
--- a/arch/arm/mach-integrator/include/mach/platform.h
+++ b/arch/arm/mach-integrator/include/mach/platform.h
@@ -23,9 +23,6 @@
  *
  *   Integrator address map
  *
- * 	NOTE: This is a multi-hosted header file for use with uHAL and
- * 	      supported debuggers.
- *
  * ***********************************************************************/
 
 #ifndef __address_h
@@ -290,12 +287,14 @@
 #define INTEGRATOR_DBG_LEDS             (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET)
 #define INTEGRATOR_DBG_SWITCH           (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET)
 
+#define INTEGRATOR_AP_GPIO_BASE		0x1B000000	/* GPIO */
 
-#if defined(CONFIG_ARCH_INTEGRATOR_AP)
-#define INTEGRATOR_GPIO_BASE            0x1B000000	 /*  GPIO */
-#elif defined(CONFIG_ARCH_INTEGRATOR_CP)
-#define INTEGRATOR_GPIO_BASE            0xC9000000	 /*  GPIO */
-#endif
+#define INTEGRATOR_CP_MMC_BASE		0x1C000000	/* MMC */
+#define INTEGRATOR_CP_AACI_BASE		0x1D000000	/* AACI */
+#define INTEGRATOR_CP_ETH_BASE		0xC8000000	/* Ethernet */
+#define INTEGRATOR_CP_GPIO_BASE		0xC9000000	/* GPIO */
+#define INTEGRATOR_CP_SIC_BASE		0xCA000000	/* SIC */
+#define INTEGRATOR_CP_CTL_BASE		0xCB000000	/* CP system control */
 
 /* ------------------------------------------------------------------------
  *  KMI keyboard/mouse definitions
@@ -328,20 +327,6 @@
  */
 #define PHYS_PCI_V3_BASE                0x62000000
 
-#define PCI_DRAMSIZE                    INTEGRATOR_SSRAM_SIZE
-
-/* 'export' these to UHAL */
-#define UHAL_PCI_IO                     PCI_IO_BASE
-#define UHAL_PCI_MEM                    PCI_MEM_BASE
-#define UHAL_PCI_ALLOC_IO_BASE          0x00004000
-#define UHAL_PCI_ALLOC_MEM_BASE         PCI_MEM_BASE
-#define UHAL_PCI_MAX_SLOT               20
-
-/* ========================================================================
- *  Start of uHAL definitions
- * ========================================================================
- */
-
 /* ------------------------------------------------------------------------
  *  Integrator Interrupt Controllers
  * ------------------------------------------------------------------------
@@ -389,7 +374,7 @@
  */
 
 /* ------------------------------------------------------------------------
- *  LED's - The header LED is not accessible via the uHAL API
+ *  LED's
  * ------------------------------------------------------------------------
  *
  */
@@ -402,34 +387,18 @@
 #define LED_BANK                        INTEGRATOR_DBG_LEDS
 
 /*
- *  Memory definitions - run uHAL out of SSRAM.
- *
- */
-#define uHAL_MEMORY_SIZE                INTEGRATOR_SSRAM_SIZE
-
-/*
- *  Clean base - dummy
- *
- */
-#define CLEAN_BASE                      INTEGRATOR_BOOT_ROM_HI
-
-/*
  *  Timer definitions
  *
  *  Only use timer 1 & 2
  *  (both run at 24MHz and will need the clock divider set to 16).
  *
- *  Timer 0 runs at bus frequency and therefore could vary and currently
- *  uHAL can't handle that.
- *
+ *  Timer 0 runs at bus frequency
  */
 
 #define INTEGRATOR_TIMER0_BASE          INTEGRATOR_CT_BASE
 #define INTEGRATOR_TIMER1_BASE          (INTEGRATOR_CT_BASE + 0x100)
 #define INTEGRATOR_TIMER2_BASE          (INTEGRATOR_CT_BASE + 0x200)
 
-#define MAX_TIMER                       2
-#define MAX_PERIOD                      699050
 #define TICKS_PER_uSEC                  24
 
 /*
@@ -437,14 +406,9 @@
  *
  */
 #define mSEC_1                          1000
-#define mSEC_5                          (mSEC_1 * 5)
 #define mSEC_10                         (mSEC_1 * 10)
-#define mSEC_25                         (mSEC_1 * 25)
-#define SEC_1                           (mSEC_1 * 1000)
 
 #define INTEGRATOR_CSR_BASE             0x10000000
 #define INTEGRATOR_CSR_SIZE             0x10000000
 
 #endif
-
-/* 	END */
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 8138a7e..227cf4d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -27,9 +27,14 @@
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/kmi.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/hardware/arm_timer.h>
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/param.h>		/* HZ */
@@ -43,8 +48,6 @@
 #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).
@@ -55,7 +58,7 @@
 #define VA_IC_BASE	IO_ADDRESS(INTEGRATOR_IC_BASE) 
 #define VA_SC_BASE	IO_ADDRESS(INTEGRATOR_SC_BASE)
 #define VA_EBI_BASE	IO_ADDRESS(INTEGRATOR_EBI_BASE)
-#define VA_CMIC_BASE	IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
+#define VA_CMIC_BASE	IO_ADDRESS(INTEGRATOR_HDR_IC)
 
 /*
  * Logical      Physical
@@ -117,8 +120,8 @@
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
-		.virtual	= IO_ADDRESS(INTEGRATOR_GPIO_BASE),
-		.pfn		= __phys_to_pfn(INTEGRATOR_GPIO_BASE),
+		.virtual	= IO_ADDRESS(INTEGRATOR_AP_GPIO_BASE),
+		.pfn		= __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
@@ -334,14 +337,163 @@
 	}
 }
 
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER0_BASE)
+#define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE)
+#define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE)
+
+/*
+ * How long is the timer interval?
+ */
+#define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)
+#if TIMER_INTERVAL >= 0x100000
+#define TICKS2USECS(x)	(256 * (x) / TICKS_PER_uSEC)
+#elif TIMER_INTERVAL >= 0x10000
+#define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)
+#else
+#define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
+#endif
+
+static unsigned long timer_reload;
+
+static void __iomem * const clksrc_base = (void __iomem *)TIMER2_VA_BASE;
+
+static cycle_t timersp_read(struct clocksource *cs)
+{
+	return ~(readl(clksrc_base + TIMER_VALUE) & 0xffff);
+}
+
+static struct clocksource clocksource_timersp = {
+	.name		= "timer2",
+	.rating		= 200,
+	.read		= timersp_read,
+	.mask		= CLOCKSOURCE_MASK(16),
+	.shift		= 16,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void integrator_clocksource_init(u32 khz)
+{
+	struct clocksource *cs = &clocksource_timersp;
+	void __iomem *base = clksrc_base;
+	u32 ctrl = TIMER_CTRL_ENABLE;
+
+	if (khz >= 1500) {
+		khz /= 16;
+		ctrl = TIMER_CTRL_DIV16;
+	}
+
+	writel(ctrl, base + TIMER_CTRL);
+	writel(0xffff, base + TIMER_LOAD);
+
+	cs->mult = clocksource_khz2mult(khz, cs->shift);
+	clocksource_register(cs);
+}
+
+static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	/* clear the interrupt */
+	writel(1, clkevt_base + TIMER_INTCLR);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
+{
+	u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
+
+	BUG_ON(mode == CLOCK_EVT_MODE_ONESHOT);
+
+	if (mode == CLOCK_EVT_MODE_PERIODIC) {
+		writel(ctrl, clkevt_base + TIMER_CTRL);
+		writel(timer_reload, clkevt_base + TIMER_LOAD);
+		ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+	}
+
+	writel(ctrl, clkevt_base + TIMER_CTRL);
+}
+
+static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
+{
+	unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
+
+	writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+	writel(next, clkevt_base + TIMER_LOAD);
+	writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+
+	return 0;
+}
+
+static struct clock_event_device integrator_clockevent = {
+	.name		= "timer1",
+	.shift		= 34,
+	.features	= CLOCK_EVT_FEAT_PERIODIC,
+	.set_mode	= clkevt_set_mode,
+	.set_next_event	= clkevt_set_next_event,
+	.rating		= 300,
+	.cpumask	= cpu_all_mask,
+};
+
+static struct irqaction integrator_timer_irq = {
+	.name		= "timer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= integrator_timer_interrupt,
+	.dev_id		= &integrator_clockevent,
+};
+
+static void integrator_clockevent_init(u32 khz)
+{
+	struct clock_event_device *evt = &integrator_clockevent;
+	unsigned int ctrl = 0;
+
+	if (khz * 1000 > 0x100000 * HZ) {
+		khz /= 256;
+		ctrl |= TIMER_CTRL_DIV256;
+	} else if (khz * 1000 > 0x10000 * HZ) {
+		khz /= 16;
+		ctrl |= TIMER_CTRL_DIV16;
+	}
+
+	timer_reload = khz * 1000 / HZ;
+	writel(ctrl, clkevt_base + TIMER_CTRL);
+
+	evt->irq = IRQ_TIMERINT1;
+	evt->mult = div_sc(khz, NSEC_PER_MSEC, evt->shift);
+	evt->max_delta_ns = clockevent_delta2ns(0xffff, evt);
+	evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
+
+	setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
+	clockevents_register_device(evt);
+}
+
+/*
+ * Set up timer(s).
+ */
 static void __init ap_init_timer(void)
 {
-	integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0);
+	u32 khz = TICKS_PER_uSEC * 1000;
+
+	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+
+	integrator_clocksource_init(khz);
+	integrator_clockevent_init(khz);
 }
 
 static struct sys_timer ap_timer = {
 	.init		= ap_init_timer,
-	.offset		= integrator_gettimeoffset,
 };
 
 MACHINE_START(INTEGRATOR, "ARM-Integrator")
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 15e6cc5..cde57b2 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -25,10 +25,12 @@
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/icst525.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/icst.h>
 
 #include <mach/cm.h>
 #include <mach/lm.h>
@@ -39,24 +41,20 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include "common.h"
-
-#define INTCP_PA_MMC_BASE		0x1c000000
-#define INTCP_PA_AACI_BASE		0x1d000000
+#include <plat/timer-sp.h>
 
 #define INTCP_PA_FLASH_BASE		0x24000000
 #define INTCP_FLASH_SIZE		SZ_32M
 
 #define INTCP_PA_CLCD_BASE		0xc0000000
 
-#define INTCP_VA_CIC_BASE		IO_ADDRESS(INTEGRATOR_HDR_BASE) + 0x40
+#define INTCP_VA_CIC_BASE		IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x40)
 #define INTCP_VA_PIC_BASE		IO_ADDRESS(INTEGRATOR_IC_BASE)
-#define INTCP_VA_SIC_BASE		IO_ADDRESS(0xca000000)
+#define INTCP_VA_SIC_BASE		IO_ADDRESS(INTEGRATOR_CP_SIC_BASE)
 
-#define INTCP_PA_ETH_BASE		0xc8000000
 #define INTCP_ETH_SIZE			0x10
 
-#define INTCP_VA_CTRL_BASE		IO_ADDRESS(0xcb000000)
+#define INTCP_VA_CTRL_BASE		IO_ADDRESS(INTEGRATOR_CP_CTL_BASE)
 #define INTCP_FLASHPROG			0x04
 #define CINTEGRATOR_FLASHPROG_FLVPPEN	(1 << 0)
 #define CINTEGRATOR_FLASHPROG_FLWREN	(1 << 1)
@@ -71,7 +69,9 @@
  * f1600000	16000000	UART 0
  * f1700000	17000000	UART 1
  * f1a00000	1a000000	Debug LEDs
- * f1b00000	1b000000	GPIO
+ * fc900000	c9000000	GPIO
+ * fca00000	ca000000	SIC
+ * fcb00000	cb000000	CP system control
  */
 
 static struct map_desc intcp_io_desc[] __initdata = {
@@ -116,18 +116,18 @@
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
-		.virtual	= IO_ADDRESS(INTEGRATOR_GPIO_BASE),
-		.pfn		= __phys_to_pfn(INTEGRATOR_GPIO_BASE),
+		.virtual	= IO_ADDRESS(INTEGRATOR_CP_GPIO_BASE),
+		.pfn		= __phys_to_pfn(INTEGRATOR_CP_GPIO_BASE),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
-		.virtual	= IO_ADDRESS(0xca000000),
-		.pfn		= __phys_to_pfn(0xca000000),
+		.virtual	= IO_ADDRESS(INTEGRATOR_CP_SIC_BASE),
+		.pfn		= __phys_to_pfn(INTEGRATOR_CP_SIC_BASE),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
-		.virtual	= IO_ADDRESS(0xcb000000),
-		.pfn		= __phys_to_pfn(0xcb000000),
+		.virtual	= IO_ADDRESS(INTEGRATOR_CP_CTL_BASE),
+		.pfn		= __phys_to_pfn(INTEGRATOR_CP_CTL_BASE),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}
@@ -266,33 +266,43 @@
 /*
  * Clock handling
  */
-#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
-#define CM_AUXOSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+0x1c)
+#define CM_LOCK		(__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
+#define CM_AUXOSC	(__io_address(INTEGRATOR_HDR_BASE)+0x1c)
 
-static const struct icst525_params cp_auxvco_params = {
-	.ref		= 24000,
-	.vco_max	= 320000,
+static const struct icst_params cp_auxvco_params = {
+	.ref		= 24000000,
+	.vco_max	= ICST525_VCO_MAX_5V,
+	.vco_min	= ICST525_VCO_MIN,
 	.vd_min 	= 8,
 	.vd_max 	= 263,
 	.rd_min 	= 3,
 	.rd_max 	= 65,
+	.s2div		= icst525_s2div,
+	.idx2s		= icst525_idx2s,
 };
 
-static void cp_auxvco_set(struct clk *clk, struct icst525_vco vco)
+static void cp_auxvco_set(struct clk *clk, struct icst_vco vco)
 {
 	u32 val;
 
-	val = readl(CM_AUXOSC) & ~0x7ffff;
+	val = readl(clk->vcoreg) & ~0x7ffff;
 	val |= vco.v | (vco.r << 9) | (vco.s << 16);
 
 	writel(0xa05f, CM_LOCK);
-	writel(val, CM_AUXOSC);
+	writel(val, clk->vcoreg);
 	writel(0, CM_LOCK);
 }
 
+static const struct clk_ops cp_auxclk_ops = {
+	.round	= icst_clk_round,
+	.set	= icst_clk_set,
+	.setvco	= cp_auxvco_set,
+};
+
 static struct clk cp_auxclk = {
+	.ops	= &cp_auxclk_ops,
 	.params	= &cp_auxvco_params,
-	.setvco = cp_auxvco_set,
+	.vcoreg	= CM_AUXOSC,
 };
 
 static struct clk_lookup cp_lookups[] = {
@@ -363,8 +373,8 @@
 
 static struct resource smc91x_resources[] = {
 	[0] = {
-		.start	= INTCP_PA_ETH_BASE,
-		.end	= INTCP_PA_ETH_BASE + INTCP_ETH_SIZE - 1,
+		.start	= INTEGRATOR_CP_ETH_BASE,
+		.end	= INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -394,8 +404,8 @@
  */
 static unsigned int mmc_status(struct device *dev)
 {
-	unsigned int status = readl(IO_ADDRESS(0xca000000) + 4);
-	writel(8, IO_ADDRESS(0xcb000000) + 8);
+	unsigned int status = readl(IO_ADDRESS(0xca000000 + 4));
+	writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE + 8));
 
 	return status & 8;
 }
@@ -413,8 +423,8 @@
 		.platform_data = &mmc_data,
 	},
 	.res		= {
-		.start	= INTCP_PA_MMC_BASE,
-		.end	= INTCP_PA_MMC_BASE + SZ_4K - 1,
+		.start	= INTEGRATOR_CP_MMC_BASE,
+		.end	= INTEGRATOR_CP_MMC_BASE + SZ_4K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	.irq		= { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 },
@@ -426,8 +436,8 @@
 		.init_name = "mb:1d",
 	},
 	.res		= {
-		.start	= INTCP_PA_AACI_BASE,
-		.end	= INTCP_PA_AACI_BASE + SZ_4K - 1,
+		.start	= INTEGRATOR_CP_AACI_BASE,
+		.end	= INTEGRATOR_CP_AACI_BASE + SZ_4K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	.irq		= { IRQ_CP_AACIINT, NO_IRQ },
@@ -567,16 +577,22 @@
 	}
 }
 
-#define TIMER_CTRL_IE	(1 << 5)			/* Interrupt Enable */
+#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
+#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
+#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
 
 static void __init intcp_timer_init(void)
 {
-	integrator_time_init(1000000 / HZ, TIMER_CTRL_IE);
+	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+
+	sp804_clocksource_init(TIMER2_VA_BASE);
+	sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1);
 }
 
 static struct sys_timer cp_timer = {
 	.init		= intcp_timer_init,
-	.offset		= integrator_gettimeoffset,
 };
 
 MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c
index 8dcc823..28be186 100644
--- a/arch/arm/mach-integrator/leds.c
+++ b/arch/arm/mach-integrator/leds.c
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/leds.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index ffbd349..9cef059 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/irq.h>
 #include <asm/signal.h>
 #include <asm/system.h>
@@ -389,9 +390,9 @@
  * means I can't get additional information on the reason for the pm2fb
  * problems.  I suppose I'll just have to mind-meld with the machine. ;)
  */
-#define SC_PCI     (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_PCIENABLE_OFFSET)
-#define SC_LBFADDR (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x20)
-#define SC_LBFCODE (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x24)
+#define SC_PCI     IO_ADDRESS(INTEGRATOR_SC_PCIENABLE)
+#define SC_LBFADDR IO_ADDRESS(INTEGRATOR_SC_BASE + 0x20)
+#define SC_LBFCODE IO_ADDRESS(INTEGRATOR_SC_BASE + 0x24)
 
 static int
 v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index 5d99039..f108a31 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -176,7 +176,7 @@
 		.mapbase	= N2100_UART,
 		.membase	= (char *)N2100_UART,
 		.irq		= 0,
-		.flags		= UPF_SKIP_TEST,
+		.flags		= UPF_SKIP_TEST | UPF_AUTO_IRQ | UPF_SHARE_IRQ,
 		.iotype		= UPIO_MEM,
 		.regshift	= 0,
 		.uartclk	= 1843200,
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 71728d3..0bce0979 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -21,7 +21,6 @@
 #include <linux/tty.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
-#include <linux/bootmem.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/time.h>
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index 17879a8..29b2163 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -38,6 +38,12 @@
 	  Say 'Y' here if you want your kernel to support the
 	  Marvell eSATA SheevaPlug Reference Board.
 
+config MACH_GURUPLUG
+	bool "Marvell GuruPlug Reference Board"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell GuruPlug Reference Board.
+
 config MACH_TS219
 	bool "QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS"
 	help
@@ -81,6 +87,18 @@
 	  Say 'Y' here if you want your kernel to support the
 	  LaCie Internet Space v2 NAS.
 
+config MACH_NET2BIG_V2
+	bool "LaCie 2Big Network v2 NAS Board"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  LaCie 2Big Network v2 NAS.
+
+config MACH_NET5BIG_V2
+	bool "LaCie 5Big Network v2 NAS Board"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  LaCie 5Big Network v2 NAS.
+
 endmenu
 
 endif
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index a5530e3..c0cd5d3 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -6,10 +6,13 @@
 obj-$(CONFIG_MACH_MV88F6281GTW_GE)	+= mv88f6281gtw_ge-setup.o
 obj-$(CONFIG_MACH_SHEEVAPLUG)		+= sheevaplug-setup.o
 obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG)	+= sheevaplug-setup.o
+obj-$(CONFIG_MACH_GURUPLUG)		+= guruplug-setup.o
 obj-$(CONFIG_MACH_TS219)		+= ts219-setup.o tsx1x-common.o
 obj-$(CONFIG_MACH_TS41X)		+= ts41x-setup.o tsx1x-common.o
 obj-$(CONFIG_MACH_OPENRD)		+= openrd-setup.o
 obj-$(CONFIG_MACH_NETSPACE_V2)		+= netspace_v2-setup.o
 obj-$(CONFIG_MACH_INETSPACE_V2)		+= netspace_v2-setup.o
+obj-$(CONFIG_MACH_NET2BIG_V2)		+= netxbig_v2-setup.o
+obj-$(CONFIG_MACH_NET5BIG_V2)		+= netxbig_v2-setup.o
 
 obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
diff --git a/arch/arm/mach-kirkwood/guruplug-setup.c b/arch/arm/mach-kirkwood/guruplug-setup.c
new file mode 100644
index 0000000..54d07c8
--- /dev/null
+++ b/arch/arm/mach-kirkwood/guruplug-setup.c
@@ -0,0 +1,131 @@
+/*
+ * arch/arm/mach-kirkwood/guruplug-setup.c
+ *
+ * Marvell GuruPlug Reference Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition guruplug_nand_parts[] = {
+	{
+		.name = "u-boot",
+		.offset = 0,
+		.size = SZ_1M
+	}, {
+		.name = "uImage",
+		.offset = MTDPART_OFS_NXTBLK,
+		.size = SZ_4M
+	}, {
+		.name = "root",
+		.offset = MTDPART_OFS_NXTBLK,
+		.size = MTDPART_SIZ_FULL
+	},
+};
+
+static struct mv643xx_eth_platform_data guruplug_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv643xx_eth_platform_data guruplug_ge01_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(1),
+};
+
+static struct mv_sata_platform_data guruplug_sata_data = {
+	.n_ports	= 1,
+};
+
+static struct mvsdio_platform_data guruplug_mvsdio_data = {
+	/* unfortunately the CD signal has not been connected */
+};
+
+static struct gpio_led guruplug_led_pins[] = {
+	{
+		.name			= "guruplug:red:health",
+		.gpio			= 46,
+		.active_low		= 1,
+	},
+	{
+		.name			= "guruplug:green:health",
+		.gpio			= 47,
+		.active_low		= 1,
+	},
+	{
+		.name			= "guruplug:red:wmode",
+		.gpio			= 48,
+		.active_low		= 1,
+	},
+	{
+		.name			= "guruplug:green:wmode",
+		.gpio			= 49,
+		.active_low		= 1,
+	},
+};
+
+static struct gpio_led_platform_data guruplug_led_data = {
+	.leds		= guruplug_led_pins,
+	.num_leds	= ARRAY_SIZE(guruplug_led_pins),
+};
+
+static struct platform_device guruplug_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &guruplug_led_data,
+	}
+};
+
+static unsigned int guruplug_mpp_config[] __initdata = {
+	MPP46_GPIO,	/* M_RLED */
+	MPP47_GPIO,	/* M_GLED */
+	MPP48_GPIO,	/* B_RLED */
+	MPP49_GPIO,	/* B_GLED */
+	0
+};
+
+static void __init guruplug_init(void)
+{
+	/*
+	 * Basic setup. Needs to be called early.
+	 */
+	kirkwood_init();
+	kirkwood_mpp_conf(guruplug_mpp_config);
+
+	kirkwood_uart0_init();
+	kirkwood_nand_init(ARRAY_AND_SIZE(guruplug_nand_parts), 25);
+
+	kirkwood_ehci_init();
+	kirkwood_ge00_init(&guruplug_ge00_data);
+	kirkwood_ge01_init(&guruplug_ge01_data);
+	kirkwood_sata_init(&guruplug_sata_data);
+	kirkwood_sdio_init(&guruplug_mvsdio_data);
+
+	platform_device_register(&guruplug_leds);
+}
+
+MACHINE_START(GURUPLUG, "Marvell GuruPlug Reference Board")
+	/* Maintainer: Siddarth Gore <gores@marvell.com> */
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= guruplug_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c
new file mode 100644
index 0000000..8a2bb02
--- /dev/null
+++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c
@@ -0,0 +1,415 @@
+/*
+ * arch/arm/mach-kirkwood/netxbig_v2-setup.c
+ *
+ * LaCie 2Big and 5Big Network v2 board setup
+ *
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/kirkwood.h>
+#include <plat/time.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
+ ****************************************************************************/
+
+static struct mtd_partition netxbig_v2_flash_parts[] = {
+	{
+		.name = "u-boot",
+		.size = MTDPART_SIZ_FULL,
+		.offset = 0,
+		.mask_flags = MTD_WRITEABLE, /* force read-only */
+	},
+};
+
+static const struct flash_platform_data netxbig_v2_flash = {
+	.type		= "mx25l4005a",
+	.name		= "spi_flash",
+	.parts		= netxbig_v2_flash_parts,
+	.nr_parts	= ARRAY_SIZE(netxbig_v2_flash_parts),
+};
+
+static struct spi_board_info __initdata netxbig_v2_spi_slave_info[] = {
+	{
+		.modalias	= "m25p80",
+		.platform_data	= &netxbig_v2_flash,
+		.irq		= -1,
+		.max_speed_hz	= 20000000,
+		.bus_num	= 0,
+		.chip_select	= 0,
+	},
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data netxbig_v2_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
+};
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+static struct at24_platform_data at24c04 = {
+	.byte_len	= SZ_4K / 8,
+	.page_size	= 16,
+};
+
+/*
+ * i2c addr | chip         | description
+ * 0x50     | HT24LC04     | eeprom (512B)
+ */
+
+static struct i2c_board_info __initdata netxbig_v2_i2c_info[] = {
+	{
+		I2C_BOARD_INFO("24c04", 0x50),
+		.platform_data  = &at24c04,
+	}
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data netxbig_v2_sata_data = {
+	.n_ports	= 2,
+};
+
+static int __initdata netxbig_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
+
+static void __init netxbig_v2_sata_power_init(void)
+{
+	int i;
+	int err;
+	int hdd_nb;
+
+	if (machine_is_net2big_v2())
+		hdd_nb = 2;
+	else
+		hdd_nb = 5;
+
+	/* Power up all hard disks. */
+	for (i = 0; i < hdd_nb; i++) {
+		err = gpio_request(netxbig_v2_gpio_hdd_power[i], NULL);
+		if (err == 0) {
+			err = gpio_direction_output(
+					netxbig_v2_gpio_hdd_power[i], 1);
+			/* Free the HDD power GPIOs. This allow user-space to
+			 * configure them via the gpiolib sysfs interface. */
+			gpio_free(netxbig_v2_gpio_hdd_power[i]);
+		}
+		if (err)
+			pr_err("netxbig_v2: failed to power up HDD%d\n", i + 1);
+	}
+}
+
+/*****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define NETXBIG_V2_GPIO_SWITCH_POWER_ON		13
+#define NETXBIG_V2_GPIO_SWITCH_POWER_OFF	15
+#define NETXBIG_V2_GPIO_FUNC_BUTTON		34
+
+#define NETXBIG_V2_SWITCH_POWER_ON		0x1
+#define NETXBIG_V2_SWITCH_POWER_OFF		0x2
+
+static struct gpio_keys_button netxbig_v2_buttons[] = {
+	[0] = {
+		.type           = EV_SW,
+		.code           = NETXBIG_V2_SWITCH_POWER_ON,
+		.gpio           = NETXBIG_V2_GPIO_SWITCH_POWER_ON,
+		.desc           = "Back power switch (on|auto)",
+		.active_low     = 1,
+	},
+	[1] = {
+		.type           = EV_SW,
+		.code           = NETXBIG_V2_SWITCH_POWER_OFF,
+		.gpio           = NETXBIG_V2_GPIO_SWITCH_POWER_OFF,
+		.desc           = "Back power switch (auto|off)",
+		.active_low     = 1,
+	},
+	[2] = {
+		.code		= KEY_OPTION,
+		.gpio		= NETXBIG_V2_GPIO_FUNC_BUTTON,
+		.desc		= "Function button",
+		.active_low	= 1,
+	},
+};
+
+static struct gpio_keys_platform_data netxbig_v2_button_data = {
+	.buttons	= netxbig_v2_buttons,
+	.nbuttons	= ARRAY_SIZE(netxbig_v2_buttons),
+};
+
+static struct platform_device netxbig_v2_gpio_buttons = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &netxbig_v2_button_data,
+	},
+};
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+/*
+ * The LEDs are controlled by a CPLD and can be configured through a GPIO
+ * extension bus:
+ *
+ * - address register : bit [0-2] -> GPIO [47-49]
+ * - data register    : bit [0-2] -> GPIO [44-46]
+ * - enable register  : GPIO 29
+ *
+ * Address register selection:
+ *
+ * addr | register
+ * ----------------------------
+ *   0  | front LED
+ *   1  | front LED brightness
+ *   2  | HDD LED brightness
+ *   3  | HDD1 LED
+ *   4  | HDD2 LED
+ *   5  | HDD3 LED
+ *   6  | HDD4 LED
+ *   7  | HDD5 LED
+ *
+ * Data register configuration:
+ *
+ * data | LED brightness
+ * -------------------------------------------------
+ *   0  | min (off)
+ *   -  | -
+ *   7  | max
+ *
+ * data | front LED mode
+ * -------------------------------------------------
+ *   0  | fix off
+ *   1  | fix blue on
+ *   2  | fix red on
+ *   3  | blink blue on=1 sec and blue off=1 sec
+ *   4  | blink red on=1 sec and red off=1 sec
+ *   5  | blink blue on=2.5 sec and red on=0.5 sec
+ *   6  | blink blue on=1 sec and red on=1 sec
+ *   7  | blink blue on=0.5 sec and blue off=2.5 sec
+ *
+ * data | HDD LED mode
+ * -------------------------------------------------
+ *   0  | fix blue on
+ *   1  | SATA activity blink
+ *   2  | fix red on
+ *   3  | blink blue on=1 sec and blue off=1 sec
+ *   4  | blink red on=1 sec and red off=1 sec
+ *   5  | blink blue on=2.5 sec and red on=0.5 sec
+ *   6  | blink blue on=1 sec and red on=1 sec
+ *   7  | blink blue on=0.5 sec and blue off=2.5 sec
+ */
+
+/*****************************************************************************
+ * Timer
+ ****************************************************************************/
+
+static void netxbig_v2_timer_init(void)
+{
+	kirkwood_tclk = 166666667;
+	orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
+}
+
+struct sys_timer netxbig_v2_timer = {
+	.init = netxbig_v2_timer_init,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int net2big_v2_mpp_config[] __initdata = {
+	MPP0_SPI_SCn,
+	MPP1_SPI_MOSI,
+	MPP2_SPI_SCK,
+	MPP3_SPI_MISO,
+	MPP6_SYSRST_OUTn,
+	MPP7_GPO,		/* Request power-off */
+	MPP8_TW_SDA,
+	MPP9_TW_SCK,
+	MPP10_UART0_TXD,
+	MPP11_UART0_RXD,
+	MPP13_GPIO,		/* Rear power switch (on|auto) */
+	MPP14_GPIO,		/* USB fuse alarm */
+	MPP15_GPIO,		/* Rear power switch (auto|off) */
+	MPP16_GPIO,		/* SATA HDD1 power */
+	MPP17_GPIO,		/* SATA HDD2 power */
+	MPP20_SATA1_ACTn,
+	MPP21_SATA0_ACTn,
+	MPP24_GPIO,		/* USB mode select */
+	MPP26_GPIO,		/* USB device vbus */
+	MPP28_GPIO,		/* USB enable host vbus */
+	MPP29_GPIO,		/* CPLD extension ALE */
+	MPP34_GPIO,		/* Rear Push button */
+	MPP35_GPIO,		/* Inhibit switch power-off */
+	MPP36_GPIO,		/* SATA HDD1 presence */
+	MPP37_GPIO,		/* SATA HDD2 presence */
+	MPP40_GPIO,		/* eSATA presence */
+	MPP44_GPIO,		/* CPLD extension (data 0) */
+	MPP45_GPIO,		/* CPLD extension (data 1) */
+	MPP46_GPIO,		/* CPLD extension (data 2) */
+	MPP47_GPIO,		/* CPLD extension (addr 0) */
+	MPP48_GPIO,		/* CPLD extension (addr 1) */
+	MPP49_GPIO,		/* CPLD extension (addr 2) */
+	0
+};
+
+static unsigned int net5big_v2_mpp_config[] __initdata = {
+	MPP0_SPI_SCn,
+	MPP1_SPI_MOSI,
+	MPP2_SPI_SCK,
+	MPP3_SPI_MISO,
+	MPP6_SYSRST_OUTn,
+	MPP7_GPO,		/* Request power-off */
+	MPP8_TW_SDA,
+	MPP9_TW_SCK,
+	MPP10_UART0_TXD,
+	MPP11_UART0_RXD,
+	MPP13_GPIO,		/* Rear power switch (on|auto) */
+	MPP14_GPIO,		/* USB fuse alarm */
+	MPP15_GPIO,		/* Rear power switch (auto|off) */
+	MPP16_GPIO,		/* SATA HDD1 power */
+	MPP17_GPIO,		/* SATA HDD2 power */
+	MPP20_GE1_0,
+	MPP21_GE1_1,
+	MPP22_GE1_2,
+	MPP23_GE1_3,
+	MPP24_GE1_4,
+	MPP25_GE1_5,
+	MPP26_GE1_6,
+	MPP27_GE1_7,
+	MPP28_GPIO,		/* USB enable host vbus */
+	MPP29_GPIO,		/* CPLD extension ALE */
+	MPP30_GE1_10,
+	MPP31_GE1_11,
+	MPP32_GE1_12,
+	MPP33_GE1_13,
+	MPP34_GPIO,		/* Rear Push button */
+	MPP35_GPIO,		/* Inhibit switch power-off */
+	MPP36_GPIO,		/* SATA HDD1 presence */
+	MPP37_GPIO,		/* SATA HDD2 presence */
+	MPP38_GPIO,		/* SATA HDD3 presence */
+	MPP39_GPIO,		/* SATA HDD4 presence */
+	MPP40_GPIO,		/* SATA HDD5 presence */
+	MPP41_GPIO,		/* SATA HDD3 power */
+	MPP42_GPIO,		/* SATA HDD4 power */
+	MPP43_GPIO,		/* SATA HDD5 power */
+	MPP44_GPIO,		/* CPLD extension (data 0) */
+	MPP45_GPIO,		/* CPLD extension (data 1) */
+	MPP46_GPIO,		/* CPLD extension (data 2) */
+	MPP47_GPIO,		/* CPLD extension (addr 0) */
+	MPP48_GPIO,		/* CPLD extension (addr 1) */
+	MPP49_GPIO,		/* CPLD extension (addr 2) */
+	0
+};
+
+#define NETXBIG_V2_GPIO_POWER_OFF		7
+
+static void netxbig_v2_power_off(void)
+{
+	gpio_set_value(NETXBIG_V2_GPIO_POWER_OFF, 1);
+}
+
+static void __init netxbig_v2_init(void)
+{
+	/*
+	 * Basic setup. Needs to be called early.
+	 */
+	kirkwood_init();
+	if (machine_is_net2big_v2())
+		kirkwood_mpp_conf(net2big_v2_mpp_config);
+	else
+		kirkwood_mpp_conf(net5big_v2_mpp_config);
+
+	netxbig_v2_sata_power_init();
+
+	kirkwood_ehci_init();
+	kirkwood_ge00_init(&netxbig_v2_ge00_data);
+	if (machine_is_net5big_v2())
+		kirkwood_ge01_init(&netxbig_v2_ge01_data);
+	kirkwood_sata_init(&netxbig_v2_sata_data);
+	kirkwood_uart0_init();
+	spi_register_board_info(netxbig_v2_spi_slave_info,
+				ARRAY_SIZE(netxbig_v2_spi_slave_info));
+	kirkwood_spi_init();
+	kirkwood_i2c_init();
+	i2c_register_board_info(0, netxbig_v2_i2c_info,
+				ARRAY_SIZE(netxbig_v2_i2c_info));
+
+	platform_device_register(&netxbig_v2_gpio_buttons);
+
+	if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 &&
+	    gpio_direction_output(NETXBIG_V2_GPIO_POWER_OFF, 0) == 0)
+		pm_power_off = netxbig_v2_power_off;
+	else
+		pr_err("netxbig_v2: failed to configure power-off GPIO\n");
+}
+
+#ifdef CONFIG_MACH_NET2BIG_V2
+MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2")
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= netxbig_v2_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &netxbig_v2_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_NET5BIG_V2
+MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2")
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= netxbig_v2_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &netxbig_v2_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index a2d307e..244655d 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -59,6 +59,13 @@
 	/* UART1 */
 	GPIO107_UART1_RXD,
 	GPIO108_UART1_TXD,
+
+	/* SSP1 */
+	GPIO113_I2S_MCLK,
+	GPIO114_I2S_FRM,
+	GPIO115_I2S_BCLK,
+	GPIO116_I2S_RXD,
+	GPIO117_I2S_TXD,
 };
 
 static struct smc91x_platdata smc91x_info = {
@@ -123,12 +130,18 @@
 	.nr_parts	= ARRAY_SIZE(aspenite_nand_partitions),
 };
 
+static struct i2c_board_info aspenite_i2c_info[] __initdata = {
+	{ I2C_BOARD_INFO("wm8753", 0x1b), },
+};
+
 static void __init common_init(void)
 {
 	mfp_config(ARRAY_AND_SIZE(common_pin_config));
 
 	/* on-chip devices */
 	pxa168_add_uart(1);
+	pxa168_add_twsi(1, NULL, ARRAY_AND_SIZE(aspenite_i2c_info));
+	pxa168_add_ssp(1);
 	pxa168_add_nand(&aspenite_nand_info);
 
 	/* off-chip devices */
diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h
index ab26d13..ee8b02e 100644
--- a/arch/arm/mach-mmp/include/mach/gpio.h
+++ b/arch/arm/mach-mmp/include/mach/gpio.h
@@ -10,7 +10,7 @@
 #define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
 #define GPIO_REG(x)	(*((volatile u32 *)(GPIO_REGS_VIRT + (x))))
 
-#define NR_BUILTIN_GPIO	(128)
+#define NR_BUILTIN_GPIO	(192)
 
 #define gpio_to_bank(gpio)	((gpio) >> 5)
 #define gpio_to_irq(gpio)	(IRQ_GPIO_START + (gpio))
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
index 0270119..b379cde 100644
--- a/arch/arm/mach-mmp/include/mach/irqs.h
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -5,10 +5,10 @@
  * Interrupt numbers for PXA168
  */
 #define IRQ_PXA168_NONE			(-1)
-#define IRQ_PXA168_SSP3			0
-#define IRQ_PXA168_SSP2			1
-#define IRQ_PXA168_SSP1			2
-#define IRQ_PXA168_SSP0			3
+#define IRQ_PXA168_SSP4			0
+#define IRQ_PXA168_SSP3			1
+#define IRQ_PXA168_SSP2			2
+#define IRQ_PXA168_SSP1			3
 #define IRQ_PXA168_PMIC_INT		4
 #define IRQ_PXA168_RTC_INT		5
 #define IRQ_PXA168_RTC_ALARM		6
@@ -20,7 +20,7 @@
 #define IRQ_PXA168_TIMER2		14
 #define IRQ_PXA168_TIMER3		15
 #define IRQ_PXA168_CMU			16
-#define IRQ_PXA168_SSP4			17
+#define IRQ_PXA168_SSP5			17
 #define IRQ_PXA168_MSP_WAKEUP		19
 #define IRQ_PXA168_CF_WAKEUP		20
 #define IRQ_PXA168_XD_WAKEUP		21
diff --git a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
index 9f9f814..761c2da 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
@@ -9,6 +9,175 @@
 #define MFP_DRIVE_FAST		(0x8 << 13)
 
 /* GPIO */
+#define GPIO0_GPIO0		MFP_CFG(GPIO0, AF0)
+#define GPIO1_GPIO1		MFP_CFG(GPIO1, AF0)
+#define GPIO2_GPIO2		MFP_CFG(GPIO2, AF0)
+#define GPIO3_GPIO3		MFP_CFG(GPIO3, AF0)
+#define GPIO4_GPIO4		MFP_CFG(GPIO4, AF0)
+#define GPIO5_GPIO5		MFP_CFG(GPIO5, AF0)
+#define GPIO6_GPIO6		MFP_CFG(GPIO6, AF0)
+#define GPIO7_GPIO7		MFP_CFG(GPIO7, AF0)
+#define GPIO8_GPIO8		MFP_CFG(GPIO8, AF0)
+#define GPIO9_GPIO9		MFP_CFG(GPIO9, AF0)
+#define GPIO10_GPIO10		MFP_CFG(GPIO10, AF0)
+#define GPIO11_GPIO11		MFP_CFG(GPIO11, AF0)
+#define GPIO12_GPIO12		MFP_CFG(GPIO12, AF0)
+#define GPIO13_GPIO13		MFP_CFG(GPIO13, AF0)
+#define GPIO14_GPIO14		MFP_CFG(GPIO14, AF0)
+#define GPIO15_GPIO15		MFP_CFG(GPIO15, AF0)
+#define GPIO16_GPIO16		MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO17		MFP_CFG(GPIO17, AF0)
+#define GPIO18_GPIO18		MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO19		MFP_CFG(GPIO19, AF0)
+#define GPIO20_GPIO20		MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO21		MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO22		MFP_CFG(GPIO22, AF0)
+#define GPIO23_GPIO23		MFP_CFG(GPIO23, AF0)
+#define GPIO24_GPIO24		MFP_CFG(GPIO24, AF0)
+#define GPIO25_GPIO25		MFP_CFG(GPIO25, AF0)
+#define GPIO26_GPIO26		MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO27		MFP_CFG(GPIO27, AF0)
+#define GPIO28_GPIO28		MFP_CFG(GPIO28, AF0)
+#define GPIO29_GPIO29		MFP_CFG(GPIO29, AF0)
+#define GPIO30_GPIO30		MFP_CFG(GPIO30, AF0)
+#define GPIO31_GPIO31		MFP_CFG(GPIO31, AF0)
+#define GPIO32_GPIO32		MFP_CFG(GPIO32, AF0)
+#define GPIO33_GPIO33		MFP_CFG(GPIO33, AF0)
+#define GPIO34_GPIO34		MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO35		MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO36		MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO37		MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO38		MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO39		MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO40		MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO41		MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO42		MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO43		MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO44		MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO45		MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO46		MFP_CFG(GPIO46, AF0)
+#define GPIO47_GPIO47		MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO48		MFP_CFG(GPIO48, AF0)
+#define GPIO49_GPIO49		MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO50		MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO51		MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO52		MFP_CFG(GPIO52, AF0)
+#define GPIO53_GPIO53		MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO54		MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO55		MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO56		MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO57		MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO58		MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO59		MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO60		MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO61		MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO62		MFP_CFG(GPIO62, AF0)
+#define GPIO63_GPIO63		MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO64		MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO65		MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO66		MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO67		MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO68		MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO69		MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO70		MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO71		MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO72		MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO73		MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO74		MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO75		MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO76		MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO77		MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO78		MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO79		MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO80		MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO81		MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO82		MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO83		MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO84		MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO85		MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO86		MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO87		MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO88		MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO89		MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO90		MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO91		MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO92		MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO93		MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO94		MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO95		MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO96		MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO97		MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO98		MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO99		MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO100		MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO101		MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO102		MFP_CFG(GPIO102, AF1)
+#define GPIO103_GPIO103		MFP_CFG(GPIO103, AF1)
+#define GPIO104_GPIO104		MFP_CFG(GPIO104, AF1)
+#define GPIO105_GPIO105		MFP_CFG(GPIO105, AF1)
+#define GPIO106_GPIO106		MFP_CFG(GPIO106, AF1)
+#define GPIO107_GPIO107		MFP_CFG(GPIO107, AF1)
+#define GPIO108_GPIO108		MFP_CFG(GPIO108, AF1)
+#define GPIO109_GPIO109		MFP_CFG(GPIO109, AF1)
+#define GPIO110_GPIO110		MFP_CFG(GPIO110, AF1)
+#define GPIO111_GPIO111		MFP_CFG(GPIO111, AF1)
+#define GPIO112_GPIO112		MFP_CFG(GPIO112, AF1)
+#define GPIO113_GPIO113		MFP_CFG(GPIO113, AF1)
+#define GPIO114_GPIO114		MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO115		MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO116		MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO117		MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO118		MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO119		MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO120		MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO121		MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO122		MFP_CFG(GPIO122, AF0)
+#define GPIO123_GPIO123		MFP_CFG(GPIO123, AF0)
+#define GPIO124_GPIO124		MFP_CFG(GPIO124, AF0)
+#define GPIO125_GPIO125		MFP_CFG(GPIO125, AF0)
+#define GPIO126_GPIO126		MFP_CFG(GPIO126, AF0)
+#define GPIO127_GPIO127		MFP_CFG(GPIO127, AF0)
+#define GPIO128_GPIO128		MFP_CFG(GPIO128, AF0)
+#define GPIO129_GPIO129		MFP_CFG(GPIO129, AF0)
+#define GPIO130_GPIO130		MFP_CFG(GPIO130, AF0)
+#define GPIO131_GPIO131		MFP_CFG(GPIO131, AF0)
+#define GPIO132_GPIO132		MFP_CFG(GPIO132, AF0)
+#define GPIO133_GPIO133		MFP_CFG(GPIO133, AF0)
+#define GPIO134_GPIO134		MFP_CFG(GPIO134, AF0)
+#define GPIO135_GPIO135		MFP_CFG(GPIO135, AF0)
+#define GPIO136_GPIO136		MFP_CFG(GPIO136, AF0)
+#define GPIO137_GPIO137		MFP_CFG(GPIO137, AF0)
+#define GPIO138_GPIO138		MFP_CFG(GPIO138, AF0)
+#define GPIO139_GPIO139		MFP_CFG(GPIO139, AF0)
+#define GPIO140_GPIO140		MFP_CFG(GPIO140, AF0)
+#define GPIO141_GPIO141		MFP_CFG(GPIO141, AF0)
+#define GPIO142_GPIO142		MFP_CFG(GPIO142, AF1)
+#define GPIO143_GPIO143		MFP_CFG(GPIO143, AF1)
+#define GPIO144_GPIO144		MFP_CFG(GPIO144, AF1)
+#define GPIO145_GPIO145		MFP_CFG(GPIO145, AF1)
+#define GPIO146_GPIO146		MFP_CFG(GPIO146, AF1)
+#define GPIO147_GPIO147		MFP_CFG(GPIO147, AF1)
+#define GPIO148_GPIO148		MFP_CFG(GPIO148, AF1)
+#define GPIO149_GPIO149		MFP_CFG(GPIO149, AF1)
+#define GPIO150_GPIO150		MFP_CFG(GPIO150, AF1)
+#define GPIO151_GPIO151		MFP_CFG(GPIO151, AF1)
+#define GPIO152_GPIO152		MFP_CFG(GPIO152, AF1)
+#define GPIO153_GPIO153		MFP_CFG(GPIO153, AF1)
+#define GPIO154_GPIO154		MFP_CFG(GPIO154, AF1)
+#define GPIO155_GPIO155		MFP_CFG(GPIO155, AF1)
+#define GPIO156_GPIO156		MFP_CFG(GPIO156, AF1)
+#define GPIO157_GPIO157		MFP_CFG(GPIO157, AF1)
+#define GPIO158_GPIO158		MFP_CFG(GPIO158, AF1)
+#define GPIO159_GPIO159		MFP_CFG(GPIO159, AF1)
+#define GPIO160_GPIO160		MFP_CFG(GPIO160, AF1)
+#define GPIO161_GPIO161		MFP_CFG(GPIO161, AF1)
+#define GPIO162_GPIO162		MFP_CFG(GPIO162, AF1)
+#define GPIO163_GPIO163		MFP_CFG(GPIO163, AF1)
+#define GPIO164_GPIO164		MFP_CFG(GPIO164, AF1)
+#define GPIO165_GPIO165		MFP_CFG(GPIO165, AF1)
+#define GPIO166_GPIO166		MFP_CFG(GPIO166, AF1)
+#define GPIO167_GPIO167		MFP_CFG(GPIO167, AF1)
+#define GPIO168_GPIO168		MFP_CFG(GPIO168, AF1)
 
 /* DFI */
 #define GPIO108_DFI_D15		MFP_CFG(GPIO108, AF0)
@@ -47,7 +216,6 @@
 
 /* Ethernet */
 #define GPIO155_SM_ADVMUX	MFP_CFG(GPIO155, AF2)
-#define GPIO155_GPIO155		MFP_CFG(GPIO155, AF1)
 
 /* UART1 */
 #define GPIO45_UART1_RXD	MFP_CFG(GPIO45, AF1)
@@ -159,6 +327,8 @@
 #define GPIO44_TWSI2_SDA	MFP_CFG_DRV(GPIO44, AF1, SLOW)
 #define GPIO71_TWSI3_SCL	MFP_CFG_DRV(GPIO71, AF1, SLOW)
 #define GPIO72_TWSI3_SDA	MFP_CFG_DRV(GPIO72, AF1, SLOW)
+#define TWSI4_SCL		MFP_CFG_DRV(TWSI4_SCL, AF0, SLOW)
+#define TWSI4_SDA		MFP_CFG_DRV(TWSI4_SDA, AF0, SLOW)
 #define GPIO99_TWSI5_SCL	MFP_CFG_DRV(GPIO99, AF4, SLOW)
 #define GPIO100_TWSI5_SDA	MFP_CFG_DRV(GPIO100, AF4, SLOW)
 #define GPIO97_TWSI6_SCL	MFP_CFG_DRV(GPIO97, AF2, SLOW)
@@ -218,21 +388,6 @@
 #define GPIO69_CAM_MCLK		MFP_CFG_DRV(GPIO69, AF1, FAST)
 #define GPIO70_CAM_PCLK		MFP_CFG_DRV(GPIO70, AF1, FAST)
 
-/* Wifi */
-#define GPIO45_GPIO45		MFP_CFG(GPIO45, AF0)
-#define GPIO46_GPIO46		MFP_CFG(GPIO46, AF0)
-#define GPIO21_GPIO21		MFP_CFG(GPIO21, AF0)
-#define GPIO22_GPIO22		MFP_CFG(GPIO22, AF0)
-#define GPIO55_GPIO55		MFP_CFG(GPIO55, AF0)
-#define GPIO56_GPIO56		MFP_CFG(GPIO56, AF0)
-#define GPIO57_GPIO57		MFP_CFG(GPIO57, AF0)
-#define GPIO58_GPIO58		MFP_CFG(GPIO58, AF0)
-
-/* Codec*/
-#define GPIO23_GPIO23		MFP_CFG(GPIO23, AF0)
-
-#define GPIO101_GPIO101		MFP_CFG(GPIO101, AF0)
-
 /* PMIC */
 #define PMIC_PMIC_INT		MFP_CFG(PMIC_INT, AF0)
 
diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h
index 459f3be..fec220b 100644
--- a/arch/arm/mach-mmp/include/mach/mmp2.h
+++ b/arch/arm/mach-mmp/include/mach/mmp2.h
@@ -39,17 +39,17 @@
 	int ret;
 
 	switch (id) {
-	case 0: d = &mmp2_device_twsi1; break;
-	case 1: d = &mmp2_device_twsi2; break;
-	case 2: d = &mmp2_device_twsi3; break;
-	case 3: d = &mmp2_device_twsi4; break;
-	case 4: d = &mmp2_device_twsi5; break;
-	case 5: d = &mmp2_device_twsi6; break;
+	case 1: d = &mmp2_device_twsi1; break;
+	case 2: d = &mmp2_device_twsi2; break;
+	case 3: d = &mmp2_device_twsi3; break;
+	case 4: d = &mmp2_device_twsi4; break;
+	case 5: d = &mmp2_device_twsi5; break;
+	case 6: d = &mmp2_device_twsi6; break;
 	default:
 		return -EINVAL;
 	}
 
-	ret = i2c_register_board_info(id, info, size);
+	ret = i2c_register_board_info(id - 1, info, size);
 	if (ret)
 		return ret;
 
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
index 3ad612c..3b2bd5d 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -14,6 +14,11 @@
 extern struct pxa_device_desc pxa168_device_pwm2;
 extern struct pxa_device_desc pxa168_device_pwm3;
 extern struct pxa_device_desc pxa168_device_pwm4;
+extern struct pxa_device_desc pxa168_device_ssp1;
+extern struct pxa_device_desc pxa168_device_ssp2;
+extern struct pxa_device_desc pxa168_device_ssp3;
+extern struct pxa_device_desc pxa168_device_ssp4;
+extern struct pxa_device_desc pxa168_device_ssp5;
 extern struct pxa_device_desc pxa168_device_nand;
 
 static inline int pxa168_add_uart(int id)
@@ -67,6 +72,22 @@
 	return pxa_register_device(d, NULL, 0);
 }
 
+static inline int pxa168_add_ssp(int id)
+{
+	struct pxa_device_desc *d = NULL;
+
+	switch (id) {
+	case 1: d = &pxa168_device_ssp1; break;
+	case 2: d = &pxa168_device_ssp2; break;
+	case 3: d = &pxa168_device_ssp3; break;
+	case 4: d = &pxa168_device_ssp4; break;
+	case 5: d = &pxa168_device_ssp5; break;
+	default:
+		return -EINVAL;
+	}
+	return pxa_register_device(d, NULL, 0);
+}
+
 static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info)
 {
 	return pxa_register_device(&pxa168_device_nand, info, sizeof(*info));
diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h
index 712af03..1a96585 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apbc.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h
@@ -26,8 +26,6 @@
 #define APBC_PXA168_PWM2	APBC_REG(0x010)
 #define APBC_PXA168_PWM3	APBC_REG(0x014)
 #define APBC_PXA168_PWM4	APBC_REG(0x018)
-#define APBC_PXA168_SSP1	APBC_REG(0x01c)
-#define APBC_PXA168_SSP2	APBC_REG(0x020)
 #define APBC_PXA168_RTC		APBC_REG(0x028)
 #define APBC_PXA168_TWSI0	APBC_REG(0x02c)
 #define APBC_PXA168_KPC		APBC_REG(0x030)
@@ -35,14 +33,16 @@
 #define APBC_PXA168_AIB		APBC_REG(0x03c)
 #define APBC_PXA168_SW_JTAG	APBC_REG(0x040)
 #define APBC_PXA168_ONEWIRE	APBC_REG(0x048)
-#define APBC_PXA168_SSP3	APBC_REG(0x04c)
 #define APBC_PXA168_ASFAR	APBC_REG(0x050)
 #define APBC_PXA168_ASSAR	APBC_REG(0x054)
-#define APBC_PXA168_SSP4	APBC_REG(0x058)
-#define APBC_PXA168_SSP5	APBC_REG(0x05c)
 #define APBC_PXA168_TWSI1	APBC_REG(0x06c)
 #define APBC_PXA168_UART3	APBC_REG(0x070)
 #define APBC_PXA168_AC97	APBC_REG(0x084)
+#define APBC_PXA168_SSP1	APBC_REG(0x81c)
+#define APBC_PXA168_SSP2	APBC_REG(0x820)
+#define APBC_PXA168_SSP3	APBC_REG(0x84c)
+#define APBC_PXA168_SSP4	APBC_REG(0x858)
+#define APBC_PXA168_SSP5	APBC_REG(0x85c)
 
 /*
  * APB Clock register offsets for PXA910
diff --git a/arch/arm/mach-mmp/include/mach/regs-smc.h b/arch/arm/mach-mmp/include/mach/regs-smc.h
new file mode 100644
index 0000000..e484d40
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-smc.h
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-smc.h
+ *
+ *  Static Memory Controller Registers
+ *
+ * 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_MACH_REGS_SMC_H
+#define __ASM_MACH_REGS_SMC_H
+
+#include <mach/addr-map.h>
+
+#define SMC_VIRT_BASE		(AXI_VIRT_BASE + 0x83800)
+#define SMC_REG(x)		(SMC_VIRT_BASE + (x))
+
+#define SMC_MSC0		SMC_REG(0x0020)
+#define SMC_MSC1		SMC_REG(0x0024)
+#define SMC_SXCNFG0		SMC_REG(0x0030)
+#define SMC_SXCNFG1		SMC_REG(0x0034)
+#define SMC_MEMCLKCFG		SMC_REG(0x0068)
+#define SMC_CSDFICFG0		SMC_REG(0x0090)
+#define SMC_CSDFICFG1		SMC_REG(0x0094)
+#define SMC_CLK_RET_DEL		SMC_REG(0x00b0)
+#define SMC_ADV_RET_DEL		SMC_REG(0x00b4)
+#define SMC_CSADRMAP0		SMC_REG(0x00c0)
+#define SMC_CSADRMAP1		SMC_REG(0x00c4)
+#define SMC_WE_AP0		SMC_REG(0x00e0)
+#define SMC_WE_AP1		SMC_REG(0x00e4)
+#define SMC_OE_AP0		SMC_REG(0x00f0)
+#define SMC_OE_AP1		SMC_REG(0x00f4)
+#define SMC_ADV_AP0		SMC_REG(0x0100)
+#define SMC_ADV_AP1		SMC_REG(0x0104)
+
+#endif /* __ASM_MACH_REGS_SMC_H */
diff --git a/arch/arm/mach-mmp/include/mach/timex.h b/arch/arm/mach-mmp/include/mach/timex.h
index 6cebbd0..70c9f1d 100644
--- a/arch/arm/mach-mmp/include/mach/timex.h
+++ b/arch/arm/mach-mmp/include/mach/timex.h
@@ -6,4 +6,8 @@
  * published by the Free Software Foundation.
  */
 
+#ifdef CONFIG_CPU_MMP2
+#define CLOCK_TICK_RATE		6500000
+#else
 #define CLOCK_TICK_RATE		3250000
+#endif
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c
index cfd4d66..d77dd41 100644
--- a/arch/arm/mach-mmp/jasper.c
+++ b/arch/arm/mach-mmp/jasper.c
@@ -15,12 +15,16 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/mfd/max8925.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/addr-map.h>
 #include <mach/mfp-mmp2.h>
 #include <mach/mmp2.h>
+#include <mach/irqs.h>
 
 #include "common.h"
 
@@ -58,6 +62,63 @@
 	GPIO149_ND_CLE,
 	GPIO112_ND_RDY0,
 	GPIO160_ND_RDY1,
+
+	/* PMIC */
+	PMIC_PMIC_INT | MFP_LPM_EDGE_FALL,
+};
+
+static struct regulator_consumer_supply max8649_supply[] = {
+	REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+static struct regulator_init_data max8649_init_data = {
+	.constraints	= {
+		.name		= "vcc_core range",
+		.min_uV		= 1150000,
+		.max_uV		= 1280000,
+		.always_on	= 1,
+		.boot_on	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &max8649_supply[0],
+};
+
+static struct max8649_platform_data jasper_max8649_info = {
+	.mode		= 2,	/* VID1 = 1, VID0 = 0 */
+	.extclk		= 0,
+	.ramp_timing	= MAX8649_RAMP_32MV,
+	.regulator	= &max8649_init_data,
+};
+
+static struct max8925_backlight_pdata jasper_backlight_data = {
+	.dual_string	= 0,
+};
+
+static struct max8925_power_pdata jasper_power_data = {
+	.batt_detect		= 0,	/* can't detect battery by ID pin */
+	.topoff_threshold	= MAX8925_TOPOFF_THR_10PER,
+	.fast_charge		= MAX8925_FCHG_1000MA,
+};
+
+static struct max8925_platform_data jasper_max8925_info = {
+	.backlight		= &jasper_backlight_data,
+	.power			= &jasper_power_data,
+	.irq_base		= IRQ_BOARD_START,
+};
+
+static struct i2c_board_info jasper_twsi1_info[] = {
+	[0] = {
+		.type		= "max8649",
+		.addr		= 0x60,
+		.platform_data	= &jasper_max8649_info,
+	},
+	[1] = {
+		.type		= "max8925",
+		.addr		= 0x3c,
+		.irq		= IRQ_MMP2_PMIC,
+		.platform_data	= &jasper_max8925_info,
+	},
 };
 
 static void __init jasper_init(void)
@@ -67,6 +128,9 @@
 	/* on-chip devices */
 	mmp2_add_uart(1);
 	mmp2_add_uart(3);
+	mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(jasper_twsi1_info));
+
+	regulator_has_full_constraints();
 }
 
 MACHINE_START(MARVELL_JASPER, "Jasper Development Platform")
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index 72eb9da..7f5eb05 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -15,11 +15,14 @@
 #include <linux/init.h>
 #include <linux/io.h>
 
+#include <asm/hardware/cache-tauros2.h>
+
 #include <mach/addr-map.h>
 #include <mach/regs-apbc.h>
 #include <mach/regs-apmu.h>
 #include <mach/cputype.h>
 #include <mach/irqs.h>
+#include <mach/dma.h>
 #include <mach/mfp.h>
 #include <mach/gpio.h>
 #include <mach/devices.h>
@@ -32,7 +35,50 @@
 #define APMASK(i)	(GPIO_REGS_VIRT + BANK_OFF(i) + 0x9c)
 
 static struct mfp_addr_map mmp2_addr_map[] __initdata = {
+
+	MFP_ADDR_X(GPIO0, GPIO58, 0x54),
+	MFP_ADDR_X(GPIO59, GPIO73, 0x280),
+	MFP_ADDR_X(GPIO74, GPIO101, 0x170),
+
+	MFP_ADDR(GPIO102, 0x0),
+	MFP_ADDR(GPIO103, 0x4),
+	MFP_ADDR(GPIO104, 0x1fc),
+	MFP_ADDR(GPIO105, 0x1f8),
+	MFP_ADDR(GPIO106, 0x1f4),
+	MFP_ADDR(GPIO107, 0x1f0),
+	MFP_ADDR(GPIO108, 0x21c),
+	MFP_ADDR(GPIO109, 0x218),
+	MFP_ADDR(GPIO110, 0x214),
+	MFP_ADDR(GPIO111, 0x200),
+	MFP_ADDR(GPIO112, 0x244),
+	MFP_ADDR(GPIO113, 0x25c),
+	MFP_ADDR(GPIO114, 0x164),
+	MFP_ADDR_X(GPIO115, GPIO122, 0x260),
+
+	MFP_ADDR(GPIO123, 0x148),
+	MFP_ADDR_X(GPIO124, GPIO141, 0xc),
+
+	MFP_ADDR(GPIO142, 0x8),
+	MFP_ADDR_X(GPIO143, GPIO151, 0x220),
+	MFP_ADDR_X(GPIO152, GPIO153, 0x248),
+	MFP_ADDR_X(GPIO154, GPIO155, 0x254),
+	MFP_ADDR_X(GPIO156, GPIO159, 0x14c),
+
+	MFP_ADDR(GPIO160, 0x250),
+	MFP_ADDR(GPIO161, 0x210),
+	MFP_ADDR(GPIO162, 0x20c),
+	MFP_ADDR(GPIO163, 0x208),
+	MFP_ADDR(GPIO164, 0x204),
+	MFP_ADDR(GPIO165, 0x1ec),
+	MFP_ADDR(GPIO166, 0x1e8),
+	MFP_ADDR(GPIO167, 0x1e4),
+	MFP_ADDR(GPIO168, 0x1e0),
+
+	MFP_ADDR_X(TWSI1_SCL, TWSI1_SDA, 0x140),
+	MFP_ADDR_X(TWSI4_SCL, TWSI4_SDA, 0x2bc),
+
 	MFP_ADDR(PMIC_INT, 0x2c4),
+	MFP_ADDR(CLK_REQ, 0x160),
 
 	MFP_ADDR_END,
 };
@@ -99,9 +145,13 @@
 static int __init mmp2_init(void)
 {
 	if (cpu_is_mmp2()) {
+#ifdef CONFIG_CACHE_TAUROS2
+		tauros2_init();
+#endif
 		mfp_init_base(MFPR_VIRT_BASE);
 		mfp_init_addr(mmp2_addr_map);
-		clks_register(ARRAY_AND_SIZE(mmp2_clkregs));
+		pxa_init_dma(IRQ_MMP2_DMA_RIQ, 16);
+		clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs));
 	}
 
 	return 0;
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 1873c82..652ae66 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -72,6 +72,11 @@
 static APBC_CLK(pwm2, PXA168_PWM2, 1, 13000000);
 static APBC_CLK(pwm3, PXA168_PWM3, 1, 13000000);
 static APBC_CLK(pwm4, PXA168_PWM4, 1, 13000000);
+static APBC_CLK(ssp1, PXA168_SSP1, 4, 0);
+static APBC_CLK(ssp2, PXA168_SSP2, 4, 0);
+static APBC_CLK(ssp3, PXA168_SSP3, 4, 0);
+static APBC_CLK(ssp4, PXA168_SSP4, 4, 0);
+static APBC_CLK(ssp5, PXA168_SSP5, 4, 0);
 
 static APMU_CLK(nand, NAND, 0x01db, 208000000);
 
@@ -85,6 +90,11 @@
 	INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL),
 	INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL),
 	INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL),
+	INIT_CLKREG(&clk_ssp1, "pxa168-ssp.0", NULL),
+	INIT_CLKREG(&clk_ssp2, "pxa168-ssp.1", NULL),
+	INIT_CLKREG(&clk_ssp3, "pxa168-ssp.2", NULL),
+	INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL),
+	INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL),
 	INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
 };
 
@@ -132,3 +142,8 @@
 PXA168_DEVICE(pwm3, "pxa168-pwm", 2, NONE, 0xd401a800, 0x10);
 PXA168_DEVICE(pwm4, "pxa168-pwm", 3, NONE, 0xd401ac00, 0x10);
 PXA168_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99);
+PXA168_DEVICE(ssp1, "pxa168-ssp", 0, SSP1, 0xd401b000, 0x40, 52, 53);
+PXA168_DEVICE(ssp2, "pxa168-ssp", 1, SSP2, 0xd401c000, 0x40, 54, 55);
+PXA168_DEVICE(ssp3, "pxa168-ssp", 2, SSP3, 0xd401f000, 0x40, 56, 57);
+PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59);
+PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index f780086..b9fd5c5 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -29,12 +29,14 @@
 
 config MACH_HALIBUT
 	depends on ARCH_MSM
+	select CPU_V6
 	default y
 	bool "Halibut Board (QCT SURF7201A)"
 	help
 	  Support for the Qualcomm SURF7201A eval board.
 
 config MACH_TROUT
+	select CPU_V6
 	default y
 	bool "HTC Dream (aka trout)"
 	help
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig
index 3c5e0f5..71f3ea6 100644
--- a/arch/arm/mach-nomadik/Kconfig
+++ b/arch/arm/mach-nomadik/Kconfig
@@ -6,6 +6,7 @@
 	bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
 	select NOMADIK_8815
 	select HAS_MTU
+	select NOMADIK_GPIO
 
 endmenu
 
diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile
index 36f67fb..a6bbd1a 100644
--- a/arch/arm/mach-nomadik/Makefile
+++ b/arch/arm/mach-nomadik/Makefile
@@ -7,7 +7,7 @@
 
 # Object file lists.
 
-obj-y			+= clock.o gpio.o
+obj-y			+= clock.o
 
 # Cpu revision
 obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index ab3712c..841d459 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -32,7 +32,6 @@
 #include <mach/setup.h>
 #include <mach/nand.h>
 #include <mach/fsmc.h>
-#include "clock.h"
 
 /* Initial value for SRC control register: all timers use MXTAL/8 source */
 #define SRC_CR_INIT_MASK	0x00007fff
@@ -202,11 +201,6 @@
 	&uart1_device,
 };
 
-/* We have a fixed clock alone, by now */
-static struct clk nhk8815_clk_48 = {
-	.rate = 48*1000*1000,
-};
-
 static struct resource nhk8815_eth_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -276,10 +270,8 @@
 	platform_add_devices(nhk8815_platform_devices,
 			     ARRAY_SIZE(nhk8815_platform_devices));
 
-	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-		nmdk_clk_create(&nhk8815_clk_48, amba_devs[i]->dev.init_name);
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
-	}
 }
 
 MACHINE_START(NOMADIK, "NHK8815")
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c
index 9f92502..60f5bee 100644
--- a/arch/arm/mach-nomadik/clock.c
+++ b/arch/arm/mach-nomadik/clock.c
@@ -32,14 +32,36 @@
 }
 EXPORT_SYMBOL(clk_disable);
 
-/* Create a clock structure with the given name */
-int nmdk_clk_create(struct clk *clk, const char *dev_id)
-{
-	struct clk_lookup *clkdev;
+/* We have a fixed clock alone, for now */
+static struct clk clk_48 = {
+	.rate = 48 * 1000 * 1000,
+};
 
-	clkdev = clkdev_alloc(clk, NULL, dev_id);
-	if (!clkdev)
-		return -ENOMEM;
-	clkdev_add(clkdev);
+/*
+ * Catch-all default clock to satisfy drivers using the clk API.  We don't
+ * model the actual hardware clocks yet.
+ */
+static struct clk clk_default;
+
+#define CLK(_clk, dev)				\
+	{					\
+		.clk		= _clk,		\
+		.dev_id		= dev,		\
+	}
+
+static struct clk_lookup lookups[] = {
+	CLK(&clk_48, "uart0"),
+	CLK(&clk_48, "uart1"),
+	CLK(&clk_default, "gpio.0"),
+	CLK(&clk_default, "gpio.1"),
+	CLK(&clk_default, "gpio.2"),
+	CLK(&clk_default, "gpio.3"),
+};
+
+static int __init clk_init(void)
+{
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 	return 0;
 }
+
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h
index 235faec..5563985 100644
--- a/arch/arm/mach-nomadik/clock.h
+++ b/arch/arm/mach-nomadik/clock.h
@@ -11,4 +11,3 @@
 struct clk {
 	unsigned long		rate;
 };
-extern int nmdk_clk_create(struct clk *clk, const char *dev_id);
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
index 9bf33b3..91c3c90 100644
--- a/arch/arm/mach-nomadik/cpu-8815.c
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/amba/bus.h>
+#include <linux/platform_device.h>
 #include <linux/gpio.h>
 
 #include <mach/hardware.h>
@@ -30,60 +31,66 @@
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
 
+#define __MEM_4K_RESOURCE(x) \
+	.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
 /* The 8815 has 4 GPIO blocks, let's register them immediately */
+
+#define GPIO_RESOURCE(block)						\
+	{								\
+		.start	= NOMADIK_GPIO##block##_BASE,			\
+		.end	= NOMADIK_GPIO##block##_BASE + SZ_4K - 1,	\
+		.flags	= IORESOURCE_MEM,				\
+	},								\
+	{								\
+		.start	= IRQ_GPIO##block,				\
+		.end	= IRQ_GPIO##block,				\
+		.flags	= IORESOURCE_IRQ,				\
+	}
+
+#define GPIO_DEVICE(block)						\
+	{								\
+		.name 		= "gpio",				\
+		.id		= block,				\
+		.num_resources 	= 2,					\
+		.resource	= &cpu8815_gpio_resources[block * 2],	\
+		.dev = {						\
+			.platform_data = &cpu8815_gpio[block],		\
+		},							\
+	}
+
 static struct nmk_gpio_platform_data cpu8815_gpio[] = {
 	{
 		.name = "GPIO-0-31",
 		.first_gpio = 0,
 		.first_irq = NOMADIK_GPIO_TO_IRQ(0),
-		.parent_irq = IRQ_GPIO0,
 	}, {
 		.name = "GPIO-32-63",
 		.first_gpio = 32,
 		.first_irq = NOMADIK_GPIO_TO_IRQ(32),
-		.parent_irq = IRQ_GPIO1,
 	}, {
 		.name = "GPIO-64-95",
 		.first_gpio = 64,
 		.first_irq = NOMADIK_GPIO_TO_IRQ(64),
-		.parent_irq = IRQ_GPIO2,
 	}, {
 		.name = "GPIO-96-127", /* 124..127 not routed to pin */
 		.first_gpio = 96,
 		.first_irq = NOMADIK_GPIO_TO_IRQ(96),
-		.parent_irq = IRQ_GPIO3,
 	}
 };
 
-#define __MEM_4K_RESOURCE(x) \
-	.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+static struct resource cpu8815_gpio_resources[] = {
+	GPIO_RESOURCE(0),
+	GPIO_RESOURCE(1),
+	GPIO_RESOURCE(2),
+	GPIO_RESOURCE(3),
+};
 
-static struct amba_device cpu8815_amba_gpio[] = {
-	{
-		.dev = {
-			.init_name = "gpio0",
-			.platform_data = cpu8815_gpio + 0,
-		},
-		__MEM_4K_RESOURCE(NOMADIK_GPIO0_BASE),
-	}, {
-		.dev = {
-			.init_name = "gpio1",
-			.platform_data = cpu8815_gpio + 1,
-		},
-		__MEM_4K_RESOURCE(NOMADIK_GPIO1_BASE),
-	}, {
-		.dev = {
-			.init_name = "gpio2",
-			.platform_data = cpu8815_gpio + 2,
-		},
-		__MEM_4K_RESOURCE(NOMADIK_GPIO2_BASE),
-	}, {
-		.dev = {
-			.init_name = "gpio3",
-			.platform_data = cpu8815_gpio + 3,
-		},
-		__MEM_4K_RESOURCE(NOMADIK_GPIO3_BASE),
-	},
+static struct platform_device cpu8815_platform_gpio[] = {
+	GPIO_DEVICE(0),
+	GPIO_DEVICE(1),
+	GPIO_DEVICE(2),
+	GPIO_DEVICE(3),
 };
 
 static struct amba_device cpu8815_amba_rng = {
@@ -93,11 +100,14 @@
 	__MEM_4K_RESOURCE(NOMADIK_RNG_BASE),
 };
 
+static struct platform_device *platform_devs[] __initdata = {
+	cpu8815_platform_gpio + 0,
+	cpu8815_platform_gpio + 1,
+	cpu8815_platform_gpio + 2,
+	cpu8815_platform_gpio + 3,
+};
+
 static struct amba_device *amba_devs[] __initdata = {
-	cpu8815_amba_gpio + 0,
-	cpu8815_amba_gpio + 1,
-	cpu8815_amba_gpio + 2,
-	cpu8815_amba_gpio + 3,
 	&cpu8815_amba_rng
 };
 
@@ -105,6 +115,7 @@
 {
 	int i;
 
+	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
 	return 0;
diff --git a/arch/arm/mach-nomadik/include/mach/gpio.h b/arch/arm/mach-nomadik/include/mach/gpio.h
index 61577c9..7a81a04 100644
--- a/arch/arm/mach-nomadik/include/mach/gpio.h
+++ b/arch/arm/mach-nomadik/include/mach/gpio.h
@@ -1,71 +1,6 @@
-/*
- * Structures and registers for GPIO access in the Nomadik SoC
- *
- * Copyright (C) 2008 STMicroelectronics
- *     Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
- * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
 #ifndef __ASM_ARCH_GPIO_H
 #define __ASM_ARCH_GPIO_H
 
-#include <asm-generic/gpio.h>
-
-/*
- * These currently cause a function call to happen, they may be optimized
- * if needed by adding cpu-specific defines to identify blocks
- * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
- */
-#define gpio_get_value  __gpio_get_value
-#define gpio_set_value  __gpio_set_value
-#define gpio_cansleep   __gpio_cansleep
-#define gpio_to_irq     __gpio_to_irq
-
-/*
- * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
- * the "gpio" namespace for generic and cross-machine functions
- */
-
-/* Register in the logic block */
-#define NMK_GPIO_DAT	0x00
-#define NMK_GPIO_DATS	0x04
-#define NMK_GPIO_DATC	0x08
-#define NMK_GPIO_PDIS	0x0c
-#define NMK_GPIO_DIR	0x10
-#define NMK_GPIO_DIRS	0x14
-#define NMK_GPIO_DIRC	0x18
-#define NMK_GPIO_SLPC	0x1c
-#define NMK_GPIO_AFSLA	0x20
-#define NMK_GPIO_AFSLB	0x24
-
-#define NMK_GPIO_RIMSC	0x40
-#define NMK_GPIO_FIMSC	0x44
-#define NMK_GPIO_IS	0x48
-#define NMK_GPIO_IC	0x4c
-#define NMK_GPIO_RWIMSC	0x50
-#define NMK_GPIO_FWIMSC	0x54
-#define NMK_GPIO_WKS	0x58
-
-/* Alternate functions: function C is set in hw by setting both A and B */
-#define NMK_GPIO_ALT_GPIO	0
-#define NMK_GPIO_ALT_A	1
-#define NMK_GPIO_ALT_B	2
-#define NMK_GPIO_ALT_C	(NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
-
-extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
-extern int nmk_gpio_get_mode(int gpio);
-
-/*
- * Platform data to register a block: only the initial gpio/irq number.
- */
-struct nmk_gpio_platform_data {
-	char *name;
-	int first_gpio;
-	int first_irq;
-	int parent_irq;
-};
+#include <plat/gpio.h>
 
 #endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index e36639f..8e313b4 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 2271b9b..12154d1 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -17,8 +17,10 @@
 #include <linux/clk.h>
 
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
+#include <asm/pmu.h>
 
 #include <plat/control.h>
 #include <plat/tc.h>
@@ -453,6 +455,37 @@
 static inline void omap_init_mcspi(void) {}
 #endif
 
+static struct resource omap2_pmu_resource = {
+	.start	= 3,
+	.end	= 3,
+	.flags	= IORESOURCE_IRQ,
+};
+
+static struct resource omap3_pmu_resource = {
+	.start	= INT_34XX_BENCH_MPU_EMUL,
+	.end	= INT_34XX_BENCH_MPU_EMUL,
+	.flags	= IORESOURCE_IRQ,
+};
+
+static struct platform_device omap_pmu_device = {
+	.name		= "arm-pmu",
+	.id		= ARM_PMU_DEVICE_CPU,
+	.num_resources	= 1,
+};
+
+static void omap_init_pmu(void)
+{
+	if (cpu_is_omap24xx())
+		omap_pmu_device.resource = &omap2_pmu_resource;
+	else if (cpu_is_omap34xx())
+		omap_pmu_device.resource = &omap3_pmu_resource;
+	else
+		return;
+
+	platform_device_register(&omap_pmu_device);
+}
+
+
 #ifdef CONFIG_OMAP_SHA1_MD5
 static struct resource sha1_md5_resources[] = {
 	{
@@ -797,6 +830,7 @@
 	omap_init_camera();
 	omap_init_mbox();
 	omap_init_mcspi();
+	omap_init_pmu();
 	omap_hdq_init();
 	omap_init_sti();
 	omap_init_sha1_md5();
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index e436dcb..2c12e8c 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -43,7 +43,6 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include <linux/bootmem.h>
 
 #include <plat/common.h>
 #include <plat/cpu.h>
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index 421b82f..685f34a 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -439,6 +439,7 @@
 	 */
 	if (dns323_dev_id() == MV88F5181_DEV_ID) {
 		dns323_leds[0].active_low = 1;
+		gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable");
 		gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
 	}
 
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 5b6ee46..3b51741 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -19,7 +19,6 @@
 config MACH_ZYLONITE
 	bool
 	select PXA3xx
-	select PXA_SSP
 	select HAVE_PWM
 	select PXA_HAVE_BOARD_IRQS
 
@@ -39,7 +38,6 @@
 	select PXA3xx
 	select CPU_PXA300
 	select CPU_PXA310
-	select PXA_SSP
 
 config MACH_TAVOREVB
 	bool "PXA930 Evaluation Board (aka TavorEVB)"
@@ -98,7 +96,6 @@
 	select PXA27x
 	select IWMMXT
 	select PXA25x
-	select PXA_SSP
 
 config MACH_EM_X270
 	bool "CompuLab EM-x270 platform"
@@ -161,7 +158,6 @@
 	select MTD_CFI
 	select MTD_CHAR
 	select SMC91X
-	select PXA_SSP
 	help
 	  PXA255 based Single Board Computer with SMC 91C111 ethernet chip and 64 MB of flash.
 	  Tuned for usage in Libera instruments for particle accelerators.
@@ -180,7 +176,6 @@
 	depends on TRIZEPS_PXA
 	select TRIZEPS_PCMCIA
 	select PXA27x
-	select PXA_SSP
 
 choice
 	prompt "Select base board for Trizeps module"
@@ -217,7 +212,6 @@
 	bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
 	select PXA27x
 	select IWMMXT
-	select PXA_SSP
 	select PXA_HAVE_BOARD_IRQS
 
 config MACH_PCM990_BASEBOARD
@@ -255,13 +249,19 @@
 	select PXA3xx
 	select CPU_PXA320
 
+config MACH_VPAC270
+	bool "Voipac PXA270"
+	select PXA27x
+	select HAVE_PATA_PLATFORM
+	help
+	  PXA270 based Single Board Computer.
+
 comment "End-user Products (sorted by vendor name)"
 
 config MACH_H4700
 	bool "HP iPAQ hx4700"
 	select PXA27x
 	select IWMMXT
-	select PXA_SSP
 	select HAVE_PWM
 	select PXA_HAVE_BOARD_IRQS
 
@@ -277,7 +277,6 @@
 	bool "Enable HTC Magician Support"
 	select PXA27x
 	select IWMMXT
-	select PXA_SSP
 	select HAVE_PWM
 	select PXA_HAVE_BOARD_IRQS
 
@@ -431,13 +430,11 @@
 	bool "Raumfeld Connector"
 	select PXA3xx
 	select CPU_PXA300
-	select PXA_SSP
 
 config MACH_RAUMFELD_SPEAKER
 	bool "Raumfeld Speaker"
 	select PXA3xx
 	select CPU_PXA300
-	select PXA_SSP
 
 config PXA_SHARPSL
 	bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
@@ -461,21 +458,11 @@
 	select HWMON
 	select SENSORS_MAX1111
 
-config CORGI_SSP_DEPRECATED
-	bool
-	select PXA_SSP
-	select PXA_SSP_LEGACY
-	help
-	  This option will include corgi_ssp.c and corgi_lcd.c
-	  that corgi_ts.c and other legacy drivers (corgi_bl.c
-	  and sharpsl_pm.c) may depend on.
-
 config MACH_POODLE
 	bool "Enable Sharp SL-5600 (Poodle) Support"
 	depends on PXA_SHARPSL
 	select PXA25x
 	select SHARP_LOCOMO
-	select PXA_SSP
 	select PXA_HAVE_BOARD_IRQS
 
 config MACH_CORGI
@@ -581,6 +568,12 @@
 	  Say Y here if you intend to run this kernel on a Toshiba
 	  e800 family PDA.
 
+config MACH_ZIPIT2
+	bool "Zipit Z2 Handheld"
+	select PXA27x
+	select HAVE_PWM
+	select PXA_HAVE_BOARD_IRQS
+
 endmenu
 
 config PXA25x
@@ -645,28 +638,16 @@
 
 config PXA_SHARP_C7xx
 	bool
-	select PXA_SSP
 	select SHARPSL_PM
 	help
 	  Enable support for all Sharp C7xx models
 
 config PXA_SHARP_Cxx00
 	bool
-	select PXA_SSP
 	select SHARPSL_PM
 	help
 	  Enable common support for Sharp Cxx00 models
 
-config PXA_SSP
-	tristate
-	help
-	  Enable support for PXA2xx SSP ports
-
-config PXA_SSP_LEGACY
-	bool
-	help
-	  Support of legacy SSP API
-
 config TOSA_BT
 	tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
 	depends on MACH_TOSA
@@ -675,6 +656,18 @@
 	  This is a simple driver that is able to control
 	  the state of built in bluetooth chip on tosa.
 
+config TOSA_USE_EXT_KEYCODES
+	bool "Tosa keyboard: use extended keycodes"
+	depends on MACH_TOSA
+	default n
+	help
+	  Say Y here to enable the tosa keyboard driver to generate extended
+	  (>= 127) keycodes. Be aware, that they can't be correctly interpreted
+	  by either console keyboard driver or by Kdrive keybd driver.
+
+	  Say Y only if you know, what you are doing!
+
+
 config PXA_HAVE_BOARD_IRQS
 	bool
 
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 86bc87b..b8f1f4b 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -14,7 +14,6 @@
 endif
 
 # Generic drivers that other drivers may depend upon
-obj-$(CONFIG_PXA_SSP)		+= ssp.o
 
 # SoC-specific code
 obj-$(CONFIG_PXA25x)		+= mfp-pxa2xx.o pxa2xx.o pxa25x.o
@@ -62,6 +61,7 @@
 obj-$(CONFIG_MACH_COLIBRI)	+= colibri-pxa270.o
 obj-$(CONFIG_MACH_COLIBRI300)	+= colibri-pxa3xx.o colibri-pxa300.o
 obj-$(CONFIG_MACH_COLIBRI320)	+= colibri-pxa3xx.o colibri-pxa320.o
+obj-$(CONFIG_MACH_VPAC270)	+= vpac270.o
 
 # End-user Products
 obj-$(CONFIG_MACH_H4700)	+= hx4700.o
@@ -80,7 +80,6 @@
 obj-$(CONFIG_PALM_TREO)		+= palmtreo.o
 obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o sharpsl_pm.o corgi_pm.o
 obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o sharpsl_pm.o spitz_pm.o
-obj-$(CONFIG_CORGI_SSP_DEPRECATED)	+= corgi_ssp.o corgi_lcd.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 obj-$(CONFIG_MACH_TOSA)		+= tosa.o
 obj-$(CONFIG_MACH_ICONTROL)     += icontrol.o mxm8x10.o
@@ -94,6 +93,7 @@
 obj-$(CONFIG_MACH_RAUMFELD_RC)		+= raumfeld.o
 obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR)	+= raumfeld.o
 obj-$(CONFIG_MACH_RAUMFELD_SPEAKER)	+= raumfeld.o
+obj-$(CONFIG_MACH_ZIPIT2)	+= z2.o
 
 # Support for blinky lights
 led-y := leds.o
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index d37cfa1..fdda6be 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -30,6 +30,9 @@
 #include <linux/i2c/pca953x.h>
 
 #include <linux/mfd/da903x.h>
+#include <linux/regulator/machine.h>
+#include <linux/power_supply.h>
+#include <linux/apm-emulation.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_gpio.h>
@@ -430,7 +433,7 @@
 
 #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
 static struct pxamci_platform_data cm_x300_mci_platform_data = {
-	.detect_delay		= 20,
+	.detect_delay_ms	= 200,
 	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
 	.gpio_card_detect	= GPIO82_MMC_IRQ,
 	.gpio_card_ro		= GPIO85_MMC_WP,
@@ -451,7 +454,7 @@
 }
 
 static struct pxamci_platform_data cm_x300_mci2_platform_data = {
-	.detect_delay		= 20,
+	.detect_delay_ms	= 200,
 	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
 	.init 			= cm_x300_mci2_init,
 	.exit			= cm_x300_mci2_exit,
@@ -584,12 +587,87 @@
 static inline void cm_x300_init_rtc(void) {}
 #endif
 
+/* Battery */
+struct power_supply_info cm_x300_psy_info = {
+	.name = "battery",
+	.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.voltage_max_design = 4200000,
+	.voltage_min_design = 3000000,
+	.use_for_apm = 1,
+};
+
+static void cm_x300_battery_low(void)
+{
+#if defined(CONFIG_APM_EMULATION)
+	apm_queue_event(APM_LOW_BATTERY);
+#endif
+}
+
+static void cm_x300_battery_critical(void)
+{
+#if defined(CONFIG_APM_EMULATION)
+	apm_queue_event(APM_CRITICAL_SUSPEND);
+#endif
+}
+
+struct da9030_battery_info cm_x300_battery_info = {
+	.battery_info = &cm_x300_psy_info,
+
+	.charge_milliamp = 1000,
+	.charge_millivolt = 4200,
+
+	.vbat_low = 3600,
+	.vbat_crit = 3400,
+	.vbat_charge_start = 4100,
+	.vbat_charge_stop = 4200,
+	.vbat_charge_restart = 4000,
+
+	.vcharge_min = 3200,
+	.vcharge_max = 5500,
+
+	.tbat_low = 197,
+	.tbat_high = 78,
+	.tbat_restart = 100,
+
+	.batmon_interval = 0,
+
+	.battery_low = cm_x300_battery_low,
+	.battery_critical = cm_x300_battery_critical,
+};
+
+static struct regulator_consumer_supply buck2_consumers[] = {
+	{
+		.dev = NULL,
+		.supply = "vcc_core",
+	},
+};
+
+static struct regulator_init_data buck2_data = {
+	.constraints = {
+		.min_uV = 1375000,
+		.max_uV = 1375000,
+		.state_mem = {
+			.enabled = 0,
+		},
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+		.apply_uV = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(buck2_consumers),
+	.consumer_supplies = buck2_consumers,
+};
+
 /* DA9030 */
 struct da903x_subdev_info cm_x300_da9030_subdevs[] = {
 	{
-		.name = "da903x-backlight",
-		.id = DA9030_ID_WLED,
-	}
+		.name = "da903x-battery",
+		.id = DA9030_ID_BAT,
+		.platform_data = &cm_x300_battery_info,
+	},
+	{
+		.name = "da903x-regulator",
+		.id = DA9030_ID_BUCK2,
+		.platform_data = &buck2_data,
+	},
 };
 
 static struct da903x_platform_data cm_x300_da9030_info = {
@@ -599,7 +677,7 @@
 
 static struct i2c_board_info cm_x300_pmic_info = {
 	I2C_BOARD_INFO("da9030", 0x49),
-	.irq = IRQ_GPIO(0),
+	.irq = IRQ_WAKEUP0,
 	.platform_data = &cm_x300_da9030_info,
 };
 
@@ -689,13 +767,13 @@
 static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags,
 				 char **cmdline, struct meminfo *mi)
 {
-	mi->nr_banks = 2;
-	mi->bank[0].start = 0xa0000000;
-	mi->bank[0].node = 0;
-	mi->bank[0].size = (64*1024*1024);
-	mi->bank[1].start = 0xc0000000;
-	mi->bank[1].node = 0;
-	mi->bank[1].size = (64*1024*1024);
+	/* Make sure that mi->bank[0].start = PHYS_ADDR */
+	for (; tags->hdr.size; tags = tag_next(tags))
+		if (tags->hdr.tag == ATAG_MEM &&
+			tags->u.mem.start == 0x80000000) {
+			tags->u.mem.start = 0xa0000000;
+			break;
+		}
 }
 
 MACHINE_START(CM_X300, "CM-X300 module")
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index e6c0a22..199afa2 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -96,7 +96,7 @@
 }
 
 static struct pxamci_platform_data colibri_pxa3xx_mci_platform_data = {
-	.detect_delay		= 20,
+	.detect_delay_ms	= 200,
 	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
 	.init			= colibri_pxa3xx_mci_init,
 	.exit			= colibri_pxa3xx_mci_exit,
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index da3156d86..3d1dcb9 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -106,18 +106,18 @@
 	GPIO8_MMC_CS0,
 
 	/* GPIO Matrix Keypad */
-	GPIO66_GPIO,	/* column 0 */
-	GPIO67_GPIO,	/* column 1 */
-	GPIO68_GPIO,	/* column 2 */
-	GPIO69_GPIO,	/* column 3 */
-	GPIO70_GPIO,	/* column 4 */
-	GPIO71_GPIO,	/* column 5 */
-	GPIO72_GPIO,	/* column 6 */
-	GPIO73_GPIO,	/* column 7 */
-	GPIO74_GPIO,	/* column 8 */
-	GPIO75_GPIO,	/* column 9 */
-	GPIO76_GPIO,	/* column 10 */
-	GPIO77_GPIO,	/* column 11 */
+	GPIO66_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 0 */
+	GPIO67_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 1 */
+	GPIO68_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 2 */
+	GPIO69_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 3 */
+	GPIO70_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 4 */
+	GPIO71_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 5 */
+	GPIO72_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 6 */
+	GPIO73_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 7 */
+	GPIO74_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 8 */
+	GPIO75_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 9 */
+	GPIO76_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 10 */
+	GPIO77_GPIO | MFP_LPM_DRIVE_HIGH,	/* column 11 */
 	GPIO58_GPIO,	/* row 0 */
 	GPIO59_GPIO,	/* row 1 */
 	GPIO60_GPIO,	/* row 2 */
@@ -128,13 +128,20 @@
 	GPIO65_GPIO,	/* row 7 */
 
 	/* GPIO */
-	GPIO9_GPIO,	/* CORGI_GPIO_nSD_DETECT */
-	GPIO7_GPIO,	/* CORGI_GPIO_nSD_WP */
-	GPIO33_GPIO,	/* CORGI_GPIO_SD_PWR */
-	GPIO22_GPIO,	/* CORGI_GPIO_IR_ON */
-	GPIO44_GPIO,	/* CORGI_GPIO_HSYNC */
+	GPIO9_GPIO,				/* CORGI_GPIO_nSD_DETECT */
+	GPIO7_GPIO,				/* CORGI_GPIO_nSD_WP */
+	GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,	/* CORGI_GPIO_MAIN_BAT_{LOW,COVER} */
+	GPIO13_GPIO | MFP_LPM_KEEP_OUTPUT,	/* CORGI_GPIO_LED_ORANGE */
+	GPIO21_GPIO,				/* CORGI_GPIO_ADC_TEMP */
+	GPIO22_GPIO,				/* CORGI_GPIO_IR_ON */
+	GPIO33_GPIO,				/* CORGI_GPIO_SD_PWR */
+	GPIO38_GPIO | MFP_LPM_KEEP_OUTPUT,	/* CORGI_GPIO_CHRG_ON */
+	GPIO43_GPIO | MFP_LPM_KEEP_OUTPUT,	/* CORGI_GPIO_CHRG_UKN */
+	GPIO44_GPIO,				/* CORGI_GPIO_HSYNC */
 
-	GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
+	GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,	/* CORGI_GPIO_KEY_INT */
+	GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,	/* CORGI_GPIO_AC_IN */
+	GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH,	/* CORGI_GPIO_WAKEUP */
 };
 
 /*
@@ -437,6 +444,7 @@
  * to give the card a chance to fully insert/eject.
  */
 static struct pxamci_platform_data corgi_mci_platform_data = {
+	.detect_delay_ms	= 250,
 	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
 	.gpio_card_detect	= -1,
 	.gpio_card_ro		= CORGI_GPIO_nSD_WP,
@@ -672,6 +680,15 @@
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config));
 
+	/* allow wakeup from various GPIOs */
+	gpio_set_wake(CORGI_GPIO_KEY_INT, 1);
+	gpio_set_wake(CORGI_GPIO_WAKEUP, 1);
+	gpio_set_wake(CORGI_GPIO_AC_IN, 1);
+	gpio_set_wake(CORGI_GPIO_CHRG_FULL, 1);
+
+	if (!machine_is_corgi())
+		gpio_set_wake(CORGI_GPIO_MAIN_BAT_LOW, 1);
+
 	pxa_set_ffuart_info(NULL);
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
@@ -679,7 +696,6 @@
 	corgi_init_spi();
 
  	pxa_set_udc_info(&udc_info);
-	corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&corgi_mci_platform_data);
 	pxa_set_ficp_info(&corgi_ficp_platform_data);
 	pxa_set_i2c_info(NULL);
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
deleted file mode 100644
index d9b9631..0000000
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/corgi_lcd.c
- *
- * Corgi/Spitz LCD Specific Code
- *
- * Copyright (C) 2005 Richard Purdie
- *
- * Connectivity:
- *   Corgi - LCD to ATI Imageon w100 (Wallaby)
- *   Spitz - LCD to PXA Framebuffer
- *
- * 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/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <mach/corgi.h>
-#include <mach/hardware.h>
-#include <mach/sharpsl.h>
-#include <mach/spitz.h>
-#include <asm/hardware/scoop.h>
-#include <asm/mach/sharpsl_param.h>
-#include "generic.h"
-
-/* Register Addresses */
-#define RESCTL_ADRS     0x00
-#define PHACTRL_ADRS    0x01
-#define DUTYCTRL_ADRS   0x02
-#define POWERREG0_ADRS  0x03
-#define POWERREG1_ADRS  0x04
-#define GPOR3_ADRS      0x05
-#define PICTRL_ADRS     0x06
-#define POLCTRL_ADRS    0x07
-
-/* Register Bit Definitions */
-#define RESCTL_QVGA     0x01
-#define RESCTL_VGA      0x00
-
-#define POWER1_VW_ON    0x01  /* VW Supply FET ON */
-#define POWER1_GVSS_ON  0x02  /* GVSS(-8V) Power Supply ON */
-#define POWER1_VDD_ON   0x04  /* VDD(8V),SVSS(-4V) Power Supply ON */
-
-#define POWER1_VW_OFF   0x00  /* VW Supply FET OFF */
-#define POWER1_GVSS_OFF 0x00  /* GVSS(-8V) Power Supply OFF */
-#define POWER1_VDD_OFF  0x00  /* VDD(8V),SVSS(-4V) Power Supply OFF */
-
-#define POWER0_COM_DCLK 0x01  /* COM Voltage DC Bias DAC Serial Data Clock */
-#define POWER0_COM_DOUT 0x02  /* COM Voltage DC Bias DAC Serial Data Out */
-#define POWER0_DAC_ON   0x04  /* DAC Power Supply ON */
-#define POWER0_COM_ON   0x08  /* COM Power Supply ON */
-#define POWER0_VCC5_ON  0x10  /* VCC5 Power Supply ON */
-
-#define POWER0_DAC_OFF  0x00  /* DAC Power Supply OFF */
-#define POWER0_COM_OFF  0x00  /* COM Power Supply OFF */
-#define POWER0_VCC5_OFF 0x00  /* VCC5 Power Supply OFF */
-
-#define PICTRL_INIT_STATE      0x01
-#define PICTRL_INIOFF          0x02
-#define PICTRL_POWER_DOWN      0x04
-#define PICTRL_COM_SIGNAL_OFF  0x08
-#define PICTRL_DAC_SIGNAL_OFF  0x10
-
-#define POLCTRL_SYNC_POL_FALL  0x01
-#define POLCTRL_EN_POL_FALL    0x02
-#define POLCTRL_DATA_POL_FALL  0x04
-#define POLCTRL_SYNC_ACT_H     0x08
-#define POLCTRL_EN_ACT_L       0x10
-
-#define POLCTRL_SYNC_POL_RISE  0x00
-#define POLCTRL_EN_POL_RISE    0x00
-#define POLCTRL_DATA_POL_RISE  0x00
-#define POLCTRL_SYNC_ACT_L     0x00
-#define POLCTRL_EN_ACT_H       0x00
-
-#define PHACTRL_PHASE_MANUAL   0x01
-#define DEFAULT_PHAD_QVGA     (9)
-#define DEFAULT_COMADJ        (125)
-
-/*
- * This is only a psuedo I2C interface. We can't use the standard kernel
- * routines as the interface is write only. We just assume the data is acked...
- */
-static void lcdtg_ssp_i2c_send(u8 data)
-{
-	corgi_ssp_lcdtg_send(POWERREG0_ADRS, data);
-	udelay(10);
-}
-
-static void lcdtg_i2c_send_bit(u8 data)
-{
-	lcdtg_ssp_i2c_send(data);
-	lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
-	lcdtg_ssp_i2c_send(data);
-}
-
-static void lcdtg_i2c_send_start(u8 base)
-{
-	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
-	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
-	lcdtg_ssp_i2c_send(base);
-}
-
-static void lcdtg_i2c_send_stop(u8 base)
-{
-	lcdtg_ssp_i2c_send(base);
-	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
-	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
-}
-
-static void lcdtg_i2c_send_byte(u8 base, u8 data)
-{
-	int i;
-	for (i = 0; i < 8; i++) {
-		if (data & 0x80)
-			lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
-		else
-			lcdtg_i2c_send_bit(base);
-		data <<= 1;
-	}
-}
-
-static void lcdtg_i2c_wait_ack(u8 base)
-{
-	lcdtg_i2c_send_bit(base);
-}
-
-static void lcdtg_set_common_voltage(u8 base_data, u8 data)
-{
-	/* Set Common Voltage to M62332FP via I2C */
-	lcdtg_i2c_send_start(base_data);
-	lcdtg_i2c_send_byte(base_data, 0x9c);
-	lcdtg_i2c_wait_ack(base_data);
-	lcdtg_i2c_send_byte(base_data, 0x00);
-	lcdtg_i2c_wait_ack(base_data);
-	lcdtg_i2c_send_byte(base_data, data);
-	lcdtg_i2c_wait_ack(base_data);
-	lcdtg_i2c_send_stop(base_data);
-}
-
-/* Set Phase Adjust */
-static void lcdtg_set_phadadj(int mode)
-{
-	int adj;
-	switch(mode) {
-		case 480:
-		case 640:
-			/* Setting for VGA */
-			adj = sharpsl_param.phadadj;
-			if (adj < 0) {
-				adj = PHACTRL_PHASE_MANUAL;
-			} else {
-				adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
-			}
-			break;
-		case 240:
-		case 320:
-		default:
-			/* Setting for QVGA */
-			adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
-			break;
-	}
-
-	corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj);
-}
-
-static int lcd_inited;
-
-void corgi_lcdtg_hw_init(int mode)
-{
-	if (!lcd_inited) {
-		int comadj;
-
-		/* Initialize Internal Logic & Port */
-		corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE
-	  			| PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF);
-
-		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF
-				| POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
-
-		/* VDD(+8V), SVSS(-4V) ON */
-		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
-		mdelay(3);
-
-		/* DAC ON */
-		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
-				| POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-		/* INIB = H, INI = L  */
-		/* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
-		corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
-
-		/* Set Common Voltage */
-		comadj = sharpsl_param.comadj;
-		if (comadj < 0)
-			comadj = DEFAULT_COMADJ;
-		lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
-
-		/* VCC5 ON, DAC ON */
-		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
-				POWER0_COM_OFF | POWER0_VCC5_ON);
-
-		/* GVSS(-8V) ON, VDD ON */
-		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
-		mdelay(2);
-
-		/* COM SIGNAL ON (PICTL[3] = L) */
-		corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE);
-
-		/* COM ON, DAC ON, VCC5_ON */
-		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
-				| POWER0_COM_ON | POWER0_VCC5_ON);
-
-		/* VW ON, GVSS ON, VDD ON */
-		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
-
-		/* Signals output enable */
-		corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
-
-		/* Set Phase Adjust */
-		lcdtg_set_phadadj(mode);
-
-		/* Initialize for Input Signals from ATI */
-		corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
-				| POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H);
-		udelay(1000);
-
-		lcd_inited=1;
-	} else {
-		lcdtg_set_phadadj(mode);
-	}
-
-	switch(mode) {
-		case 480:
-		case 640:
-			/* Set Lcd Resolution (VGA) */
-			corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA);
-			break;
-		case 240:
-		case 320:
-		default:
-			/* Set Lcd Resolution (QVGA) */
-			corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA);
-			break;
-	}
-}
-
-void corgi_lcdtg_suspend(void)
-{
-	/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
-	mdelay(34);
-
-	/* (1)VW OFF */
-	corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
-
-	/* (2)COM OFF */
-	corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
-	corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
-
-	/* (3)Set Common Voltage Bias 0V */
-	lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
-
-	/* (4)GVSS OFF */
-	corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
-
-	/* (5)VCC5 OFF */
-	corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-	/* (6)Set PDWN, INIOFF, DACOFF */
-	corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
-			PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
-
-	/* (7)DAC OFF */
-	corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-	/* (8)VDD OFF */
-	corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
-
-	lcd_inited = 0;
-}
-
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
index d4a0733..3f1dc74 100644
--- a/arch/arm/mach-pxa/corgi_pm.c
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/apm-emulation.h>
@@ -25,7 +26,8 @@
 #include <mach/sharpsl.h>
 #include <mach/corgi.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+
+#include "generic.h"
 #include "sharpsl.h"
 
 #define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
@@ -35,87 +37,46 @@
 #define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
 #define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
 
+static struct gpio charger_gpios[] = {
+	{ CORGI_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
+	{ CORGI_GPIO_CHRG_ON,	  GPIOF_OUT_INIT_LOW, "Charger On" },
+	{ CORGI_GPIO_CHRG_UKN,	  GPIOF_OUT_INIT_LOW, "Charger Unknown" },
+	{ CORGI_GPIO_KEY_INT,	  GPIOF_IN, "Key Interrupt" },
+};
+
 static void corgi_charger_init(void)
 {
-	pxa_gpio_mode(CORGI_GPIO_ADC_TEMP_ON | GPIO_OUT);
-	pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT);
-	pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT);
-	pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN);
+	gpio_request_array(ARRAY_AND_SIZE(charger_gpios));
 }
 
 static void corgi_measure_temp(int on)
 {
-	if (on)
-		GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
-	else
-		GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+	gpio_set_value(CORGI_GPIO_ADC_TEMP_ON, on);
 }
 
 static void corgi_charge(int on)
 {
 	if (on) {
 		if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) {
-			GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
-			GPSR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+			gpio_set_value(CORGI_GPIO_CHRG_ON, 0);
+			gpio_set_value(CORGI_GPIO_CHRG_UKN, 1);
 		} else {
-			GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
-			GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+			gpio_set_value(CORGI_GPIO_CHRG_ON, 1);
+			gpio_set_value(CORGI_GPIO_CHRG_UKN, 0);
 		}
 	} else {
-		GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
-		GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+		gpio_set_value(CORGI_GPIO_CHRG_ON, 0);
+		gpio_set_value(CORGI_GPIO_CHRG_UKN, 0);
 	}
 }
 
 static void corgi_discharge(int on)
 {
-	if (on)
-		GPSR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
-	else
-		GPCR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
+	gpio_set_value(CORGI_GPIO_DISCHARGE_ON, on);
 }
 
 static void corgi_presuspend(void)
 {
-	int i;
-	unsigned long wakeup_mask;
-
-	/* charging , so CHARGE_ON bit is HIGH during OFF. */
-	if (READ_GPIO_BIT(CORGI_GPIO_CHRG_ON))
-		PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON);
-	else
-		PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON);
-
-	if (READ_GPIO_BIT(CORGI_GPIO_LED_ORANGE))
-		PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE);
-	else
-		PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE);
-
-	if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN))
-		PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN);
-	else
-		PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN);
-
-	/* Resume on keyboard power key */
-	PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0);
-
-	wakeup_mask = GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CHRG_FULL);
-
-	if (!machine_is_corgi())
-		wakeup_mask |= GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW);
-
-	PWER = wakeup_mask | PWER_RTC;
-	PRER = wakeup_mask;
-	PFER = wakeup_mask;
-
-	for (i = 0; i <=15; i++) {
-		if (PRER & PFER & GPIO_bit(i)) {
-			if (GPLR0 & GPIO_bit(i) )
-				PRER &= ~GPIO_bit(i);
-			else
-				PFER &= ~GPIO_bit(i);
-		}
-	}
 }
 
 static void corgi_postsuspend(void)
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
deleted file mode 100644
index 9347254..0000000
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- *  SSP control code for Sharp Corgi devices
- *
- *  Copyright (c) 2004-2005 Richard Purdie
- *
- *  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/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-
-#include <mach/ssp.h>
-#include <mach/pxa2xx-gpio.h>
-#include <mach/regs-ssp.h>
-#include "sharpsl.h"
-
-static DEFINE_SPINLOCK(corgi_ssp_lock);
-static struct ssp_dev corgi_ssp_dev;
-static struct ssp_state corgi_ssp_state;
-static struct corgissp_machinfo *ssp_machinfo;
-
-/*
- * There are three devices connected to the SSP interface:
- *   1. A touchscreen controller (TI ADS7846 compatible)
- *   2. An LCD controller (with some Backlight functionality)
- *   3. A battery monitoring IC (Maxim MAX1111)
- *
- * Each device uses a different speed/mode of communication.
- *
- * The touchscreen is very sensitive and the most frequently used
- * so the port is left configured for this.
- *
- * Devices are selected using Chip Selects on GPIOs.
- */
-
-/*
- *  ADS7846 Routines
- */
-unsigned long corgi_ssp_ads7846_putget(ulong data)
-{
-	unsigned long flag;
-	u32 ret = 0;
-
-	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-
-	ssp_write_word(&corgi_ssp_dev,data);
- 	ssp_read_word(&corgi_ssp_dev, &ret);
-
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
-
-	return ret;
-}
-
-/*
- * NOTE: These functions should always be called in interrupt context
- * and use the _lock and _unlock functions. They are very time sensitive.
- */
-void corgi_ssp_ads7846_lock(void)
-{
-	spin_lock(&corgi_ssp_lock);
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-}
-
-void corgi_ssp_ads7846_unlock(void)
-{
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-	spin_unlock(&corgi_ssp_lock);
-}
-
-void corgi_ssp_ads7846_put(ulong data)
-{
-	ssp_write_word(&corgi_ssp_dev,data);
-}
-
-unsigned long corgi_ssp_ads7846_get(void)
-{
-	u32 ret = 0;
-	ssp_read_word(&corgi_ssp_dev, &ret);
-	return ret;
-}
-
-EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
-EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
-EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
-EXPORT_SYMBOL(corgi_ssp_ads7846_put);
-EXPORT_SYMBOL(corgi_ssp_ads7846_get);
-
-
-/*
- *  LCD/Backlight Routines
- */
-unsigned long corgi_ssp_dac_put(ulong data)
-{
-	unsigned long flag, sscr1 = SSCR1_SPH;
-	u32 tmp;
-
-	spin_lock_irqsave(&corgi_ssp_lock, flag);
-
-	if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi())
-		sscr1 = 0;
-
-	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon));
-	ssp_enable(&corgi_ssp_dev);
-
-	if (ssp_machinfo->cs_lcdcon >= 0)
-		GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
-	ssp_write_word(&corgi_ssp_dev,data);
-	/* Read null data back from device to prevent SSP overflow */
-	ssp_read_word(&corgi_ssp_dev, &tmp);
-	if (ssp_machinfo->cs_lcdcon >= 0)
-		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
-
-	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
-	ssp_enable(&corgi_ssp_dev);
-
-	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
-
-	return 0;
-}
-
-void corgi_ssp_lcdtg_send(u8 adrs, u8 data)
-{
-	corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f));
-}
-
-void corgi_ssp_blduty_set(int duty)
-{
-	corgi_ssp_lcdtg_send(0x02,duty);
-}
-
-EXPORT_SYMBOL(corgi_ssp_lcdtg_send);
-EXPORT_SYMBOL(corgi_ssp_blduty_set);
-
-/*
- *  Max1111 Routines
- */
-int corgi_ssp_max1111_get(ulong data)
-{
-	unsigned long flag;
-	long voltage = 0, voltage1 = 0, voltage2 = 0;
-
-	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	if (ssp_machinfo->cs_max1111 >= 0)
-		GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
-	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111));
-	ssp_enable(&corgi_ssp_dev);
-
-	udelay(1);
-
-	/* TB1/RB1 */
-	ssp_write_word(&corgi_ssp_dev,data);
-	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */
-
-	/* TB12/RB2 */
-	ssp_write_word(&corgi_ssp_dev,0);
-	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1);
-
-	/* TB13/RB3*/
-	ssp_write_word(&corgi_ssp_dev,0);
-	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2);
-
-	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
-	ssp_enable(&corgi_ssp_dev);
-	if (ssp_machinfo->cs_max1111 >= 0)
-		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
-	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
-
-	if (voltage1 & 0xc0 || voltage2 & 0x3f)
-		voltage = -1;
-	else
-		voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
-
-	return voltage;
-}
-
-EXPORT_SYMBOL(corgi_ssp_max1111_get);
-
-/*
- *  Support Routines
- */
-
-void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
-{
-	ssp_machinfo = machinfo;
-}
-
-static int __devinit corgi_ssp_probe(struct platform_device *dev)
-{
-	int ret;
-
-	/* Chip Select - Disable All */
-	if (ssp_machinfo->cs_lcdcon >= 0)
-		pxa_gpio_mode(ssp_machinfo->cs_lcdcon  | GPIO_OUT | GPIO_DFLT_HIGH);
-	if (ssp_machinfo->cs_max1111 >= 0)
-	        pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
-	if (ssp_machinfo->cs_ads7846 >= 0)
-        	pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
-
-	ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
-
-	if (ret)
-		printk(KERN_ERR "Unable to register SSP handler!\n");
-	else {
-		ssp_disable(&corgi_ssp_dev);
-		ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
-		ssp_enable(&corgi_ssp_dev);
-	}
-
-	return ret;
-}
-
-static int corgi_ssp_remove(struct platform_device *dev)
-{
-	ssp_exit(&corgi_ssp_dev);
-	return 0;
-}
-
-static int corgi_ssp_suspend(struct platform_device *dev, pm_message_t state)
-{
-	ssp_flush(&corgi_ssp_dev);
-	ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
-
-	return 0;
-}
-
-static int corgi_ssp_resume(struct platform_device *dev)
-{
-	if (ssp_machinfo->cs_lcdcon >= 0)
-		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
-	if (ssp_machinfo->cs_max1111 >= 0)
-		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
-	if (ssp_machinfo->cs_ads7846 >= 0)
-		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
-	ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
-	ssp_enable(&corgi_ssp_dev);
-
-	return 0;
-}
-
-static struct platform_driver corgissp_driver = {
-	.probe		= corgi_ssp_probe,
-	.remove		= corgi_ssp_remove,
-	.suspend	= corgi_ssp_suspend,
-	.resume		= corgi_ssp_resume,
-	.driver		= {
-		.name	= "corgi-ssp",
-	},
-};
-
-int __init corgi_ssp_init(void)
-{
-	return platform_driver_register(&corgissp_driver);
-}
-
-arch_initcall(corgi_ssp_init);
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
index 88575b8..91fd4fe 100644
--- a/arch/arm/mach-pxa/csb726.c
+++ b/arch/arm/mach-pxa/csb726.c
@@ -125,18 +125,9 @@
 	GPIO118_I2C_SDA,
 };
 
-static struct pxamci_platform_data csb726_mci_data;
-
-static int csb726_mci_init(struct device *dev,
-		irq_handler_t detect, void *data)
-{
-	csb726_mci_data.detect_delay = msecs_to_jiffies(500);
-	return 0;
-}
-
 static struct pxamci_platform_data csb726_mci = {
+	.detect_delay_ms	= 500,
 	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init			= csb726_mci_init,
 	/* FIXME setpower */
 	.gpio_card_detect	= CSB726_GPIO_MMC_DETECT,
 	.gpio_card_ro		= CSB726_GPIO_MMC_RO,
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index aab04f3..0517c17 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -626,6 +626,7 @@
 }
 
 static struct pxamci_platform_data em_x270_mci_platform_data = {
+	.detect_delay_ms	= 250,
 	.ocr_mask		= MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23|
 				  MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
 				  MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
@@ -643,7 +644,6 @@
 	if (machine_is_em_x270())
 		em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro;
 
-	em_x270_mci_platform_data.detect_delay	= msecs_to_jiffies(250);
 	pxa_set_mci_info(&em_x270_mci_platform_data);
 }
 #else
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 3126a35..baabb3c 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -28,7 +28,6 @@
 
 #include <mach/reset.h>
 #include <mach/gpio.h>
-#include <mach/pxa2xx-gpio.h>
 
 #include "generic.h"
 
@@ -128,33 +127,3 @@
 	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
 	get_clk_frequency_khz(1);
 }
-
-/*
- * Configure pins for GPIO or other functions
- */
-int pxa_gpio_mode(int gpio_mode)
-{
-	unsigned long flags;
-	int gpio = gpio_mode & GPIO_MD_MASK_NR;
-	int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
-	int gafr;
-
-	if (gpio > pxa_last_gpio)
-		return -EINVAL;
-
-	local_irq_save(flags);
-	if (gpio_mode & GPIO_DFLT_LOW)
-		GPCR(gpio) = GPIO_bit(gpio);
-	else if (gpio_mode & GPIO_DFLT_HIGH)
-		GPSR(gpio) = GPIO_bit(gpio);
-	if (gpio_mode & GPIO_MD_MASK_DIR)
-		GPDR(gpio) |= GPIO_bit(gpio);
-	else
-		GPDR(gpio) &= ~GPIO_bit(gpio);
-	gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
-	GAFR(gpio) = gafr |  (fn  << (((gpio) & 0xf)*2));
-	local_irq_restore(flags);
-
-	return 0;
-}
-EXPORT_SYMBOL(pxa_gpio_mode);
diff --git a/arch/arm/mach-pxa/include/mach/corgi.h b/arch/arm/mach-pxa/include/mach/corgi.h
index 7239281..585970e 100644
--- a/arch/arm/mach-pxa/include/mach/corgi.h
+++ b/arch/arm/mach-pxa/include/mach/corgi.h
@@ -113,7 +113,6 @@
  * Shared data structures
  */
 extern struct platform_device corgiscoop_device;
-extern struct platform_device corgissp_device;
 
 #endif /* __ASM_ARCH_CORGI_H  */
 
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
index 658b28e..c54cef2 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
@@ -25,6 +25,8 @@
 #define MFP_DIR(x)		(((x) >> 23) & 0x1)
 
 #define MFP_LPM_CAN_WAKEUP	(0x1 << 24)
+#define MFP_LPM_KEEP_OUTPUT	(0x1 << 25)
+
 #define WAKEUP_ON_EDGE_RISE	(MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE)
 #define WAKEUP_ON_EDGE_FALL	(MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_FALL)
 #define WAKEUP_ON_EDGE_BOTH	(MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_BOTH)
diff --git a/arch/arm/mach-pxa/include/mach/mmc.h b/arch/arm/mach-pxa/include/mach/mmc.h
index 02a69dc..9eb515b 100644
--- a/arch/arm/mach-pxa/include/mach/mmc.h
+++ b/arch/arm/mach-pxa/include/mach/mmc.h
@@ -9,7 +9,7 @@
 
 struct pxamci_platform_data {
 	unsigned int ocr_mask;			/* available voltages */
-	unsigned long detect_delay;		/* delay in jiffies before detecting cards after interrupt */
+	unsigned long detect_delay_ms;		/* delay in millisecond before detecting cards after interrupt */
 	int (*init)(struct device *, irq_handler_t , void *);
 	int (*get_ro)(struct device *);
 	void (*setpower)(struct device *, unsigned int);
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h b/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h
deleted file mode 100644
index 1209c44..0000000
--- a/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h
+++ /dev/null
@@ -1,375 +0,0 @@
-#ifndef __ASM_ARCH_PXA2XX_GPIO_H
-#define __ASM_ARCH_PXA2XX_GPIO_H
-
-#warning Please use mfp-pxa2[57]x.h instead of pxa2xx-gpio.h
-
-#include <mach/gpio.h>
-
-/* GPIO alternate function assignments */
-
-#define GPIO1_RST		1	/* reset */
-#define GPIO6_MMCCLK		6	/* MMC Clock */
-#define GPIO7_48MHz		7	/* 48 MHz clock output */
-#define GPIO8_MMCCS0		8	/* MMC Chip Select 0 */
-#define GPIO9_MMCCS1		9	/* MMC Chip Select 1 */
-#define GPIO10_RTCCLK		10	/* real time clock (1 Hz) */
-#define GPIO11_3_6MHz		11	/* 3.6 MHz oscillator out */
-#define GPIO12_32KHz		12	/* 32 kHz out */
-#define GPIO12_CIF_DD_7		12	/* Camera data pin 7 */
-#define GPIO13_MBGNT		13	/* memory controller grant */
-#define GPIO14_MBREQ		14	/* alternate bus master request */
-#define GPIO15_nCS_1		15	/* chip select 1 */
-#define GPIO16_PWM0		16	/* PWM0 output */
-#define GPIO17_PWM1		17	/* PWM1 output */
-#define GPIO17_CIF_DD_6		17	/* Camera data pin 6 */
-#define GPIO18_RDY		18	/* Ext. Bus Ready */
-#define GPIO19_DREQ1		19	/* External DMA Request */
-#define GPIO20_DREQ0		20	/* External DMA Request */
-#define GPIO23_SCLK		23	/* SSP clock */
-#define GPIO23_CIF_MCLK		23	/* Camera Master Clock */
-#define GPIO24_SFRM		24	/* SSP Frame */
-#define GPIO24_CIF_FV		24	/* Camera frame start signal */
-#define GPIO25_STXD		25	/* SSP transmit */
-#define GPIO25_CIF_LV		25	/* Camera line start signal */
-#define GPIO26_SRXD		26	/* SSP receive */
-#define GPIO26_CIF_PCLK		26	/* Camera Pixel Clock */
-#define GPIO27_SEXTCLK		27	/* SSP ext_clk */
-#define GPIO27_CIF_DD_0		27	/* Camera data pin 0 */
-#define GPIO28_BITCLK		28	/* AC97/I2S bit_clk */
-#define GPIO29_SDATA_IN		29	/* AC97 Sdata_in0 / I2S Sdata_in */
-#define GPIO30_SDATA_OUT	30	/* AC97/I2S Sdata_out */
-#define GPIO31_SYNC		31	/* AC97/I2S sync */
-#define GPIO32_SDATA_IN1	32	/* AC97 Sdata_in1 */
-#define GPIO32_SYSCLK		32	/* I2S System Clock */
-#define GPIO32_MMCCLK		32	/* MMC Clock (PXA270) */
-#define GPIO33_nCS_5		33	/* chip select 5 */
-#define GPIO34_FFRXD		34	/* FFUART receive */
-#define GPIO34_MMCCS0		34	/* MMC Chip Select 0 */
-#define GPIO35_FFCTS		35	/* FFUART Clear to send */
-#define GPIO36_FFDCD		36	/* FFUART Data carrier detect */
-#define GPIO37_FFDSR		37	/* FFUART data set ready */
-#define GPIO38_FFRI		38	/* FFUART Ring Indicator */
-#define GPIO39_MMCCS1		39	/* MMC Chip Select 1 */
-#define GPIO39_FFTXD		39	/* FFUART transmit data */
-#define GPIO40_FFDTR		40	/* FFUART data terminal Ready */
-#define GPIO41_FFRTS		41	/* FFUART request to send */
-#define GPIO42_BTRXD		42	/* BTUART receive data */
-#define GPIO42_HWRXD		42	/* HWUART receive data */
-#define GPIO42_CIF_MCLK		42	/* Camera Master Clock */
-#define GPIO43_BTTXD		43	/* BTUART transmit data */
-#define GPIO43_HWTXD		43	/* HWUART transmit data */
-#define GPIO43_CIF_FV		43	/* Camera frame start signal */
-#define GPIO44_BTCTS		44	/* BTUART clear to send */
-#define GPIO44_HWCTS		44	/* HWUART clear to send */
-#define GPIO44_CIF_LV		44	/* Camera line start signal */
-#define GPIO45_BTRTS		45	/* BTUART request to send */
-#define GPIO45_HWRTS		45	/* HWUART request to send */
-#define GPIO45_AC97_SYSCLK	45	/* AC97 System Clock */
-#define GPIO45_CIF_PCLK		45	/* Camera Pixel Clock */
-#define GPIO46_ICPRXD		46	/* ICP receive data */
-#define GPIO46_STRXD		46	/* STD_UART receive data */
-#define GPIO47_ICPTXD		47	/* ICP transmit data */
-#define GPIO47_STTXD		47	/* STD_UART transmit data */
-#define GPIO47_CIF_DD_0		47	/* Camera data pin 0 */
-#define GPIO48_nPOE		48	/* Output Enable for Card Space */
-#define GPIO48_CIF_DD_5		48	/* Camera data pin 5 */
-#define GPIO49_nPWE		49	/* Write Enable for Card Space */
-#define GPIO50_nPIOR		50	/* I/O Read for Card Space */
-#define GPIO50_CIF_DD_3		50	/* Camera data pin 3 */
-#define GPIO51_nPIOW		51	/* I/O Write for Card Space */
-#define GPIO51_CIF_DD_2		51	/* Camera data pin 2 */
-#define GPIO52_nPCE_1		52	/* Card Enable for Card Space */
-#define GPIO52_CIF_DD_4		52	/* Camera data pin 4 */
-#define GPIO53_nPCE_2		53	/* Card Enable for Card Space */
-#define GPIO53_MMCCLK		53	/* MMC Clock */
-#define GPIO53_CIF_MCLK		53	/* Camera Master Clock */
-#define GPIO54_MMCCLK		54	/* MMC Clock */
-#define GPIO54_pSKTSEL		54	/* Socket Select for Card Space */
-#define GPIO54_nPCE_2		54	/* Card Enable for Card Space (PXA27x) */
-#define GPIO54_CIF_PCLK		54	/* Camera Pixel Clock */
-#define GPIO55_nPREG		55	/* Card Address bit 26 */
-#define GPIO55_CIF_DD_1		55	/* Camera data pin 1 */
-#define GPIO56_nPWAIT		56	/* Wait signal for Card Space */
-#define GPIO57_nIOIS16		57	/* Bus Width select for I/O Card Space */
-#define GPIO58_LDD_0		58	/* LCD data pin 0 */
-#define GPIO59_LDD_1		59	/* LCD data pin 1 */
-#define GPIO60_LDD_2		60	/* LCD data pin 2 */
-#define GPIO61_LDD_3		61	/* LCD data pin 3 */
-#define GPIO62_LDD_4		62	/* LCD data pin 4 */
-#define GPIO63_LDD_5		63	/* LCD data pin 5 */
-#define GPIO64_LDD_6		64	/* LCD data pin 6 */
-#define GPIO65_LDD_7		65	/* LCD data pin 7 */
-#define GPIO66_LDD_8		66	/* LCD data pin 8 */
-#define GPIO66_MBREQ		66	/* alternate bus master req */
-#define GPIO67_LDD_9		67	/* LCD data pin 9 */
-#define GPIO67_MMCCS0		67	/* MMC Chip Select 0 */
-#define GPIO68_LDD_10		68	/* LCD data pin 10 */
-#define GPIO68_MMCCS1		68	/* MMC Chip Select 1 */
-#define GPIO69_LDD_11		69	/* LCD data pin 11 */
-#define GPIO69_MMCCLK		69	/* MMC_CLK */
-#define GPIO70_LDD_12		70	/* LCD data pin 12 */
-#define GPIO70_RTCCLK		70	/* Real Time clock (1 Hz) */
-#define GPIO71_LDD_13		71	/* LCD data pin 13 */
-#define GPIO71_3_6MHz		71	/* 3.6 MHz Oscillator clock */
-#define GPIO72_LDD_14		72	/* LCD data pin 14 */
-#define GPIO72_32kHz		72	/* 32 kHz clock */
-#define GPIO73_LDD_15		73	/* LCD data pin 15 */
-#define GPIO73_MBGNT		73	/* Memory controller grant */
-#define GPIO74_LCD_FCLK		74	/* LCD Frame clock */
-#define GPIO75_LCD_LCLK		75	/* LCD line clock */
-#define GPIO76_LCD_PCLK		76	/* LCD Pixel clock */
-#define GPIO77_LCD_ACBIAS	77	/* LCD AC Bias */
-#define GPIO78_nCS_2		78	/* chip select 2 */
-#define GPIO79_nCS_3		79	/* chip select 3 */
-#define GPIO80_nCS_4		80	/* chip select 4 */
-#define GPIO81_NSCLK		81	/* NSSP clock */
-#define GPIO81_CIF_DD_0		81	/* Camera data pin 0 */
-#define GPIO82_NSFRM		82	/* NSSP Frame */
-#define GPIO82_CIF_DD_5		82	/* Camera data pin 5 */
-#define GPIO83_NSTXD		83	/* NSSP transmit */
-#define GPIO83_CIF_DD_4		83	/* Camera data pin 4 */
-#define GPIO84_NSRXD		84	/* NSSP receive */
-#define GPIO84_CIF_FV		84	/* Camera frame start signal */
-#define GPIO85_nPCE_1		85	/* Card Enable for Card Space (PXA27x) */
-#define GPIO85_CIF_LV		85	/* Camera line start signal */
-#define GPIO90_CIF_DD_4		90	/* Camera data pin 4 */
-#define GPIO91_CIF_DD_5		91	/* Camera data pin 5 */
-#define GPIO92_MMCDAT0		92	/* MMC DAT0 (PXA27x) */
-#define GPIO93_CIF_DD_6		93	/* Camera data pin 6 */
-#define GPIO94_CIF_DD_5		94	/* Camera data pin 5 */
-#define GPIO95_CIF_DD_4		95	/* Camera data pin 4 */
-#define GPIO96_FFRXD		96	/* FFUART recieve */
-#define GPIO98_FFRTS		98	/* FFUART request to send */
-#define GPIO98_CIF_DD_0		98	/* Camera data pin 0 */
-#define GPIO99_FFTXD		99	/* FFUART transmit data */
-#define GPIO100_FFCTS		100	/* FFUART Clear to send */
-#define GPIO102_nPCE_1		102	/* PCMCIA (PXA27x) */
-#define GPIO103_CIF_DD_3	103	/* Camera data pin 3 */
-#define GPIO104_CIF_DD_2	104	/* Camera data pin 2 */
-#define GPIO105_CIF_DD_1	105	/* Camera data pin 1 */
-#define GPIO106_CIF_DD_9	106	/* Camera data pin 9 */
-#define GPIO107_CIF_DD_8	107	/* Camera data pin 8 */
-#define GPIO108_CIF_DD_7	108	/* Camera data pin 7 */
-#define GPIO109_MMCDAT1		109	/* MMC DAT1 (PXA27x) */
-#define GPIO110_MMCDAT2		110	/* MMC DAT2 (PXA27x) */
-#define GPIO110_MMCCS0		110	/* MMC Chip Select 0 (PXA27x) */
-#define GPIO111_MMCDAT3		111	/* MMC DAT3 (PXA27x) */
-#define GPIO111_MMCCS1		111	/* MMC Chip Select 1 (PXA27x) */
-#define GPIO112_MMCCMD		112	/* MMC CMD (PXA27x) */
-#define GPIO113_I2S_SYSCLK	113	/* I2S System Clock (PXA27x) */
-#define GPIO113_AC97_RESET_N	113	/* AC97 NRESET on (PXA27x) */
-#define GPIO114_CIF_DD_1	114	/* Camera data pin 1 */
-#define GPIO115_CIF_DD_3	115	/* Camera data pin 3 */
-#define GPIO116_CIF_DD_2	116	/* Camera data pin 2 */
-
-/* GPIO alternate function mode & direction */
-
-#define GPIO_IN			0x000
-#define GPIO_OUT		0x080
-#define GPIO_ALT_FN_1_IN	0x100
-#define GPIO_ALT_FN_1_OUT	0x180
-#define GPIO_ALT_FN_2_IN	0x200
-#define GPIO_ALT_FN_2_OUT	0x280
-#define GPIO_ALT_FN_3_IN	0x300
-#define GPIO_ALT_FN_3_OUT	0x380
-#define GPIO_MD_MASK_NR		0x07f
-#define GPIO_MD_MASK_DIR	0x080
-#define GPIO_MD_MASK_FN		0x300
-#define GPIO_DFLT_LOW		0x400
-#define GPIO_DFLT_HIGH		0x800
-
-#define GPIO1_RTS_MD		( 1 | GPIO_ALT_FN_1_IN)
-#define GPIO6_MMCCLK_MD		( 6 | GPIO_ALT_FN_1_OUT)
-#define GPIO7_48MHz_MD		( 7 | GPIO_ALT_FN_1_OUT)
-#define GPIO8_MMCCS0_MD		( 8 | GPIO_ALT_FN_1_OUT)
-#define GPIO9_MMCCS1_MD		( 9 | GPIO_ALT_FN_1_OUT)
-#define GPIO10_RTCCLK_MD	(10 | GPIO_ALT_FN_1_OUT)
-#define GPIO11_3_6MHz_MD	(11 | GPIO_ALT_FN_1_OUT)
-#define GPIO12_32KHz_MD		(12 | GPIO_ALT_FN_1_OUT)
-#define GPIO12_CIF_DD_7_MD	(12 | GPIO_ALT_FN_2_IN)
-#define GPIO13_MBGNT_MD		(13 | GPIO_ALT_FN_2_OUT)
-#define GPIO14_MBREQ_MD		(14 | GPIO_ALT_FN_1_IN)
-#define GPIO15_nCS_1_MD		(15 | GPIO_ALT_FN_2_OUT)
-#define GPIO16_PWM0_MD		(16 | GPIO_ALT_FN_2_OUT)
-#define GPIO17_PWM1_MD		(17 | GPIO_ALT_FN_2_OUT)
-#define GPIO17_CIF_DD_6_MD	(17 | GPIO_ALT_FN_2_IN)
-#define GPIO18_RDY_MD		(18 | GPIO_ALT_FN_1_IN)
-#define GPIO19_DREQ1_MD		(19 | GPIO_ALT_FN_1_IN)
-#define GPIO20_DREQ0_MD		(20 | GPIO_ALT_FN_1_IN)
-#define GPIO23_CIF_MCLK_MD	(23 | GPIO_ALT_FN_1_OUT)
-#define GPIO23_SCLK_MD		(23 | GPIO_ALT_FN_2_OUT)
-#define GPIO24_CIF_FV_MD	(24 | GPIO_ALT_FN_1_OUT)
-#define GPIO24_SFRM_MD		(24 | GPIO_ALT_FN_2_OUT)
-#define GPIO25_CIF_LV_MD	(25 | GPIO_ALT_FN_1_OUT)
-#define GPIO25_STXD_MD		(25 | GPIO_ALT_FN_2_OUT)
-#define GPIO26_SRXD_MD		(26 | GPIO_ALT_FN_1_IN)
-#define GPIO26_CIF_PCLK_MD	(26 | GPIO_ALT_FN_2_IN)
-#define GPIO27_SEXTCLK_MD	(27 | GPIO_ALT_FN_1_IN)
-#define GPIO27_CIF_DD_0_MD	(27 | GPIO_ALT_FN_3_IN)
-#define GPIO28_BITCLK_AC97_MD	(28 | GPIO_ALT_FN_1_IN)
-#define GPIO28_BITCLK_IN_I2S_MD	(28 | GPIO_ALT_FN_2_IN)
-#define GPIO28_BITCLK_OUT_I2S_MD	(28 | GPIO_ALT_FN_1_OUT)
-#define GPIO29_SDATA_IN_AC97_MD	(29 | GPIO_ALT_FN_1_IN)
-#define GPIO29_SDATA_IN_I2S_MD	(29 | GPIO_ALT_FN_2_IN)
-#define GPIO30_SDATA_OUT_AC97_MD	(30 | GPIO_ALT_FN_2_OUT)
-#define GPIO30_SDATA_OUT_I2S_MD	(30 | GPIO_ALT_FN_1_OUT)
-#define GPIO31_SYNC_I2S_MD	(31 | GPIO_ALT_FN_1_OUT)
-#define GPIO31_SYNC_AC97_MD	(31 | GPIO_ALT_FN_2_OUT)
-#define GPIO32_SDATA_IN1_AC97_MD	(32 | GPIO_ALT_FN_1_IN)
-#define GPIO32_SYSCLK_I2S_MD	(32 | GPIO_ALT_FN_1_OUT)
-#define GPIO32_MMCCLK_MD	(32 | GPIO_ALT_FN_2_OUT)
-#define GPIO33_nCS_5_MD		(33 | GPIO_ALT_FN_2_OUT)
-#define GPIO34_FFRXD_MD		(34 | GPIO_ALT_FN_1_IN)
-#define GPIO34_MMCCS0_MD	(34 | GPIO_ALT_FN_2_OUT)
-#define GPIO35_FFCTS_MD		(35 | GPIO_ALT_FN_1_IN)
-#define GPIO35_KP_MKOUT6_MD	(35 | GPIO_ALT_FN_2_OUT)
-#define GPIO36_FFDCD_MD		(36 | GPIO_ALT_FN_1_IN)
-#define GPIO37_FFDSR_MD		(37 | GPIO_ALT_FN_1_IN)
-#define GPIO38_FFRI_MD		(38 | GPIO_ALT_FN_1_IN)
-#define GPIO39_MMCCS1_MD	(39 | GPIO_ALT_FN_1_OUT)
-#define GPIO39_FFTXD_MD		(39 | GPIO_ALT_FN_2_OUT)
-#define GPIO40_FFDTR_MD		(40 | GPIO_ALT_FN_2_OUT)
-#define GPIO41_FFRTS_MD		(41 | GPIO_ALT_FN_2_OUT)
-#define GPIO41_KP_MKOUT7_MD	(41 | GPIO_ALT_FN_1_OUT)
-#define GPIO42_BTRXD_MD		(42 | GPIO_ALT_FN_1_IN)
-#define GPIO42_HWRXD_MD		(42 | GPIO_ALT_FN_3_IN)
-#define GPIO42_CIF_MCLK_MD	(42 | GPIO_ALT_FN_3_OUT)
-#define GPIO43_BTTXD_MD		(43 | GPIO_ALT_FN_2_OUT)
-#define GPIO43_HWTXD_MD		(43 | GPIO_ALT_FN_3_OUT)
-#define GPIO43_CIF_FV_MD	(43 | GPIO_ALT_FN_3_OUT)
-#define GPIO44_BTCTS_MD		(44 | GPIO_ALT_FN_1_IN)
-#define GPIO44_HWCTS_MD		(44 | GPIO_ALT_FN_3_IN)
-#define GPIO44_CIF_LV_MD	(44 | GPIO_ALT_FN_3_OUT)
-#define GPIO45_CIF_PCLK_MD	(45 | GPIO_ALT_FN_3_IN)
-#define GPIO45_BTRTS_MD		(45 | GPIO_ALT_FN_2_OUT)
-#define GPIO45_HWRTS_MD		(45 | GPIO_ALT_FN_3_OUT)
-#define GPIO45_SYSCLK_AC97_MD	(45 | GPIO_ALT_FN_1_OUT)
-#define GPIO46_ICPRXD_MD	(46 | GPIO_ALT_FN_1_IN)
-#define GPIO46_STRXD_MD		(46 | GPIO_ALT_FN_2_IN)
-#define GPIO47_CIF_DD_0_MD	(47 | GPIO_ALT_FN_1_IN)
-#define GPIO47_ICPTXD_MD	(47 | GPIO_ALT_FN_2_OUT)
-#define GPIO47_STTXD_MD		(47 | GPIO_ALT_FN_1_OUT)
-#define GPIO48_CIF_DD_5_MD	(48 | GPIO_ALT_FN_1_IN)
-#define GPIO48_nPOE_MD		(48 | GPIO_ALT_FN_2_OUT)
-#define GPIO48_HWTXD_MD		(48 | GPIO_ALT_FN_1_OUT)
-#define GPIO48_nPOE_MD		(48 | GPIO_ALT_FN_2_OUT)
-#define GPIO49_HWRXD_MD		(49 | GPIO_ALT_FN_1_IN)
-#define GPIO49_nPWE_MD		(49 | GPIO_ALT_FN_2_OUT)
-#define GPIO50_CIF_DD_3_MD	(50 | GPIO_ALT_FN_1_IN)
-#define GPIO50_nPIOR_MD		(50 | GPIO_ALT_FN_2_OUT)
-#define GPIO50_HWCTS_MD		(50 | GPIO_ALT_FN_1_IN)
-#define GPIO50_CIF_DD_3_MD	(50 | GPIO_ALT_FN_1_IN)
-#define GPIO51_CIF_DD_2_MD	(51 | GPIO_ALT_FN_1_IN)
-#define GPIO51_nPIOW_MD		(51 | GPIO_ALT_FN_2_OUT)
-#define GPIO51_HWRTS_MD		(51 | GPIO_ALT_FN_1_OUT)
-#define GPIO51_CIF_DD_2_MD	(51 | GPIO_ALT_FN_1_IN)
-#define GPIO52_nPCE_1_MD	(52 | GPIO_ALT_FN_2_OUT)
-#define GPIO52_CIF_DD_4_MD	(52 | GPIO_ALT_FN_1_IN)
-#define GPIO53_nPCE_2_MD	(53 | GPIO_ALT_FN_2_OUT)
-#define GPIO53_MMCCLK_MD	(53 | GPIO_ALT_FN_1_OUT)
-#define GPIO53_CIF_MCLK_MD	(53 | GPIO_ALT_FN_2_OUT)
-#define GPIO54_MMCCLK_MD	(54 | GPIO_ALT_FN_1_OUT)
-#define GPIO54_nPCE_2_MD	(54 | GPIO_ALT_FN_2_OUT)
-#define GPIO54_pSKTSEL_MD	(54 | GPIO_ALT_FN_2_OUT)
-#define GPIO54_CIF_PCLK_MD	(54 | GPIO_ALT_FN_3_IN)
-#define GPIO55_nPREG_MD		(55 | GPIO_ALT_FN_2_OUT)
-#define GPIO55_CIF_DD_1_MD	(55 | GPIO_ALT_FN_1_IN)
-#define GPIO56_nPWAIT_MD	(56 | GPIO_ALT_FN_1_IN)
-#define GPIO57_nIOIS16_MD	(57 | GPIO_ALT_FN_1_IN)
-#define GPIO58_LDD_0_MD		(58 | GPIO_ALT_FN_2_OUT)
-#define GPIO59_LDD_1_MD		(59 | GPIO_ALT_FN_2_OUT)
-#define GPIO60_LDD_2_MD		(60 | GPIO_ALT_FN_2_OUT)
-#define GPIO61_LDD_3_MD		(61 | GPIO_ALT_FN_2_OUT)
-#define GPIO62_LDD_4_MD		(62 | GPIO_ALT_FN_2_OUT)
-#define GPIO63_LDD_5_MD		(63 | GPIO_ALT_FN_2_OUT)
-#define GPIO64_LDD_6_MD		(64 | GPIO_ALT_FN_2_OUT)
-#define GPIO65_LDD_7_MD		(65 | GPIO_ALT_FN_2_OUT)
-#define GPIO66_LDD_8_MD		(66 | GPIO_ALT_FN_2_OUT)
-#define GPIO66_MBREQ_MD		(66 | GPIO_ALT_FN_1_IN)
-#define GPIO67_LDD_9_MD		(67 | GPIO_ALT_FN_2_OUT)
-#define GPIO67_MMCCS0_MD	(67 | GPIO_ALT_FN_1_OUT)
-#define GPIO68_LDD_10_MD	(68 | GPIO_ALT_FN_2_OUT)
-#define GPIO68_MMCCS1_MD	(68 | GPIO_ALT_FN_1_OUT)
-#define GPIO69_LDD_11_MD	(69 | GPIO_ALT_FN_2_OUT)
-#define GPIO69_MMCCLK_MD	(69 | GPIO_ALT_FN_1_OUT)
-#define GPIO70_LDD_12_MD	(70 | GPIO_ALT_FN_2_OUT)
-#define GPIO70_RTCCLK_MD	(70 | GPIO_ALT_FN_1_OUT)
-#define GPIO71_LDD_13_MD	(71 | GPIO_ALT_FN_2_OUT)
-#define GPIO71_3_6MHz_MD	(71 | GPIO_ALT_FN_1_OUT)
-#define GPIO72_LDD_14_MD	(72 | GPIO_ALT_FN_2_OUT)
-#define GPIO72_32kHz_MD		(72 | GPIO_ALT_FN_1_OUT)
-#define GPIO73_LDD_15_MD	(73 | GPIO_ALT_FN_2_OUT)
-#define GPIO73_MBGNT_MD		(73 | GPIO_ALT_FN_1_OUT)
-#define GPIO74_LCD_FCLK_MD	(74 | GPIO_ALT_FN_2_OUT)
-#define GPIO75_LCD_LCLK_MD	(75 | GPIO_ALT_FN_2_OUT)
-#define GPIO76_LCD_PCLK_MD	(76 | GPIO_ALT_FN_2_OUT)
-#define GPIO77_LCD_ACBIAS_MD	(77 | GPIO_ALT_FN_2_OUT)
-#define GPIO78_nCS_2_MD		(78 | GPIO_ALT_FN_2_OUT)
-#define GPIO78_nPCE_2_MD	(78 | GPIO_ALT_FN_1_OUT)
-#define GPIO79_nCS_3_MD		(79 | GPIO_ALT_FN_2_OUT)
-#define GPIO79_pSKTSEL_MD	(79 | GPIO_ALT_FN_1_OUT)
-#define GPIO80_nCS_4_MD		(80 | GPIO_ALT_FN_2_OUT)
-#define GPIO81_NSSP_CLK_OUT	(81 | GPIO_ALT_FN_1_OUT)
-#define GPIO81_NSSP_CLK_IN	(81 | GPIO_ALT_FN_1_IN)
-#define GPIO81_CIF_DD_0_MD	(81 | GPIO_ALT_FN_2_IN)
-#define GPIO82_NSSP_FRM_OUT	(82 | GPIO_ALT_FN_1_OUT)
-#define GPIO82_NSSP_FRM_IN	(82 | GPIO_ALT_FN_1_IN)
-#define GPIO82_CIF_DD_5_MD	(82 | GPIO_ALT_FN_3_IN)
-#define GPIO83_NSSP_TX		(83 | GPIO_ALT_FN_1_OUT)
-#define GPIO83_NSSP_RX		(83 | GPIO_ALT_FN_2_IN)
-#define GPIO83_CIF_DD_4_MD	(83 | GPIO_ALT_FN_3_IN)
-#define GPIO84_NSSP_TX		(84 | GPIO_ALT_FN_1_OUT)
-#define GPIO84_NSSP_RX		(84 | GPIO_ALT_FN_2_IN)
-#define GPIO84_CIF_FV_MD	(84 | GPIO_ALT_FN_3_IN)
-#define GPIO85_nPCE_1_MD	(85 | GPIO_ALT_FN_1_OUT)
-#define GPIO85_CIF_LV_MD	(85 | GPIO_ALT_FN_3_IN)
-#define GPIO86_nPCE_1_MD	(86 | GPIO_ALT_FN_1_OUT)
-#define GPIO88_USBH1_PWR_MD	(88 | GPIO_ALT_FN_1_IN)
-#define GPIO89_USBH1_PEN_MD	(89 | GPIO_ALT_FN_2_OUT)
-#define GPIO90_CIF_DD_4_MD	(90 | GPIO_ALT_FN_3_IN)
-#define GPIO91_CIF_DD_5_MD	(91 | GPIO_ALT_FN_3_IN)
-#define GPIO92_MMCDAT0_MD	(92 | GPIO_ALT_FN_1_OUT)
-#define GPIO93_CIF_DD_6_MD	(93 | GPIO_ALT_FN_2_IN)
-#define GPIO94_CIF_DD_5_MD	(94 | GPIO_ALT_FN_2_IN)
-#define GPIO95_CIF_DD_4_MD	(95 | GPIO_ALT_FN_2_IN)
-#define GPIO95_KP_MKIN6_MD	(95 | GPIO_ALT_FN_3_IN)
-#define GPIO96_KP_DKIN3_MD	(96 | GPIO_ALT_FN_1_IN)
-#define GPIO96_FFRXD_MD		(96 | GPIO_ALT_FN_3_IN)
-#define GPIO97_KP_MKIN3_MD	(97 | GPIO_ALT_FN_3_IN)
-#define GPIO98_CIF_DD_0_MD	(98 | GPIO_ALT_FN_2_IN)
-#define GPIO98_FFRTS_MD		(98 | GPIO_ALT_FN_3_OUT)
-#define GPIO99_FFTXD_MD		(99 | GPIO_ALT_FN_3_OUT)
-#define GPIO100_KP_MKIN0_MD	(100 | GPIO_ALT_FN_1_IN)
-#define GPIO101_KP_MKIN1_MD	(101 | GPIO_ALT_FN_1_IN)
-#define GPIO102_nPCE_1_MD	(102 | GPIO_ALT_FN_1_OUT)
-#define GPIO102_KP_MKIN2_MD	(102 | GPIO_ALT_FN_1_IN)
-#define GPIO103_CIF_DD_3_MD	(103 | GPIO_ALT_FN_1_IN)
-#define GPIO103_KP_MKOUT0_MD	(103 | GPIO_ALT_FN_2_OUT)
-#define GPIO104_CIF_DD_2_MD	(104 | GPIO_ALT_FN_1_IN)
-#define GPIO104_pSKTSEL_MD	(104 | GPIO_ALT_FN_1_OUT)
-#define GPIO104_KP_MKOUT1_MD	(104 | GPIO_ALT_FN_2_OUT)
-#define GPIO105_CIF_DD_1_MD	(105 | GPIO_ALT_FN_1_IN)
-#define GPIO105_KP_MKOUT2_MD	(105 | GPIO_ALT_FN_2_OUT)
-#define GPIO106_CIF_DD_9_MD	(106 | GPIO_ALT_FN_1_IN)
-#define GPIO106_KP_MKOUT3_MD	(106 | GPIO_ALT_FN_2_OUT)
-#define GPIO107_CIF_DD_8_MD	(107 | GPIO_ALT_FN_1_IN)
-#define GPIO107_KP_MKOUT4_MD	(107 | GPIO_ALT_FN_2_OUT)
-#define GPIO108_CIF_DD_7_MD	(108 | GPIO_ALT_FN_1_IN)
-#define GPIO108_KP_MKOUT5_MD	(108 | GPIO_ALT_FN_2_OUT)
-#define GPIO109_MMCDAT1_MD	(109 | GPIO_ALT_FN_1_OUT)
-#define GPIO110_MMCDAT2_MD	(110 | GPIO_ALT_FN_1_OUT)
-#define GPIO110_MMCCS0_MD	(110 | GPIO_ALT_FN_1_OUT)
-#define GPIO111_MMCDAT3_MD	(111 | GPIO_ALT_FN_1_OUT)
-#define GPIO110_MMCCS1_MD	(111 | GPIO_ALT_FN_1_OUT)
-#define GPIO112_MMCCMD_MD	(112 | GPIO_ALT_FN_1_OUT)
-#define GPIO113_I2S_SYSCLK_MD	(113 | GPIO_ALT_FN_1_OUT)
-#define GPIO113_AC97_RESET_N_MD	(113 | GPIO_ALT_FN_2_OUT)
-#define GPIO117_I2CSCL_MD	(117 | GPIO_ALT_FN_1_IN)
-#define GPIO118_I2CSDA_MD	(118 | GPIO_ALT_FN_1_IN)
-
-/*
- * Handy routine to set GPIO alternate functions
- */
-extern int pxa_gpio_mode( int gpio_mode );
-
-#endif /* __ASM_ARCH_PXA2XX_GPIO_H */
diff --git a/arch/arm/mach-pxa/include/mach/ssp.h b/arch/arm/mach-pxa/include/mach/ssp.h
deleted file mode 100644
index be1be5b..0000000
--- a/arch/arm/mach-pxa/include/mach/ssp.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *  ssp.h
- *
- *  Copyright (C) 2003 Russell King, 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.
- *
- * This driver supports the following PXA CPU/SSP ports:-
- *
- *       PXA250     SSP
- *       PXA255     SSP, NSSP
- *       PXA26x     SSP, NSSP, ASSP
- *       PXA27x     SSP1, SSP2, SSP3
- *       PXA3xx     SSP1, SSP2, SSP3, SSP4
- */
-
-#ifndef __ASM_ARCH_SSP_H
-#define __ASM_ARCH_SSP_H
-
-#include <linux/list.h>
-#include <linux/io.h>
-
-enum pxa_ssp_type {
-	SSP_UNDEFINED = 0,
-	PXA25x_SSP,  /* pxa 210, 250, 255, 26x */
-	PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
-	PXA27x_SSP,
-};
-
-struct ssp_device {
-	struct platform_device *pdev;
-	struct list_head	node;
-
-	struct clk	*clk;
-	void __iomem	*mmio_base;
-	unsigned long	phys_base;
-
-	const char	*label;
-	int		port_id;
-	int		type;
-	int		use_count;
-	int		irq;
-	int		drcmr_rx;
-	int		drcmr_tx;
-};
-
-#ifdef CONFIG_PXA_SSP_LEGACY
-/*
- * SSP initialisation flags
- */
-#define SSP_NO_IRQ	0x1		/* don't register an irq handler in SSP driver */
-
-struct ssp_state {
-	u32	cr0;
-	u32 cr1;
-	u32 to;
-	u32 psp;
-};
-
-struct ssp_dev {
-	struct ssp_device *ssp;
-	u32 port;
-	u32 mode;
-	u32 flags;
-	u32 psp_flags;
-	u32 speed;
-	int irq;
-};
-
-int ssp_write_word(struct ssp_dev *dev, u32 data);
-int ssp_read_word(struct ssp_dev *dev, u32 *data);
-int ssp_flush(struct ssp_dev *dev);
-void ssp_enable(struct ssp_dev *dev);
-void ssp_disable(struct ssp_dev *dev);
-void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp);
-void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp);
-int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags);
-int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
-void ssp_exit(struct ssp_dev *dev);
-#endif /* CONFIG_PXA_SSP_LEGACY */
-
-/**
- * ssp_write_reg - Write to a SSP register
- *
- * @dev: SSP device to access
- * @reg: Register to write to
- * @val: Value to be written.
- */
-static inline void ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val)
-{
-	__raw_writel(val, dev->mmio_base + reg);
-}
-
-/**
- * ssp_read_reg - Read from a SSP register
- *
- * @dev: SSP device to access
- * @reg: Register to read from
- */
-static inline u32 ssp_read_reg(struct ssp_device *dev, u32 reg)
-{
-	return __raw_readl(dev->mmio_base + reg);
-}
-
-struct ssp_device *ssp_request(int port, const char *label);
-void ssp_free(struct ssp_device *);
-#endif /* __ASM_ARCH_SSP_H */
diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h
index 4df2d38..1bbd1f2 100644
--- a/arch/arm/mach-pxa/include/mach/tosa.h
+++ b/arch/arm/mach-pxa/include/mach/tosa.h
@@ -167,7 +167,7 @@
 
 #define TOSA_KEY_SYNC		KEY_102ND /* ??? */
 
-#ifndef CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES
+#ifndef CONFIG_TOSA_USE_EXT_KEYCODES
 #define TOSA_KEY_RECORD		KEY_YEN
 #define TOSA_KEY_ADDRESSBOOK	KEY_KATAKANA
 #define TOSA_KEY_CANCEL		KEY_ESC
diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h
new file mode 100644
index 0000000..7bfa3dd
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/vpac270.h
@@ -0,0 +1,42 @@
+/*
+ * GPIOs and interrupts for Voipac PXA270
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.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.
+ *
+ */
+
+#ifndef _INCLUDE_VPAC270_H_
+#define _INCLUDE_VPAC270_H_
+
+#define	GPIO1_VPAC270_USER_BTN		1
+
+#define	GPIO15_VPAC270_LED_ORANGE	15
+
+#define	GPIO81_VPAC270_BKL_ON		81
+#define	GPIO83_VPAC270_NL_ON		83
+
+#define	GPIO52_VPAC270_SD_READONLY	52
+#define	GPIO53_VPAC270_SD_DETECT_N	53
+
+#define	GPIO84_VPAC270_PCMCIA_CD	84
+#define	GPIO35_VPAC270_PCMCIA_RDY	35
+#define	GPIO107_VPAC270_PCMCIA_PPEN	107
+#define	GPIO11_VPAC270_PCMCIA_RESET	11
+#define	GPIO17_VPAC270_CF_CD		17
+#define	GPIO12_VPAC270_CF_RDY		12
+#define	GPIO16_VPAC270_CF_RESET		16
+
+#define	GPIO41_VPAC270_UDC_DETECT	41
+
+#define	GPIO114_VPAC270_ETH_IRQ		114
+
+#define	GPIO36_VPAC270_IDE_IRQ		36
+
+#define	GPIO113_VPAC270_TS_IRQ		113
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/z2.h b/arch/arm/mach-pxa/include/mach/z2.h
new file mode 100644
index 0000000..8835c16
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/z2.h
@@ -0,0 +1,41 @@
+/*
+ *  arch/arm/mach-pxa/include/mach/z2.h
+ *
+ *  Author: Ken McGuire
+ *  Created: Feb 6, 2009
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ASM_ARCH_ZIPIT2_H
+#define ASM_ARCH_ZIPIT2_H
+
+/* LEDs */
+#define	GPIO10_ZIPITZ2_LED_WIFI		10
+#define	GPIO85_ZIPITZ2_LED_CHARGED	85
+#define	GPIO83_ZIPITZ2_LED_CHARGING	83
+
+/* SD/MMC */
+#define	GPIO96_ZIPITZ2_SD_DETECT	96
+
+/* GPIO Buttons */
+#define	GPIO1_ZIPITZ2_POWER_BUTTON	1
+#define	GPIO98_ZIPITZ2_LID_BUTTON	98
+
+/* Libertas GSPI8686 WiFi */
+#define	GPIO14_ZIPITZ2_WIFI_RESET	14
+#define	GPIO15_ZIPITZ2_WIFI_POWER	15
+#define	GPIO24_ZIPITZ2_WIFI_CS		24
+#define	GPIO36_ZIPITZ2_WIFI_IRQ		36
+
+/* LCD */
+#define	GPIO19_ZIPITZ2_LCD_RESET	19
+#define	GPIO88_ZIPITZ2_LCD_CS		88
+
+/* MISC GPIOs */
+#define	GPIO0_ZIPITZ2_AC_DETECT		0
+#define GPIO37_ZIPITZ2_HEADSET_DETECT	37
+
+#endif
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index fa527b2..9b90461 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -41,7 +41,6 @@
 
 #include <mach/pxa300.h>
 #include <mach/pxafb.h>
-#include <mach/ssp.h>
 #include <mach/mmc.h>
 #include <mach/pxa2xx_spi.h>
 #include <mach/pxa27x_keypad.h>
@@ -272,7 +271,7 @@
 
 #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
 static struct pxamci_platform_data littleton_mci_platform_data = {
-	.detect_delay		= 20,
+	.detect_delay_ms	= 200,
 	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
 	.gpio_card_detect	= GPIO_MMC1_CARD_DETECT,
 	.gpio_card_ro		= -1,
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 63d65a2..330c328 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -478,7 +478,7 @@
 
 static struct pxamci_platform_data lubbock_mci_platform_data = {
 	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
-	.detect_delay		= 1,
+	.detect_delay_ms	= 10,
 	.init 			= lubbock_mci_init,
 	.get_ro			= lubbock_mci_get_ro,
 	.exit 			= lubbock_mci_exit,
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index cf6b720..1d1419b 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -81,6 +81,7 @@
 		PGSR(bank) &= ~mask;
 		is_out = 1;
 		break;
+	case MFP_LPM_INPUT:
 	case MFP_LPM_DEFAULT:
 		break;
 	default:
@@ -178,8 +179,17 @@
 	if (!d->valid)
 		return -EINVAL;
 
-	if (d->keypad_gpio)
-		return -EINVAL;
+	/* Allow keypad GPIOs to wakeup system when
+	 * configured as generic GPIOs.
+	 */
+	if (d->keypad_gpio && (MFP_AF(d->config) == 0) &&
+	    (d->config & MFP_LPM_CAN_WAKEUP)) {
+		if (on)
+			PKWR |= d->mask;
+		else
+			PKWR &= ~d->mask;
+		return 0;
+	}
 
 	mux_taken = (PWER & d->mux_mask) & (~d->mask);
 	if (on && mux_taken)
@@ -239,21 +249,25 @@
 int keypad_set_wake(unsigned int on)
 {
 	unsigned int i, gpio, mask = 0;
-
-	if (!on) {
-		PKWR = 0;
-		return 0;
-	}
+	struct gpio_desc *d;
 
 	for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
 
 		gpio = pxa27x_pkwr_gpio[i];
+		d = &gpio_desc[gpio];
 
-		if (gpio_desc[gpio].config & MFP_LPM_CAN_WAKEUP)
+		/* skip if configured as generic GPIO */
+		if (MFP_AF(d->config) == 0)
+			continue;
+
+		if (d->config & MFP_LPM_CAN_WAKEUP)
 			mask |= gpio_desc[gpio].mask;
 	}
 
-	PKWR = mask;
+	if (on)
+		PKWR |= mask;
+	else
+		PKWR &= ~mask;
 	return 0;
 }
 
@@ -328,6 +342,17 @@
 {
 	int i;
 
+	/* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */
+	for (i = 0; i < pxa_last_gpio; i++) {
+		if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
+		    (GPDR(i) & GPIO_bit(i))) {
+			if (GPLR(i) & GPIO_bit(i))
+				PGSR(i) |= GPIO_bit(i);
+			else
+				PGSR(i) &= ~GPIO_bit(i);
+		}
+	}
+
 	for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
 
 		saved_gafr[0][i] = GAFR_L(i);
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 7a50ed8..d60db87 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -426,6 +426,7 @@
  * to give the card a chance to fully insert/eject.
  */
 static struct pxamci_platform_data mioa701_mci_info = {
+	.detect_delay_ms	= 250,
 	.ocr_mask 		= MMC_VDD_32_33 | MMC_VDD_33_34,
 	.gpio_card_detect	= GPIO15_SDIO_INSERT,
 	.gpio_card_ro		= GPIO78_SDIO_RO,
@@ -791,7 +792,6 @@
 	mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
 	bootstrap_init();
 	set_pxa_fb_info(&mioa701_pxafb_info);
-	mioa701_mci_info.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&mioa701_mci_info);
 	pxa_set_keypad_info(&mioa701_keypad_info);
 	wm97xx_bat_set_pdata(&mioa701_battery_data);
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
index 8c9c6f0..462167a 100644
--- a/arch/arm/mach-pxa/mxm8x10.c
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -325,7 +325,7 @@
 #if defined(CONFIG_MMC)
 static struct pxamci_platform_data mxm_8x10_mci_platform_data = {
 	.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
-	.detect_delay = 1,
+	.detect_delay_ms = 10,
 	.gpio_card_detect = MXM_8X10_SD_nCD,
 	.gpio_card_ro = MXM_8X10_SD_WP,
 	.gpio_power = -1
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index f70c75b..1963819 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -168,7 +168,7 @@
 	.gpio_card_detect	= GPIO_NR_PALMLD_SD_DETECT_N,
 	.gpio_card_ro		= GPIO_NR_PALMLD_SD_READONLY,
 	.gpio_power		= GPIO_NR_PALMLD_SD_POWER,
-	.detect_delay		= 20,
+	.detect_delay_ms	= 200,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index d902a81..5305a39 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -110,7 +110,7 @@
 	.gpio_card_detect	= GPIO_NR_PALMT5_SD_DETECT_N,
 	.gpio_card_ro		= GPIO_NR_PALMT5_SD_READONLY,
 	.gpio_power		= GPIO_NR_PALMT5_SD_POWER,
-	.detect_delay		= 20,
+	.detect_delay_ms	= 200,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index 717d7a6..033b567 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -121,7 +121,7 @@
 	.gpio_power		= GPIO_NR_PALMTC_SD_POWER,
 	.gpio_card_ro		= GPIO_NR_PALMTC_SD_READONLY,
 	.gpio_card_detect	= GPIO_NR_PALMTC_SD_DETECT_N,
-	.detect_delay		= 20,
+	.detect_delay_ms	= 200,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index 007b58c..ecc1a40 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -170,7 +170,7 @@
 	.gpio_card_detect	= GPIO_NR_PALMTX_SD_DETECT_N,
 	.gpio_card_ro		= GPIO_NR_PALMTX_SD_READONLY,
 	.gpio_power		= GPIO_NR_PALMTX_SD_POWER,
-	.detect_delay		= 20,
+	.detect_delay_ms	= 200,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 9d0ecea1..f56ae10 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -326,7 +326,7 @@
 #define MSECS_PER_JIFFY (1000/HZ)
 
 static struct pxamci_platform_data pcm990_mci_platform_data = {
-	.detect_delay		= 250 / MSECS_PER_JIFFY,
+	.detect_delay_ms	= 250,
 	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
 	.init 			= pcm990_mci_init,
 	.setpower 		= pcm990_mci_setpower,
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index d58a524..f4abdaa 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -40,13 +40,12 @@
 #include <mach/pxa25x.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
-#include <plat/i2c.h>
 #include <mach/irda.h>
 #include <mach/poodle.h>
 #include <mach/pxafb.h>
 #include <mach/sharpsl.h>
-#include <mach/ssp.h>
 #include <mach/pxa2xx_spi.h>
+#include <plat/i2c.h>
 
 #include <asm/hardware/scoop.h>
 #include <asm/hardware/locomo.h>
@@ -277,6 +276,7 @@
 }
 
 static struct pxamci_platform_data poodle_mci_platform_data = {
+	.detect_delay_ms	= 250,
 	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
 	.init 			= poodle_mci_init,
 	.setpower 		= poodle_mci_setpower,
@@ -450,7 +450,6 @@
 	set_pxa_fb_parent(&poodle_locomo_device.dev);
 	set_pxa_fb_info(&poodle_fb_info);
 	pxa_set_udc_info(&udc_info);
-	poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&poodle_mci_platform_data);
 	pxa_set_ficp_info(&poodle_ficp_platform_data);
 	pxa_set_i2c_info(NULL);
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 4d7c03e..f544e58 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -29,7 +29,6 @@
 #include <mach/ohci.h>
 #include <mach/pm.h>
 #include <mach/dma.h>
-#include <mach/ssp.h>
 #include <mach/regs-intc.h>
 #include <plat/i2c.h>
 
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index d12667b..d4b61b3 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -714,7 +714,7 @@
 static struct pxamci_platform_data raumfeld_mci_platform_data = {
 	.init			= raumfeld_mci_init,
 	.exit			= raumfeld_mci_exit,
-	.detect_delay		= 20,
+	.detect_delay_ms	= 200,
 	.gpio_card_detect	= -1,
 	.gpio_card_ro		= -1,
 	.gpio_power		= -1,
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index 1439785..0cc1203 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -10,29 +10,6 @@
 #include <mach/sharpsl_pm.h>
 
 /*
- * SharpSL SSP Driver
- */
-struct corgissp_machinfo {
-	int port;
-	int cs_lcdcon;
-	int cs_ads7846;
-	int cs_max1111;
-	int clk_lcdcon;
-	int clk_ads7846;
-	int clk_max1111;
-};
-
-void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo);
-
-
-/*
- * SharpSL/Corgi LCD Driver
- */
-void corgi_lcdtg_suspend(void);
-void corgi_lcdtg_hw_init(int mode);
-
-
-/*
  * SharpSL Battery/PM Driver
  */
 #define READ_GPIO_BIT(x)    (GPLR(x) & GPIO_bit(x))
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 463d874..cb47672 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -28,7 +28,6 @@
 #include <asm/mach-types.h>
 #include <mach/pm.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
 #include <mach/regs-rtc.h>
 #include <mach/sharpsl.h>
 #include <mach/sharpsl_pm.h>
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 01bdd75..4d2413e 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -86,6 +86,7 @@
 
 	/* GPIOs */
 	GPIO9_GPIO,	/* SPITZ_GPIO_nSD_DETECT */
+	GPIO16_GPIO,	/* SPITZ_GPIO_SYNC */
 	GPIO81_GPIO,	/* SPITZ_GPIO_nSD_WP */
 	GPIO41_GPIO,	/* SPITZ_GPIO_USB_CONNECT */
 	GPIO37_GPIO,	/* SPITZ_GPIO_USB_HOST */
@@ -119,7 +120,8 @@
 	GPIO117_I2C_SCL,
 	GPIO118_I2C_SDA,
 
-	GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
+	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,	/* SPITZ_GPIO_KEY_INT */
+	GPIO1_GPIO | WAKEUP_ON_EDGE_FALL,	/* SPITZ_GPIO_RESET */
 };
 
 /*
@@ -537,6 +539,7 @@
 }
 
 static struct pxamci_platform_data spitz_mci_platform_data = {
+	.detect_delay_ms	= 250,
 	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
 	.setpower 		= spitz_mci_setpower,
 	.gpio_card_detect	= SPITZ_GPIO_nSD_DETECT,
@@ -757,7 +760,6 @@
 	spitz_init_spi();
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
-	spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&spitz_mci_platform_data);
 	pxa_set_ohci_info(&spitz_ohci_platform_data);
 	pxa_set_ficp_info(&spitz_ficp_platform_data);
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index fc5a70c..4209ddf 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -24,9 +24,10 @@
 
 #include <mach/sharpsl.h>
 #include <mach/spitz.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/pxa27x.h>
+
 #include "sharpsl.h"
+#include "generic.h"
 
 #define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
 #define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
@@ -37,10 +38,17 @@
 
 static int spitz_last_ac_status;
 
+static struct gpio spitz_charger_gpios[] = {
+	{ SPITZ_GPIO_KEY_INT,	GPIOF_IN, "Keyboard Interrupt" },
+	{ SPITZ_GPIO_SYNC,	GPIOF_IN, "Sync" },
+	{ SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
+	{ SPITZ_GPIO_JK_B,	  GPIOF_OUT_INIT_LOW, "JK B" },
+	{ SPITZ_GPIO_CHRG_ON,	  GPIOF_OUT_INIT_LOW, "Charger On" },
+};
+
 static void spitz_charger_init(void)
 {
-	pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN);
-	pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
+	gpio_request_array(ARRAY_AND_SIZE(spitz_charger_gpios));
 }
 
 static void spitz_measure_temp(int on)
@@ -76,6 +84,11 @@
 	gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
 }
 
+static unsigned long gpio18_config[] = {
+	GPIO18_RDY,
+	GPIO18_GPIO,
+};
+
 static void spitz_presuspend(void)
 {
 	spitz_last_ac_status = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
@@ -97,7 +110,9 @@
 	PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
 	PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
 
-	pxa_gpio_mode(GPIO18_RDY|GPIO_OUT | GPIO_DFLT_HIGH);
+	pxa2xx_mfp_config(&gpio18_config[0], 1);
+	gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown");
+	gpio_free(18);
 
 	PRER = GPIO_bit(SPITZ_GPIO_KEY_INT);
 	PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
@@ -114,8 +129,7 @@
 
 static void spitz_postsuspend(void)
 {
-	pxa_gpio_mode(GPIO18_RDY_MD);
-	pxa_gpio_mode(10 | GPIO_IN);
+	pxa2xx_mfp_config(&gpio18_config[1], 1);
 }
 
 static int spitz_should_wakeup(unsigned int resume_on_alarm)
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
deleted file mode 100644
index a81d6db..0000000
--- a/arch/arm/mach-pxa/ssp.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- *  linux/arch/arm/mach-pxa/ssp.c
- *
- *  based on linux/arch/arm/mach-sa1100/ssp.c by Russell King
- *
- *  Copyright (C) 2003 Russell King.
- *  Copyright (C) 2003 Wolfson Microelectronics PLC
- *
- * 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.
- *
- *  PXA2xx SSP driver.  This provides the generic core for simple
- *  IO-based SSP applications and allows easy port setup for DMA access.
- *
- *  Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/ssp.h>
-#include <mach/regs-ssp.h>
-
-#ifdef CONFIG_PXA_SSP_LEGACY
-
-#define TIMEOUT 100000
-
-static irqreturn_t ssp_interrupt(int irq, void *dev_id)
-{
-	struct ssp_dev *dev = dev_id;
-	struct ssp_device *ssp = dev->ssp;
-	unsigned int status;
-
-	status = __raw_readl(ssp->mmio_base + SSSR);
-	__raw_writel(status, ssp->mmio_base + SSSR);
-
-	if (status & SSSR_ROR)
-		printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port);
-
-	if (status & SSSR_TUR)
-		printk(KERN_WARNING "SSP(%d): transmitter underrun\n", dev->port);
-
-	if (status & SSSR_BCE)
-		printk(KERN_WARNING "SSP(%d): bit count error\n", dev->port);
-
-	return IRQ_HANDLED;
-}
-
-/**
- * ssp_write_word - write a word to the SSP port
- * @data: 32-bit, MSB justified data to write.
- *
- * Wait for a free entry in the SSP transmit FIFO, and write a data
- * word to the SSP port.
- *
- * The caller is expected to perform the necessary locking.
- *
- * Returns:
- *   %-ETIMEDOUT	timeout occurred
- *   0			success
- */
-int ssp_write_word(struct ssp_dev *dev, u32 data)
-{
-	struct ssp_device *ssp = dev->ssp;
-	int timeout = TIMEOUT;
-
-	while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_TNF)) {
-	        if (!--timeout)
-	        	return -ETIMEDOUT;
-		cpu_relax();
-	}
-
-	__raw_writel(data, ssp->mmio_base + SSDR);
-
-	return 0;
-}
-
-/**
- * ssp_read_word - read a word from the SSP port
- *
- * Wait for a data word in the SSP receive FIFO, and return the
- * received data.  Data is LSB justified.
- *
- * Note: Currently, if data is not expected to be received, this
- * function will wait for ever.
- *
- * The caller is expected to perform the necessary locking.
- *
- * Returns:
- *   %-ETIMEDOUT	timeout occurred
- *   32-bit data	success
- */
-int ssp_read_word(struct ssp_dev *dev, u32 *data)
-{
-	struct ssp_device *ssp = dev->ssp;
-	int timeout = TIMEOUT;
-
-	while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE)) {
-	        if (!--timeout)
-	        	return -ETIMEDOUT;
-		cpu_relax();
-	}
-
-	*data = __raw_readl(ssp->mmio_base + SSDR);
-	return 0;
-}
-
-/**
- * ssp_flush - flush the transmit and receive FIFOs
- *
- * Wait for the SSP to idle, and ensure that the receive FIFO
- * is empty.
- *
- * The caller is expected to perform the necessary locking.
- */
-int ssp_flush(struct ssp_dev *dev)
-{
-	struct ssp_device *ssp = dev->ssp;
-	int timeout = TIMEOUT * 2;
-
-	/* ensure TX FIFO is empty instead of not full */
-	if (cpu_is_pxa3xx()) {
-		while (__raw_readl(ssp->mmio_base + SSSR) & 0xf00) {
-			if (!--timeout)
-				return -ETIMEDOUT;
-			cpu_relax();
-		}
-		timeout = TIMEOUT * 2;
-	}
-
-	do {
-		while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE) {
-		        if (!--timeout)
-		        	return -ETIMEDOUT;
-			(void)__raw_readl(ssp->mmio_base + SSDR);
-		}
-	        if (!--timeout)
-	        	return -ETIMEDOUT;
-	} while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_BSY);
-
-	return 0;
-}
-
-/**
- * ssp_enable - enable the SSP port
- *
- * Turn on the SSP port.
- */
-void ssp_enable(struct ssp_dev *dev)
-{
-	struct ssp_device *ssp = dev->ssp;
-	uint32_t sscr0;
-
-	sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
-	sscr0 |= SSCR0_SSE;
-	__raw_writel(sscr0, ssp->mmio_base + SSCR0);
-}
-
-/**
- * ssp_disable - shut down the SSP port
- *
- * Turn off the SSP port, optionally powering it down.
- */
-void ssp_disable(struct ssp_dev *dev)
-{
-	struct ssp_device *ssp = dev->ssp;
-	uint32_t sscr0;
-
-	sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
-	sscr0 &= ~SSCR0_SSE;
-	__raw_writel(sscr0, ssp->mmio_base + SSCR0);
-}
-
-/**
- * ssp_save_state - save the SSP configuration
- * @ssp: pointer to structure to save SSP configuration
- *
- * Save the configured SSP state for suspend.
- */
-void ssp_save_state(struct ssp_dev *dev, struct ssp_state *state)
-{
-	struct ssp_device *ssp = dev->ssp;
-
-	state->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
-	state->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
-	state->to  = __raw_readl(ssp->mmio_base + SSTO);
-	state->psp = __raw_readl(ssp->mmio_base + SSPSP);
-
-	ssp_disable(dev);
-}
-
-/**
- * ssp_restore_state - restore a previously saved SSP configuration
- * @ssp: pointer to configuration saved by ssp_save_state
- *
- * Restore the SSP configuration saved previously by ssp_save_state.
- */
-void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *state)
-{
-	struct ssp_device *ssp = dev->ssp;
-	uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
-
-	__raw_writel(sssr, ssp->mmio_base + SSSR);
-
-	__raw_writel(state->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
-	__raw_writel(state->cr1, ssp->mmio_base + SSCR1);
-	__raw_writel(state->to,  ssp->mmio_base + SSTO);
-	__raw_writel(state->psp, ssp->mmio_base + SSPSP);
-	__raw_writel(state->cr0, ssp->mmio_base + SSCR0);
-}
-
-/**
- * ssp_config - configure SSP port settings
- * @mode: port operating mode
- * @flags: port config flags
- * @psp_flags: port PSP config flags
- * @speed: port speed
- *
- * Port MUST be disabled by ssp_disable before making any config changes.
- */
-int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed)
-{
-	struct ssp_device *ssp = dev->ssp;
-
-	dev->mode = mode;
-	dev->flags = flags;
-	dev->psp_flags = psp_flags;
-	dev->speed = speed;
-
-	/* set up port type, speed, port settings */
-	__raw_writel((dev->speed | dev->mode), ssp->mmio_base + SSCR0);
-	__raw_writel(dev->flags, ssp->mmio_base + SSCR1);
-	__raw_writel(dev->psp_flags, ssp->mmio_base + SSPSP);
-
-	return 0;
-}
-
-/**
- * ssp_init - setup the SSP port
- *
- * initialise and claim resources for the SSP port.
- *
- * Returns:
- *   %-ENODEV	if the SSP port is unavailable
- *   %-EBUSY	if the resources are already in use
- *   %0		on success
- */
-int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
-{
-	struct ssp_device *ssp;
-	int ret;
-
-	ssp = ssp_request(port, "SSP");
-	if (ssp == NULL)
-		return -ENODEV;
-
-	dev->ssp = ssp;
-	dev->port = port;
-
-	/* do we need to get irq */
-	if (!(init_flags & SSP_NO_IRQ)) {
-		ret = request_irq(ssp->irq, ssp_interrupt,
-				0, "SSP", dev);
-	    	if (ret)
-			goto out_region;
-		dev->irq = ssp->irq;
-	} else
-		dev->irq = NO_IRQ;
-
-	/* turn on SSP port clock */
-	clk_enable(ssp->clk);
-	return 0;
-
-out_region:
-	ssp_free(ssp);
-	return ret;
-}
-
-/**
- * ssp_exit - undo the effects of ssp_init
- *
- * release and free resources for the SSP port.
- */
-void ssp_exit(struct ssp_dev *dev)
-{
-	struct ssp_device *ssp = dev->ssp;
-
-	ssp_disable(dev);
-	if (dev->irq != NO_IRQ)
-		free_irq(dev->irq, dev);
-	clk_disable(ssp->clk);
-	ssp_free(ssp);
-}
-#endif /* CONFIG_PXA_SSP_LEGACY */
-
-static DEFINE_MUTEX(ssp_lock);
-static LIST_HEAD(ssp_list);
-
-struct ssp_device *ssp_request(int port, const char *label)
-{
-	struct ssp_device *ssp = NULL;
-
-	mutex_lock(&ssp_lock);
-
-	list_for_each_entry(ssp, &ssp_list, node) {
-		if (ssp->port_id == port && ssp->use_count == 0) {
-			ssp->use_count++;
-			ssp->label = label;
-			break;
-		}
-	}
-
-	mutex_unlock(&ssp_lock);
-
-	if (&ssp->node == &ssp_list)
-		return NULL;
-
-	return ssp;
-}
-EXPORT_SYMBOL(ssp_request);
-
-void ssp_free(struct ssp_device *ssp)
-{
-	mutex_lock(&ssp_lock);
-	if (ssp->use_count) {
-		ssp->use_count--;
-		ssp->label = NULL;
-	} else
-		dev_err(&ssp->pdev->dev, "device already free\n");
-	mutex_unlock(&ssp_lock);
-}
-EXPORT_SYMBOL(ssp_free);
-
-static int __devinit ssp_probe(struct platform_device *pdev)
-{
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	struct resource *res;
-	struct ssp_device *ssp;
-	int ret = 0;
-
-	ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL);
-	if (ssp == NULL) {
-		dev_err(&pdev->dev, "failed to allocate memory");
-		return -ENOMEM;
-	}
-	ssp->pdev = pdev;
-
-	ssp->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(ssp->clk)) {
-		ret = PTR_ERR(ssp->clk);
-		goto err_free;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "no memory resource defined\n");
-		ret = -ENODEV;
-		goto err_free_clk;
-	}
-
-	res = request_mem_region(res->start, res->end - res->start + 1,
-			pdev->name);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to request memory resource\n");
-		ret = -EBUSY;
-		goto err_free_clk;
-	}
-
-	ssp->phys_base = res->start;
-
-	ssp->mmio_base = ioremap(res->start, res->end - res->start + 1);
-	if (ssp->mmio_base == NULL) {
-		dev_err(&pdev->dev, "failed to ioremap() registers\n");
-		ret = -ENODEV;
-		goto err_free_mem;
-	}
-
-	ssp->irq = platform_get_irq(pdev, 0);
-	if (ssp->irq < 0) {
-		dev_err(&pdev->dev, "no IRQ resource defined\n");
-		ret = -ENODEV;
-		goto err_free_io;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "no SSP RX DRCMR defined\n");
-		ret = -ENODEV;
-		goto err_free_io;
-	}
-	ssp->drcmr_rx = res->start;
-
-	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "no SSP TX DRCMR defined\n");
-		ret = -ENODEV;
-		goto err_free_io;
-	}
-	ssp->drcmr_tx = res->start;
-
-	/* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
-	 * starts from 0, do a translation here
-	 */
-	ssp->port_id = pdev->id + 1;
-	ssp->use_count = 0;
-	ssp->type = (int)id->driver_data;
-
-	mutex_lock(&ssp_lock);
-	list_add(&ssp->node, &ssp_list);
-	mutex_unlock(&ssp_lock);
-
-	platform_set_drvdata(pdev, ssp);
-	return 0;
-
-err_free_io:
-	iounmap(ssp->mmio_base);
-err_free_mem:
-	release_mem_region(res->start, res->end - res->start + 1);
-err_free_clk:
-	clk_put(ssp->clk);
-err_free:
-	kfree(ssp);
-	return ret;
-}
-
-static int __devexit ssp_remove(struct platform_device *pdev)
-{
-	struct resource *res;
-	struct ssp_device *ssp;
-
-	ssp = platform_get_drvdata(pdev);
-	if (ssp == NULL)
-		return -ENODEV;
-
-	iounmap(ssp->mmio_base);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, res->end - res->start + 1);
-
-	clk_put(ssp->clk);
-
-	mutex_lock(&ssp_lock);
-	list_del(&ssp->node);
-	mutex_unlock(&ssp_lock);
-
-	kfree(ssp);
-	return 0;
-}
-
-static const struct platform_device_id ssp_id_table[] = {
-	{ "pxa25x-ssp",		PXA25x_SSP },
-	{ "pxa25x-nssp",	PXA25x_NSSP },
-	{ "pxa27x-ssp",		PXA27x_SSP },
-	{ },
-};
-
-static struct platform_driver ssp_driver = {
-	.probe		= ssp_probe,
-	.remove		= __devexit_p(ssp_remove),
-	.driver		= {
-		.owner	= THIS_MODULE,
-		.name	= "pxa2xx-ssp",
-	},
-	.id_table	= ssp_id_table,
-};
-
-static int __init pxa_ssp_init(void)
-{
-	return platform_driver_register(&ssp_driver);
-}
-
-static void __exit pxa_ssp_exit(void)
-{
-	platform_driver_unregister(&ssp_driver);
-}
-
-arch_initcall(pxa_ssp_init);
-module_exit(pxa_ssp_exit);
-
-#ifdef CONFIG_PXA_SSP_LEGACY
-EXPORT_SYMBOL(ssp_write_word);
-EXPORT_SYMBOL(ssp_read_word);
-EXPORT_SYMBOL(ssp_flush);
-EXPORT_SYMBOL(ssp_enable);
-EXPORT_SYMBOL(ssp_disable);
-EXPORT_SYMBOL(ssp_save_state);
-EXPORT_SYMBOL(ssp_restore_state);
-EXPORT_SYMBOL(ssp_init);
-EXPORT_SYMBOL(ssp_exit);
-EXPORT_SYMBOL(ssp_config);
-#endif
-
-MODULE_DESCRIPTION("PXA SSP driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
-
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index 2041eb1..af40d2a 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -464,8 +464,6 @@
 
 
 
-static struct pxamci_platform_data stargate2_mci_platform_data;
-
 /*
  * The card detect interrupt isn't debounced so we delay it by 250ms
  * to give the card a chance to fully insert / eject.
@@ -489,8 +487,6 @@
 		goto free_power_en;
 	}
 	gpio_direction_input(SG2_GPIO_nSD_DETECT);
-	/* Delay to allow for full insertion */
-	stargate2_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
 	err = request_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT),
 			  stargate2_detect_int,
@@ -529,6 +525,7 @@
 }
 
 static struct pxamci_platform_data stargate2_mci_platform_data = {
+	.detect_delay_ms = 250,
 	.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
 	.init = stargate2_mci_init,
 	.setpower = stargate2_mci_setpower,
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index ad552791..7512b82 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -275,6 +275,7 @@
 }
 
 static struct pxamci_platform_data tosa_mci_platform_data = {
+	.detect_delay_ms	= 250,
 	.ocr_mask       	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.init           	= tosa_mci_init,
 	.exit           	= tosa_mci_exit,
@@ -926,7 +927,6 @@
 	dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12);
 	dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
 
-	tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&tosa_mci_platform_data);
 	pxa_set_udc_info(&udc_info);
 	pxa_set_ficp_info(&tosa_ficp_platform_data);
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 797f254..6968911 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -349,7 +349,7 @@
 
 static struct pxamci_platform_data trizeps4_mci_platform_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.detect_delay	= 1,
+	.detect_delay_ms= 10,
 	.init 		= trizeps4_mci_init,
 	.exit		= trizeps4_mci_exit,
 	.get_ro		= NULL,	/* write-protection not supported */
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
new file mode 100644
index 0000000..9884fa9
--- /dev/null
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -0,0 +1,615 @@
+/*
+ * Hardware definitions for Voipac PXA270
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.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/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/sysdev.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/onenand.h>
+#include <linux/dm9000.h>
+#include <linux/ucb1400.h>
+#include <linux/ata_platform.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/vpac270.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/ohci.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/udc.h>
+
+#include <plat/i2c.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long vpac270_pin_config[] __initdata = {
+	/* MMC */
+	GPIO32_MMC_CLK,
+	GPIO92_MMC_DAT_0,
+	GPIO109_MMC_DAT_1,
+	GPIO110_MMC_DAT_2,
+	GPIO111_MMC_DAT_3,
+	GPIO112_MMC_CMD,
+	GPIO53_GPIO,	/* SD detect */
+	GPIO52_GPIO,	/* SD r/o switch */
+
+	/* GPIO KEYS */
+	GPIO1_GPIO,	/* USER BTN */
+
+	/* LEDs */
+	GPIO15_GPIO,	/* orange led */
+
+	/* FFUART */
+	GPIO34_FFUART_RXD,
+	GPIO39_FFUART_TXD,
+	GPIO27_FFUART_RTS,
+	GPIO100_FFUART_CTS,
+	GPIO33_FFUART_DSR,
+	GPIO40_FFUART_DTR,
+	GPIO10_FFUART_DCD,
+	GPIO38_FFUART_RI,
+
+	/* LCD */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO86_LCD_LDD_16,
+	GPIO87_LCD_LDD_17,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+	GPIO77_LCD_BIAS,
+
+	/* PCMCIA */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO85_nPCE_1,
+	GPIO54_nPCE_2,
+	GPIO55_nPREG,
+	GPIO57_nIOIS16,
+	GPIO56_nPWAIT,
+	GPIO104_PSKTSEL,
+	GPIO84_GPIO,	/* PCMCIA CD */
+	GPIO35_GPIO,	/* PCMCIA RDY */
+	GPIO107_GPIO,	/* PCMCIA PPEN */
+	GPIO11_GPIO,	/* PCMCIA RESET */
+	GPIO17_GPIO,	/* CF CD */
+	GPIO12_GPIO,	/* CF RDY */
+	GPIO16_GPIO,	/* CF RESET */
+
+	/* UHC */
+	GPIO88_USBH1_PWR,
+	GPIO89_USBH1_PEN,
+	GPIO119_USBH2_PWR,
+	GPIO120_USBH2_PEN,
+
+	/* UDC */
+	GPIO41_GPIO,
+
+	/* Ethernet */
+	GPIO114_GPIO,	/* IRQ */
+
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+	GPIO95_AC97_nRESET,
+	GPIO98_AC97_SYSCLK,
+	GPIO113_GPIO,	/* TS IRQ */
+
+	/* I2C */
+	GPIO117_I2C_SCL,
+	GPIO118_I2C_SDA,
+
+	/* IDE */
+	GPIO36_GPIO,	/* IDE IRQ */
+	GPIO80_DREQ_1,
+};
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition vpac270_nor_partitions[] = {
+	{
+		.name		= "Flash",
+		.offset		= 0x00000000,
+		.size		= MTDPART_SIZ_FULL,
+	}
+};
+
+static struct physmap_flash_data vpac270_flash_data[] = {
+	{
+		.width		= 2,	/* bankwidth in bytes */
+		.parts		= vpac270_nor_partitions,
+		.nr_parts	= ARRAY_SIZE(vpac270_nor_partitions)
+	}
+};
+
+static struct resource vpac270_flash_resource = {
+	.start	= PXA_CS0_PHYS,
+	.end	= PXA_CS0_PHYS + SZ_64M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device vpac270_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.resource	= &vpac270_flash_resource,
+	.num_resources	= 1,
+	.dev 		= {
+		.platform_data = vpac270_flash_data,
+	},
+};
+static void __init vpac270_nor_init(void)
+{
+	platform_device_register(&vpac270_flash);
+}
+#else
+static inline void vpac270_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * OneNAND Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE)
+static struct mtd_partition vpac270_onenand_partitions[] = {
+	{
+		.name		= "Flash",
+		.offset		= 0x00000000,
+		.size		= MTDPART_SIZ_FULL,
+	}
+};
+
+static struct onenand_platform_data vpac270_onenand_info = {
+	.parts		= vpac270_onenand_partitions,
+	.nr_parts	= ARRAY_SIZE(vpac270_onenand_partitions),
+};
+
+static struct resource vpac270_onenand_resources[] = {
+	[0] = {
+		.start	= PXA_CS0_PHYS,
+		.end	= PXA_CS0_PHYS + SZ_1M,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device vpac270_onenand = {
+	.name		= "onenand-flash",
+	.id		= -1,
+	.resource	= vpac270_onenand_resources,
+	.num_resources	= ARRAY_SIZE(vpac270_onenand_resources),
+	.dev		= {
+		.platform_data	= &vpac270_onenand_info,
+	},
+};
+
+static void __init vpac270_onenand_init(void)
+{
+	platform_device_register(&vpac270_onenand);
+}
+#else
+static void __init vpac270_onenand_init(void) {}
+#endif
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data vpac270_mci_platform_data = {
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO53_VPAC270_SD_DETECT_N,
+	.gpio_card_ro		= GPIO52_VPAC270_SD_READONLY,
+	.detect_delay_ms	= 200,
+};
+
+static void __init vpac270_mmc_init(void)
+{
+	pxa_set_mci_info(&vpac270_mci_platform_data);
+}
+#else
+static inline void vpac270_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button vpac270_pxa_buttons[] = {
+	{KEY_POWER, GPIO1_VPAC270_USER_BTN, 0, "USER BTN"},
+};
+
+static struct gpio_keys_platform_data vpac270_pxa_keys_data = {
+	.buttons	= vpac270_pxa_buttons,
+	.nbuttons	= ARRAY_SIZE(vpac270_pxa_buttons),
+};
+
+static struct platform_device vpac270_pxa_keys = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &vpac270_pxa_keys_data,
+	},
+};
+
+static void __init vpac270_keys_init(void)
+{
+	platform_device_register(&vpac270_pxa_keys);
+}
+#else
+static inline void vpac270_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * LED
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led vpac270_gpio_leds[] = {
+{
+	.name			= "vpac270:orange:user",
+	.default_trigger	= "none",
+	.gpio			= GPIO15_VPAC270_LED_ORANGE,
+	.active_low		= 1,
+}
+};
+
+static struct gpio_led_platform_data vpac270_gpio_led_info = {
+	.leds		= vpac270_gpio_leds,
+	.num_leds	= ARRAY_SIZE(vpac270_gpio_leds),
+};
+
+static struct platform_device vpac270_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &vpac270_gpio_led_info,
+	}
+};
+
+static void __init vpac270_leds_init(void)
+{
+	platform_device_register(&vpac270_leds);
+}
+#else
+static inline void vpac270_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Host
+ ******************************************************************************/
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static int vpac270_ohci_init(struct device *dev)
+{
+	UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;
+	return 0;
+}
+
+static struct pxaohci_platform_data vpac270_ohci_info = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.flags		= ENABLE_PORT1 | ENABLE_PORT2 |
+			POWER_CONTROL_LOW | POWER_SENSE_LOW,
+	.init		= vpac270_ohci_init,
+};
+
+static void __init vpac270_uhc_init(void)
+{
+	pxa_set_ohci_info(&vpac270_ohci_info);
+}
+#else
+static inline void vpac270_uhc_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Gadget
+ ******************************************************************************/
+#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+static struct gpio_vbus_mach_info vpac270_gpio_vbus_info = {
+	.gpio_vbus		= GPIO41_VPAC270_UDC_DETECT,
+	.gpio_pullup		= -1,
+};
+
+static struct platform_device vpac270_gpio_vbus = {
+	.name	= "gpio-vbus",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &vpac270_gpio_vbus_info,
+	},
+};
+
+static void vpac270_udc_command(int cmd)
+{
+	if (cmd == PXA2XX_UDC_CMD_CONNECT)
+		UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE;
+	else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
+		UP2OCR = UP2OCR_HXOE;
+}
+
+static struct pxa2xx_udc_mach_info vpac270_udc_info __initdata = {
+	.udc_command		= vpac270_udc_command,
+	.gpio_pullup		= -1,
+};
+
+static void __init vpac270_udc_init(void)
+{
+	pxa_set_udc_info(&vpac270_udc_info);
+	platform_device_register(&vpac270_gpio_vbus);
+}
+#else
+static inline void vpac270_udc_init(void) {}
+#endif
+
+/******************************************************************************
+ * Ethernet
+ ******************************************************************************/
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource vpac270_dm9000_resources[] = {
+	[0] = {
+		.start	= PXA_CS2_PHYS + 0x300,
+		.end	= PXA_CS2_PHYS + 0x303,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= PXA_CS2_PHYS + 0x304,
+		.end	= PXA_CS2_PHYS + 0x343,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ),
+		.end	= IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	},
+};
+
+static struct dm9000_plat_data vpac270_dm9000_platdata = {
+	.flags		= DM9000_PLATF_32BITONLY,
+};
+
+static struct platform_device vpac270_dm9000_device = {
+	.name		= "dm9000",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(vpac270_dm9000_resources),
+	.resource	= vpac270_dm9000_resources,
+	.dev		= {
+		.platform_data = &vpac270_dm9000_platdata,
+	}
+};
+
+static void __init vpac270_eth_init(void)
+{
+	platform_device_register(&vpac270_dm9000_device);
+}
+#else
+static inline void vpac270_eth_init(void) {}
+#endif
+
+/******************************************************************************
+ * Audio and Touchscreen
+ ******************************************************************************/
+#if	defined(CONFIG_TOUCHSCREEN_UCB1400) || \
+	defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static pxa2xx_audio_ops_t vpac270_ac97_pdata = {
+	.reset_gpio	= 95,
+};
+
+static struct ucb1400_pdata vpac270_ucb1400_pdata = {
+	.irq		= IRQ_GPIO(GPIO113_VPAC270_TS_IRQ),
+};
+
+static struct platform_device vpac270_ucb1400_device = {
+	.name		= "ucb1400_core",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &vpac270_ucb1400_pdata,
+	},
+};
+
+static void __init vpac270_ts_init(void)
+{
+	pxa_set_ac97_info(&vpac270_ac97_pdata);
+	platform_device_register(&vpac270_ucb1400_device);
+}
+#else
+static inline void vpac270_ts_init(void) {}
+#endif
+
+/******************************************************************************
+ * RTC
+ ******************************************************************************/
+#if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE)
+static struct i2c_board_info __initdata vpac270_i2c_devs[] = {
+	{
+		I2C_BOARD_INFO("ds1339", 0x68),
+	},
+};
+
+static void __init vpac270_rtc_init(void)
+{
+	pxa_set_i2c_info(NULL);
+	i2c_register_board_info(0, ARRAY_AND_SIZE(vpac270_i2c_devs));
+}
+#else
+static inline void vpac270_rtc_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info vpac270_lcd_modes[] = {
+{
+	.pixclock	= 57692,
+	.xres		= 640,
+	.yres		= 480,
+	.bpp		= 32,
+	.depth		= 18,
+
+	.left_margin	= 144,
+	.right_margin	= 32,
+	.upper_margin	= 13,
+	.lower_margin	= 30,
+
+	.hsync_len	= 32,
+	.vsync_len	= 2,
+
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+},
+};
+
+static struct pxafb_mach_info vpac270_lcd_screen = {
+	.modes		= vpac270_lcd_modes,
+	.num_modes	= ARRAY_SIZE(vpac270_lcd_modes),
+	.lcd_conn	= LCD_COLOR_TFT_18BPP,
+};
+
+static void vpac270_lcd_power(int on, struct fb_var_screeninfo *info)
+{
+	gpio_set_value(GPIO81_VPAC270_BKL_ON, on);
+}
+
+static void __init vpac270_lcd_init(void)
+{
+	int ret;
+
+	ret = gpio_request(GPIO81_VPAC270_BKL_ON, "BKL-ON");
+	if (ret) {
+		pr_err("Requesting BKL-ON GPIO failed!\n");
+		goto err;
+	}
+
+	ret = gpio_direction_output(GPIO81_VPAC270_BKL_ON, 1);
+	if (ret) {
+		pr_err("Setting BKL-ON GPIO direction failed!\n");
+		goto err2;
+	}
+
+	vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power;
+	set_pxa_fb_info(&vpac270_lcd_screen);
+	return;
+
+err2:
+	gpio_free(GPIO81_VPAC270_BKL_ON);
+err:
+	return;
+}
+#else
+static inline void vpac270_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * PATA IDE
+ ******************************************************************************/
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+static struct pata_platform_info vpac270_pata_pdata = {
+	.ioport_shift	= 1,
+	.irq_flags	= IRQF_TRIGGER_RISING,
+};
+
+static struct resource vpac270_ide_resources[] = {
+	[0] = {	/* I/O Base address */
+	       .start	= PXA_CS3_PHYS + 0x120,
+	       .end	= PXA_CS3_PHYS + 0x13f,
+	       .flags	= IORESOURCE_MEM
+	},
+	[1] = {	/* CTL Base address */
+	       .start	= PXA_CS3_PHYS + 0x15c,
+	       .end	= PXA_CS3_PHYS + 0x15f,
+	       .flags	= IORESOURCE_MEM
+	},
+	[2] = {	/* IDE IRQ pin */
+	       .start	= gpio_to_irq(GPIO36_VPAC270_IDE_IRQ),
+	       .end	= gpio_to_irq(GPIO36_VPAC270_IDE_IRQ),
+	       .flags	= IORESOURCE_IRQ
+	}
+};
+
+static struct platform_device vpac270_ide_device = {
+	.name		= "pata_platform",
+	.num_resources	= ARRAY_SIZE(vpac270_ide_resources),
+	.resource	= vpac270_ide_resources,
+	.dev		= {
+		.platform_data	= &vpac270_pata_pdata,
+	}
+};
+
+static void __init vpac270_ide_init(void)
+{
+	platform_device_register(&vpac270_ide_device);
+}
+#else
+static inline void vpac270_ide_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init vpac270_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(vpac270_pin_config));
+
+	pxa_set_ffuart_info(NULL);
+	pxa_set_btuart_info(NULL);
+	pxa_set_stuart_info(NULL);
+
+	vpac270_lcd_init();
+	vpac270_mmc_init();
+	vpac270_nor_init();
+	vpac270_onenand_init();
+	vpac270_leds_init();
+	vpac270_keys_init();
+	vpac270_uhc_init();
+	vpac270_udc_init();
+	vpac270_eth_init();
+	vpac270_ts_init();
+	vpac270_rtc_init();
+	vpac270_ide_init();
+}
+
+MACHINE_START(VPAC270, "Voipac PXA270")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= vpac270_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
new file mode 100644
index 0000000..f5d1ae3
--- /dev/null
+++ b/arch/arm/mach-pxa/z2.c
@@ -0,0 +1,609 @@
+/*
+ *  linux/arch/arm/mach-pxa/z2.c
+ *
+ *  Support for the Zipit Z2 Handheld device.
+ *
+ *  Author: 	Ken McGuire
+ *  Created:	Jan 25, 2009
+ *  Based on mainstone.c as modified for the Zipit Z2.
+ *
+ *  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/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pwm_backlight.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/libertas_spi.h>
+#include <linux/spi/lms283gf05.h>
+#include <linux/power_supply.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/z2.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/pxa27x_keypad.h>
+#include <mach/pxa2xx_spi.h>
+
+#include <plat/i2c.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long z2_pin_config[] = {
+
+	/* LCD - 16bpp Active TFT */
+	GPIO58_LCD_LDD_0,
+	GPIO59_LCD_LDD_1,
+	GPIO60_LCD_LDD_2,
+	GPIO61_LCD_LDD_3,
+	GPIO62_LCD_LDD_4,
+	GPIO63_LCD_LDD_5,
+	GPIO64_LCD_LDD_6,
+	GPIO65_LCD_LDD_7,
+	GPIO66_LCD_LDD_8,
+	GPIO67_LCD_LDD_9,
+	GPIO68_LCD_LDD_10,
+	GPIO69_LCD_LDD_11,
+	GPIO70_LCD_LDD_12,
+	GPIO71_LCD_LDD_13,
+	GPIO72_LCD_LDD_14,
+	GPIO73_LCD_LDD_15,
+	GPIO74_LCD_FCLK,
+	GPIO75_LCD_LCLK,
+	GPIO76_LCD_PCLK,
+	GPIO77_LCD_BIAS,
+	GPIO19_GPIO,		/* LCD reset */
+	GPIO88_GPIO,		/* LCD chipselect */
+
+	/* PWM */
+	GPIO115_PWM1_OUT,	/* Keypad Backlight */
+	GPIO11_PWM2_OUT,	/* LCD Backlight */
+
+	/* MMC */
+	GPIO32_MMC_CLK,
+	GPIO112_MMC_CMD,
+	GPIO92_MMC_DAT_0,
+	GPIO109_MMC_DAT_1,
+	GPIO110_MMC_DAT_2,
+	GPIO111_MMC_DAT_3,
+	GPIO96_GPIO,		/* SD detect */
+
+	/* STUART */
+	GPIO46_STUART_RXD,
+	GPIO47_STUART_TXD,
+
+	/* Keypad */
+	GPIO100_KP_MKIN_0	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO101_KP_MKIN_1	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO102_KP_MKIN_2	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO34_KP_MKIN_3	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO38_KP_MKIN_4	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO16_KP_MKIN_5	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO17_KP_MKIN_6	| WAKEUP_ON_LEVEL_HIGH,
+	GPIO103_KP_MKOUT_0,
+	GPIO104_KP_MKOUT_1,
+	GPIO105_KP_MKOUT_2,
+	GPIO106_KP_MKOUT_3,
+	GPIO107_KP_MKOUT_4,
+	GPIO108_KP_MKOUT_5,
+	GPIO35_KP_MKOUT_6,
+	GPIO41_KP_MKOUT_7,
+
+	/* I2C */
+	GPIO117_I2C_SCL,
+	GPIO118_I2C_SDA,
+
+	/* SSP1 */
+	GPIO23_SSP1_SCLK,	/* SSP1_SCK */
+	GPIO25_SSP1_TXD,	/* SSP1_TXD */
+	GPIO26_SSP1_RXD,	/* SSP1_RXD */
+
+	/* SSP2 */
+	GPIO22_SSP2_SCLK,	/* SSP2_SCK */
+	GPIO13_SSP2_TXD,	/* SSP2_TXD */
+	GPIO40_SSP2_RXD,	/* SSP2_RXD */
+
+	/* LEDs */
+	GPIO10_GPIO,		/* WiFi LED */
+	GPIO83_GPIO,		/* Charging LED */
+	GPIO85_GPIO,		/* Charged LED */
+
+	/* I2S */
+	GPIO28_I2S_BITCLK_OUT,
+	GPIO29_I2S_SDATA_IN,
+	GPIO30_I2S_SDATA_OUT,
+	GPIO31_I2S_SYNC,
+	GPIO113_I2S_SYSCLK,
+
+	/* MISC */
+	GPIO0_GPIO,		/* AC power detect */
+	GPIO1_GPIO,		/* Power button */
+	GPIO37_GPIO,		/* Headphone detect */
+	GPIO98_GPIO,		/* Lid switch */
+	GPIO14_GPIO,		/* WiFi Reset */
+	GPIO15_GPIO,		/* WiFi Power */
+	GPIO24_GPIO,		/* WiFi CS */
+	GPIO36_GPIO,		/* WiFi IRQ */
+	GPIO88_GPIO,		/* LCD CS */
+};
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct resource z2_flash_resource = {
+	.start	= PXA_CS0_PHYS,
+	.end	= PXA_CS0_PHYS + SZ_8M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct mtd_partition z2_flash_parts[] = {
+	{
+		.name	= "U-Boot Bootloader",
+		.offset	= 0x0,
+		.size	= 0x20000,
+	},
+	{
+		.name	= "Linux Kernel",
+		.offset	= 0x20000,
+		.size	= 0x220000,
+	},
+	{
+		.name	= "Filesystem",
+		.offset	= 0x240000,
+		.size	= 0x5b0000,
+	},
+	{
+		.name	= "U-Boot Environment",
+		.offset	= 0x7f0000,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data z2_flash_data = {
+	.width		= 2,
+	.parts		= z2_flash_parts,
+	.nr_parts	= ARRAY_SIZE(z2_flash_parts),
+};
+
+static struct platform_device z2_flash = {
+	.name		= "physmap-flash",
+	.id		= -1,
+	.resource	= &z2_flash_resource,
+	.num_resources	= 1,
+	.dev = {
+		.platform_data	= &z2_flash_data,
+	},
+};
+
+static void __init z2_nor_init(void)
+{
+	platform_device_register(&z2_flash);
+}
+#else
+static inline void z2_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct platform_pwm_backlight_data z2_backlight_data[] = {
+	[0] = {
+		/* Keypad Backlight */
+		.pwm_id		= 1,
+		.max_brightness	= 1023,
+		.dft_brightness	= 512,
+		.pwm_period_ns	= 1260320,
+	},
+	[1] = {
+		/* LCD Backlight */
+		.pwm_id		= 2,
+		.max_brightness	= 1023,
+		.dft_brightness	= 512,
+		.pwm_period_ns	= 1260320,
+	},
+};
+
+static struct platform_device z2_backlight_devices[2] = {
+	{
+		.name	= "pwm-backlight",
+		.id	= 0,
+		.dev	= {
+			.platform_data	= &z2_backlight_data[1],
+		},
+	},
+	{
+		.name	= "pwm-backlight",
+		.id	= 1,
+		.dev	= {
+			.platform_data	= &z2_backlight_data[0],
+		},
+	},
+};
+static void __init z2_pwm_init(void)
+{
+	platform_device_register(&z2_backlight_devices[0]);
+	platform_device_register(&z2_backlight_devices[1]);
+}
+#else
+static inline void z2_pwm_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info z2_lcd_modes[] = {
+{
+	.pixclock	= 192000,
+	.xres		= 240,
+	.yres		= 320,
+	.bpp		= 16,
+
+	.left_margin	= 4,
+	.right_margin	= 8,
+	.upper_margin	= 4,
+	.lower_margin	= 8,
+
+	.hsync_len	= 4,
+	.vsync_len	= 4,
+},
+};
+
+static struct pxafb_mach_info z2_lcd_screen = {
+	.modes		= z2_lcd_modes,
+	.num_modes      = ARRAY_SIZE(z2_lcd_modes),
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_BIAS_ACTIVE_LOW |
+			  LCD_ALTERNATE_MAPPING,
+};
+
+static void __init z2_lcd_init(void)
+{
+	set_pxa_fb_info(&z2_lcd_screen);
+}
+#else
+static inline void z2_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data z2_mci_platform_data = {
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO96_ZIPITZ2_SD_DETECT,
+	.gpio_power		= -1,
+	.gpio_card_ro		= -1,
+	.detect_delay_ms	= 200,
+};
+
+static void __init z2_mmc_init(void)
+{
+	pxa_set_mci_info(&z2_mci_platform_data);
+}
+#else
+static inline void z2_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led z2_gpio_leds[] = {
+{
+	.name			= "z2:green:wifi",
+	.default_trigger	= "none",
+	.gpio			= GPIO10_ZIPITZ2_LED_WIFI,
+	.active_low		= 1,
+}, {
+	.name			= "z2:green:charged",
+	.default_trigger	= "none",
+	.gpio			= GPIO85_ZIPITZ2_LED_CHARGED,
+	.active_low		= 1,
+}, {
+	.name			= "z2:amber:charging",
+	.default_trigger	= "none",
+	.gpio			= GPIO83_ZIPITZ2_LED_CHARGING,
+	.active_low		= 1,
+},
+};
+
+static struct gpio_led_platform_data z2_gpio_led_info = {
+	.leds		= z2_gpio_leds,
+	.num_leds	= ARRAY_SIZE(z2_gpio_leds),
+};
+
+static struct platform_device z2_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &z2_gpio_led_info,
+	}
+};
+
+static void __init z2_leds_init(void)
+{
+	platform_device_register(&z2_leds);
+}
+#else
+static inline void z2_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int z2_matrix_keys[] = {
+	KEY(0, 0, KEY_OPTION),
+	KEY(1, 0, KEY_UP),
+	KEY(2, 0, KEY_DOWN),
+	KEY(3, 0, KEY_LEFT),
+	KEY(4, 0, KEY_RIGHT),
+	KEY(5, 0, KEY_END),
+	KEY(6, 0, KEY_KPPLUS),
+
+	KEY(0, 1, KEY_HOME),
+	KEY(1, 1, KEY_Q),
+	KEY(2, 1, KEY_I),
+	KEY(3, 1, KEY_G),
+	KEY(4, 1, KEY_X),
+	KEY(5, 1, KEY_ENTER),
+	KEY(6, 1, KEY_KPMINUS),
+
+	KEY(0, 2, KEY_PAGEUP),
+	KEY(1, 2, KEY_W),
+	KEY(2, 2, KEY_O),
+	KEY(3, 2, KEY_H),
+	KEY(4, 2, KEY_C),
+	KEY(5, 2, KEY_LEFTALT),
+
+	KEY(0, 3, KEY_PAGEDOWN),
+	KEY(1, 3, KEY_E),
+	KEY(2, 3, KEY_P),
+	KEY(3, 3, KEY_J),
+	KEY(4, 3, KEY_V),
+	KEY(5, 3, KEY_LEFTSHIFT),
+
+	KEY(0, 4, KEY_ESC),
+	KEY(1, 4, KEY_R),
+	KEY(2, 4, KEY_A),
+	KEY(3, 4, KEY_K),
+	KEY(4, 4, KEY_B),
+	KEY(5, 4, KEY_LEFTCTRL),
+
+	KEY(0, 5, KEY_TAB),
+	KEY(1, 5, KEY_T),
+	KEY(2, 5, KEY_S),
+	KEY(3, 5, KEY_L),
+	KEY(4, 5, KEY_N),
+	KEY(5, 5, KEY_SPACE),
+
+	KEY(0, 6, KEY_STOPCD),
+	KEY(1, 6, KEY_Y),
+	KEY(2, 6, KEY_D),
+	KEY(3, 6, KEY_BACKSPACE),
+	KEY(4, 6, KEY_M),
+	KEY(5, 6, KEY_COMMA),
+
+	KEY(0, 7, KEY_PLAYCD),
+	KEY(1, 7, KEY_U),
+	KEY(2, 7, KEY_F),
+	KEY(3, 7, KEY_Z),
+	KEY(4, 7, KEY_SEMICOLON),
+	KEY(5, 7, KEY_DOT),
+};
+
+static struct pxa27x_keypad_platform_data z2_keypad_platform_data = {
+	.matrix_key_rows	= 7,
+	.matrix_key_cols	= 8,
+	.matrix_key_map		= z2_matrix_keys,
+	.matrix_key_map_size	= ARRAY_SIZE(z2_matrix_keys),
+
+	.debounce_interval	= 30,
+};
+
+static void __init z2_mkp_init(void)
+{
+	pxa_set_keypad_info(&z2_keypad_platform_data);
+}
+#else
+static inline void z2_mkp_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button z2_pxa_buttons[] = {
+	{KEY_POWER, GPIO1_ZIPITZ2_POWER_BUTTON, 0, "Power Button" },
+	{KEY_CLOSE, GPIO98_ZIPITZ2_LID_BUTTON, 0, "Lid Button" },
+};
+
+static struct gpio_keys_platform_data z2_pxa_keys_data = {
+	.buttons	= z2_pxa_buttons,
+	.nbuttons	= ARRAY_SIZE(z2_pxa_buttons),
+};
+
+static struct platform_device z2_pxa_keys = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &z2_pxa_keys_data,
+	},
+};
+
+static void __init z2_keys_init(void)
+{
+	platform_device_register(&z2_pxa_keys);
+}
+#else
+static inline void z2_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * SSP Devices - WiFi and LCD control
+ ******************************************************************************/
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+/* WiFi */
+static int z2_lbs_spi_setup(struct spi_device *spi)
+{
+	int ret = 0;
+
+	ret = gpio_request(GPIO15_ZIPITZ2_WIFI_POWER, "WiFi Power");
+	if (ret)
+		goto err;
+
+	ret = gpio_direction_output(GPIO15_ZIPITZ2_WIFI_POWER, 1);
+	if (ret)
+		goto err2;
+
+	ret = gpio_request(GPIO14_ZIPITZ2_WIFI_RESET, "WiFi Reset");
+	if (ret)
+		goto err2;
+
+	ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_RESET, 0);
+	if (ret)
+		goto err3;
+
+	/* Reset the card */
+	mdelay(180);
+	gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 1);
+	mdelay(20);
+
+	spi->bits_per_word = 16;
+	spi->mode = SPI_MODE_2,
+
+	spi_setup(spi);
+
+	return 0;
+
+err3:
+	gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
+err2:
+	gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
+err:
+	return ret;
+};
+
+static int z2_lbs_spi_teardown(struct spi_device *spi)
+{
+	gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 0);
+	gpio_set_value(GPIO15_ZIPITZ2_WIFI_POWER, 0);
+	gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
+	gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
+	return 0;
+
+};
+
+static struct pxa2xx_spi_chip z2_lbs_chip_info = {
+	.rx_threshold	= 8,
+	.tx_threshold	= 8,
+	.timeout	= 1000,
+	.gpio_cs	= GPIO24_ZIPITZ2_WIFI_CS,
+};
+
+static struct libertas_spi_platform_data z2_lbs_pdata = {
+	.use_dummy_writes	= 1,
+	.setup			= z2_lbs_spi_setup,
+	.teardown		= z2_lbs_spi_teardown,
+};
+
+/* LCD */
+static struct pxa2xx_spi_chip lms283_chip_info = {
+	.rx_threshold	= 1,
+	.tx_threshold	= 1,
+	.timeout	= 64,
+	.gpio_cs	= GPIO88_ZIPITZ2_LCD_CS,
+};
+
+static const struct lms283gf05_pdata lms283_pdata = {
+	.reset_gpio	= GPIO19_ZIPITZ2_LCD_RESET,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+{
+	.modalias		= "libertas_spi",
+	.platform_data		= &z2_lbs_pdata,
+	.controller_data	= &z2_lbs_chip_info,
+	.irq			= gpio_to_irq(GPIO36_ZIPITZ2_WIFI_IRQ),
+	.max_speed_hz		= 13000000,
+	.bus_num		= 1,
+	.chip_select		= 0,
+},
+{
+	.modalias		= "lms283gf05",
+	.controller_data	= &lms283_chip_info,
+	.platform_data		= &lms283_pdata,
+	.max_speed_hz		= 400000,
+	.bus_num		= 2,
+	.chip_select		= 0,
+},
+};
+
+static struct pxa2xx_spi_master pxa_ssp1_master_info = {
+	.clock_enable	= CKEN_SSP,
+	.num_chipselect	= 1,
+	.enable_dma	= 1,
+};
+
+static struct pxa2xx_spi_master pxa_ssp2_master_info = {
+	.clock_enable	= CKEN_SSP2,
+	.num_chipselect	= 1,
+};
+
+static void __init z2_spi_init(void)
+{
+	pxa2xx_set_spi_info(1, &pxa_ssp1_master_info);
+	pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+#else
+static inline void z2_spi_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init z2_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(z2_pin_config));
+
+	z2_lcd_init();
+	z2_mmc_init();
+	z2_mkp_init();
+
+	pxa_set_i2c_info(NULL);
+
+	z2_spi_init();
+	z2_nor_init();
+	z2_pwm_init();
+	z2_leds_init();
+	z2_keys_init();
+}
+
+MACHINE_START(ZIPIT2, "Zipit Z2")
+	.phys_io	= 0x40000000,
+	.boot_params	= 0xa0000100,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= z2_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 39896d8..3680f6a 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -644,7 +644,7 @@
 
 static struct pxamci_platform_data zeus_mci_platform_data = {
 	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
-	.detect_delay		= HZ/4,
+	.detect_delay_ms	= 250,
 	.gpio_card_detect       = ZEUS_MMC_CD_GPIO,
 	.gpio_card_ro           = ZEUS_MMC_WP_GPIO,
 	.gpio_card_ro_invert	= 1,
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 2b4043c..c479cbe 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -218,7 +218,7 @@
 
 #if defined(CONFIG_MMC)
 static struct pxamci_platform_data zylonite_mci_platform_data = {
-	.detect_delay	= 20,
+	.detect_delay_ms= 200,
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.gpio_card_detect = EXT_GPIO(0),
 	.gpio_card_ro	= EXT_GPIO(2),
@@ -226,7 +226,7 @@
 };
 
 static struct pxamci_platform_data zylonite_mci2_platform_data = {
-	.detect_delay	= 20,
+	.detect_delay_ms= 200,
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.gpio_card_detect = EXT_GPIO(1),
 	.gpio_card_ro	= EXT_GPIO(3),
@@ -234,7 +234,7 @@
 };
 
 static struct pxamci_platform_data zylonite_mci3_platform_data = {
-	.detect_delay	= 20,
+	.detect_delay_ms= 200,
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.gpio_card_detect = EXT_GPIO(30),
 	.gpio_card_ro	= EXT_GPIO(31),
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index e704edb..a01b76b 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-y					:= core.o clock.o
+obj-y					:= core.o
 obj-$(CONFIG_MACH_REALVIEW_EB)		+= realview_eb.o
 obj-$(CONFIG_MACH_REALVIEW_PB11MP)	+= realview_pb11mp.o
 obj-$(CONFIG_MACH_REALVIEW_PB1176)	+= realview_pb1176.o
diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c
deleted file mode 100644
index a704311..0000000
--- a/arch/arm/mach-realview/clock.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/clock.c
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-
-#include <asm/hardware/icst307.h>
-
-#include "clock.h"
-
-int clk_enable(struct clk *clk)
-{
-	return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	struct icst307_vco vco;
-	vco = icst307_khz_to_vco(clk->params, rate / 1000);
-	return icst307_khz(clk->params, vco) * 1000;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -EIO;
-
-	if (clk->setvco) {
-		struct icst307_vco vco;
-
-		vco = icst307_khz_to_vco(clk->params, rate / 1000);
-		clk->rate = icst307_khz(clk->params, vco) * 1000;
-		clk->setvco(clk, vco);
-		ret = 0;
-	}
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h
deleted file mode 100644
index ebbb0f0..0000000
--- a/arch/arm/mach-realview/clock.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/clock.h
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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.
- */
-struct module;
-struct icst307_params;
-
-struct clk {
-	unsigned long		rate;
-	const struct icst307_params *params;
-	void			*data;
-	void			(*setvco)(struct clk *, struct icst307_vco vco);
-};
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index d5a9573..595be19 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -25,8 +25,6 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
 #include <linux/io.h>
 #include <linux/smsc911x.h>
 #include <linux/ata_platform.h>
@@ -40,7 +38,7 @@
 #include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/hardware/arm_timer.h>
-#include <asm/hardware/icst307.h>
+#include <asm/hardware/icst.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
@@ -49,13 +47,12 @@
 
 #include <asm/hardware/gic.h>
 
+#include <mach/clkdev.h>
 #include <mach/platform.h>
 #include <mach/irqs.h>
+#include <plat/timer-sp.h>
 
 #include "core.h"
-#include "clock.h"
-
-#define REALVIEW_REFCOUNTER	(__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
 
 /* used by entry-macro.S and platsmp.c */
 void __iomem *gic_cpu_base_addr;
@@ -79,20 +76,6 @@
 }
 #endif
 
-/*
- * This is the RealView sched_clock implementation.  This has
- * a resolution of 41.7ns, and a maximum value of about 179s.
- */
-unsigned long long sched_clock(void)
-{
-	unsigned long long v;
-
-	v = (unsigned long long)readl(REALVIEW_REFCOUNTER) * 125;
-	do_div(v, 3);
-
-	return v;
-}
-
 
 #define REALVIEW_FLASHCTRL    (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
 
@@ -274,37 +257,40 @@
 /*
  * Clock handling
  */
-static const struct icst307_params realview_oscvco_params = {
-	.ref		= 24000,
-	.vco_max	= 200000,
+static const struct icst_params realview_oscvco_params = {
+	.ref		= 24000000,
+	.vco_max	= ICST307_VCO_MAX,
+	.vco_min	= ICST307_VCO_MIN,
 	.vd_min		= 4 + 8,
 	.vd_max		= 511 + 8,
 	.rd_min		= 1 + 2,
 	.rd_max		= 127 + 2,
+	.s2div		= icst307_s2div,
+	.idx2s		= icst307_idx2s,
 };
 
-static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
+static void realview_oscvco_set(struct clk *clk, struct icst_vco vco)
 {
 	void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
-	void __iomem *sys_osc;
 	u32 val;
 
-	if (machine_is_realview_pb1176())
-		sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET;
-	else
-		sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
-
-	val = readl(sys_osc) & ~0x7ffff;
+	val = readl(clk->vcoreg) & ~0x7ffff;
 	val |= vco.v | (vco.r << 9) | (vco.s << 16);
 
 	writel(0xa05f, sys_lock);
-	writel(val, sys_osc);
+	writel(val, clk->vcoreg);
 	writel(0, sys_lock);
 }
 
+static const struct clk_ops oscvco_clk_ops = {
+	.round	= icst_clk_round,
+	.set	= icst_clk_set,
+	.setvco	= realview_oscvco_set,
+};
+
 static struct clk oscvco_clk = {
+	.ops	= &oscvco_clk_ops,
 	.params	= &realview_oscvco_params,
-	.setvco = realview_oscvco_set,
 };
 
 /*
@@ -347,7 +333,13 @@
 
 static int __init clk_init(void)
 {
+	if (machine_is_realview_pb1176())
+		oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET;
+	else
+		oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
+
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
 	return 0;
 }
 arch_initcall(clk_init);
@@ -644,133 +636,6 @@
 void __iomem *timer3_va_base;
 
 /*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD	(TIMER_INTERVAL >> 8)
-#define TIMER_DIVISOR	(TIMER_CTRL_DIV256)
-#define TICKS2USECS(x)	(256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TIMER_RELOAD	(TIMER_INTERVAL >> 4)		/* Divide by 16 */
-#define TIMER_DIVISOR	(TIMER_CTRL_DIV16)
-#define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)
-#else
-#define TIMER_RELOAD	(TIMER_INTERVAL)
-#define TIMER_DIVISOR	(TIMER_CTRL_DIV1)
-#define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
-#endif
-
-static void timer_set_mode(enum clock_event_mode mode,
-			   struct clock_event_device *clk)
-{
-	unsigned long ctrl;
-
-	switch(mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		writel(TIMER_RELOAD, timer0_va_base + TIMER_LOAD);
-
-		ctrl = TIMER_CTRL_PERIODIC;
-		ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* period set, and timer enabled in 'next_event' hook */
-		ctrl = TIMER_CTRL_ONESHOT;
-		ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	default:
-		ctrl = 0;
-	}
-
-	writel(ctrl, timer0_va_base + TIMER_CTRL);
-}
-
-static int timer_set_next_event(unsigned long evt,
-				struct clock_event_device *unused)
-{
-	unsigned long ctrl = readl(timer0_va_base + TIMER_CTRL);
-
-	writel(evt, timer0_va_base + TIMER_LOAD);
-	writel(ctrl | TIMER_CTRL_ENABLE, timer0_va_base + TIMER_CTRL);
-
-	return 0;
-}
-
-static struct clock_event_device timer0_clockevent =	 {
-	.name		= "timer0",
-	.shift		= 32,
-	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode	= timer_set_mode,
-	.set_next_event	= timer_set_next_event,
-	.rating		= 300,
-	.cpumask	= cpu_all_mask,
-};
-
-static void __init realview_clockevents_init(unsigned int timer_irq)
-{
-	timer0_clockevent.irq = timer_irq;
-	timer0_clockevent.mult =
-		div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
-	timer0_clockevent.max_delta_ns =
-		clockevent_delta2ns(0xffffffff, &timer0_clockevent);
-	timer0_clockevent.min_delta_ns =
-		clockevent_delta2ns(0xf, &timer0_clockevent);
-
-	clockevents_register_device(&timer0_clockevent);
-}
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = &timer0_clockevent;
-
-	/* clear the interrupt */
-	writel(1, timer0_va_base + TIMER_INTCLR);
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction realview_timer_irq = {
-	.name		= "RealView Timer Tick",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= realview_timer_interrupt,
-};
-
-static cycle_t realview_get_cycles(struct clocksource *cs)
-{
-	return ~readl(timer3_va_base + TIMER_VALUE);
-}
-
-static struct clocksource clocksource_realview = {
-	.name	= "timer3",
-	.rating	= 200,
-	.read	= realview_get_cycles,
-	.mask	= CLOCKSOURCE_MASK(32),
-	.shift	= 20,
-	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static void __init realview_clocksource_init(void)
-{
-	/* setup timer 0 as free-running clocksource */
-	writel(0, timer3_va_base + TIMER_CTRL);
-	writel(0xffffffff, timer3_va_base + TIMER_LOAD);
-	writel(0xffffffff, timer3_va_base + TIMER_VALUE);
-	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
-		timer3_va_base + TIMER_CTRL);
-
-	clocksource_realview.mult =
-		clocksource_khz2mult(1000, clocksource_realview.shift);
-	clocksource_register(&clocksource_realview);
-}
-
-/*
  * Set up the clock source and clock events devices
  */
 void __init realview_timer_init(unsigned int timer_irq)
@@ -797,13 +662,8 @@
 	writel(0, timer2_va_base + TIMER_CTRL);
 	writel(0, timer3_va_base + TIMER_CTRL);
 
-	/* 
-	 * Make irqs happen for the system timer
-	 */
-	setup_irq(timer_irq, &realview_timer_irq);
-
-	realview_clocksource_init();
-	realview_clockevents_init(timer_irq);
+	sp804_clocksource_init(timer3_va_base);
+	sp804_clockevents_init(timer0_va_base, timer_irq);
 }
 
 /*
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index be048e3..f95521a 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -131,7 +131,7 @@
 	cpu_leave_lowpower();
 }
 
-int mach_cpu_disable(unsigned int cpu)
+int platform_cpu_disable(unsigned int cpu)
 {
 	/*
 	 * we don't allow CPU 0 to be shutdown (it is still too special
diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h
index 04b37a8..e58d077 100644
--- a/arch/arm/mach-realview/include/mach/clkdev.h
+++ b/arch/arm/mach-realview/include/mach/clkdev.h
@@ -1,6 +1,15 @@
 #ifndef __ASM_MACH_CLKDEV_H
 #define __ASM_MACH_CLKDEV_H
 
+#include <plat/clock.h>
+
+struct clk {
+	unsigned long		rate;
+	const struct clk_ops	*ops;
+	const struct icst_params *params;
+	void __iomem		*vcoreg;
+};
+
 #define __clk_get(clk) ({ 1; })
 #define __clk_put(clk) do { } while (0)
 
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
index 2410d4f..830055b 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pb1176.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
@@ -31,6 +31,7 @@
 #define IRQ_DC1176_SOFTINT	(IRQ_DC1176_GIC_START + 1)	/* Software interrupt */
 #define IRQ_DC1176_COMMRx	(IRQ_DC1176_GIC_START + 2)	/* Debug Comm Rx interrupt */
 #define IRQ_DC1176_COMMTx	(IRQ_DC1176_GIC_START + 3)	/* Debug Comm Tx interrupt */
+#define IRQ_DC1176_CORE_PMU	(IRQ_DC1176_GIC_START + 7)	/* Core PMU interrupt */
 #define IRQ_DC1176_TIMER0	(IRQ_DC1176_GIC_START + 8)	/* Timer 0 */
 #define IRQ_DC1176_TIMER1	(IRQ_DC1176_GIC_START + 9)	/* Timer 1 */
 #define IRQ_DC1176_TIMER2	(IRQ_DC1176_GIC_START + 10)	/* Timer 2 */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pba8.h b/arch/arm/mach-realview/include/mach/irqs-pba8.h
index 86792a9..4a88a4e 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pba8.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pba8.h
@@ -23,12 +23,6 @@
 
 #define IRQ_PBA8_GIC_START			32
 
-/* L220
-#define IRQ_PBA8_L220_EVENT	(IRQ_PBA8_GIC_START + 29)
-#define IRQ_PBA8_L220_SLAVE	(IRQ_PBA8_GIC_START + 30)
-#define IRQ_PBA8_L220_DECODE	(IRQ_PBA8_GIC_START + 31)
-*/
-
 /*
  * PB-A8 on-board gic irq sources
  */
@@ -65,6 +59,8 @@
 #define IRQ_PBA8_TSPEN		(IRQ_PBA8_GIC_START + 30)	/* Touchscreen pen */
 #define IRQ_PBA8_TSKPAD		(IRQ_PBA8_GIC_START + 31)	/* Touchscreen keypad */
 
+#define IRQ_PBA8_PMU		(IRQ_PBA8_GIC_START + 47)	/* Cortex-A8 PMU */
+
 /* ... */
 #define IRQ_PBA8_PCI0		(IRQ_PBA8_GIC_START + 50)
 #define IRQ_PBA8_PCI1		(IRQ_PBA8_GIC_START + 51)
diff --git a/arch/arm/mach-realview/include/mach/irqs-pbx.h b/arch/arm/mach-realview/include/mach/irqs-pbx.h
index deaad43..206a300 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pbx.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pbx.h
@@ -22,12 +22,6 @@
 
 #define IRQ_PBX_GIC_START			32
 
-/* L220
-#define IRQ_PBX_L220_EVENT	(IRQ_PBX_GIC_START + 29)
-#define IRQ_PBX_L220_SLAVE	(IRQ_PBX_GIC_START + 30)
-#define IRQ_PBX_L220_DECODE	(IRQ_PBX_GIC_START + 31)
-*/
-
 /*
  * PBX on-board gic irq sources
  */
@@ -77,10 +71,10 @@
 #define IRQ_PBX_TIMER4_5        (IRQ_PBX_GIC_START + 41)        /* Timer 0/1 (default timer) */
 #define IRQ_PBX_TIMER6_7        (IRQ_PBX_GIC_START + 42)        /* Timer 2/3 */
 /* ... */
-#define IRQ_PBX_PMU_CPU3        (IRQ_PBX_GIC_START + 44)        /* CPU PMU Interrupts */
-#define IRQ_PBX_PMU_CPU2        (IRQ_PBX_GIC_START + 45)
-#define IRQ_PBX_PMU_CPU1        (IRQ_PBX_GIC_START + 46)
-#define IRQ_PBX_PMU_CPU0        (IRQ_PBX_GIC_START + 47)
+#define IRQ_PBX_PMU_CPU0        (IRQ_PBX_GIC_START + 44)        /* CPU PMU Interrupts */
+#define IRQ_PBX_PMU_CPU1        (IRQ_PBX_GIC_START + 45)
+#define IRQ_PBX_PMU_CPU2        (IRQ_PBX_GIC_START + 46)
+#define IRQ_PBX_PMU_CPU3        (IRQ_PBX_GIC_START + 47)
 
 /* ... */
 #define IRQ_PBX_PCI0		(IRQ_PBX_GIC_START + 50)
diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h
index 86c0c44..1b77a27 100644
--- a/arch/arm/mach-realview/include/mach/platform.h
+++ b/arch/arm/mach-realview/include/mach/platform.h
@@ -231,12 +231,6 @@
 #define REALVIEW_INTREG_OFFSET		0x8	/* Interrupt control */
 #define REALVIEW_DECODE_OFFSET		0xC	/* Fitted logic modules */
 
-/* 
- *  Clean base - dummy
- * 
- */
-#define CLEAN_BASE                      REALVIEW_BOOT_ROM_HI
-
 /*
  * System controller bit assignment
  */
@@ -249,20 +243,6 @@
 #define REALVIEW_TIMER4_EnSel	21
 
 
-#define MAX_TIMER                       2
-#define MAX_PERIOD                      699050
-#define TICKS_PER_uSEC                  1
-
-/* 
- *  These are useconds NOT ticks.  
- * 
- */
-#define mSEC_1                          1000
-#define mSEC_5                          (mSEC_1 * 5)
-#define mSEC_10                         (mSEC_1 * 10)
-#define mSEC_25                         (mSEC_1 * 25)
-#define SEC_1                           (mSEC_1 * 1000)
-
 #define REALVIEW_CSR_BASE             0x10000000
 #define REALVIEW_CSR_SIZE             0x10000000
 
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 7d857d3..422ccd7 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -31,8 +31,8 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/hardware/gic.h>
-#include <asm/hardware/icst307.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/localtimer.h>
 
@@ -44,7 +44,6 @@
 #include <mach/irqs.h>
 
 #include "core.h"
-#include "clock.h"
 
 static struct map_desc realview_eb_io_desc[] __initdata = {
 	{
@@ -294,6 +293,36 @@
 	},
 };
 
+static struct resource pmu_resources[] = {
+	[0] = {
+		.start		= IRQ_EB11MP_PMU_CPU0,
+		.end		= IRQ_EB11MP_PMU_CPU0,
+		.flags		= IORESOURCE_IRQ,
+	},
+	[1] = {
+		.start		= IRQ_EB11MP_PMU_CPU1,
+		.end		= IRQ_EB11MP_PMU_CPU1,
+		.flags		= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start		= IRQ_EB11MP_PMU_CPU2,
+		.end		= IRQ_EB11MP_PMU_CPU2,
+		.flags		= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start		= IRQ_EB11MP_PMU_CPU3,
+		.end		= IRQ_EB11MP_PMU_CPU3,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device pmu_device = {
+	.name			= "arm-pmu",
+	.id			= ARM_PMU_DEVICE_CPU,
+	.num_resources		= ARRAY_SIZE(pmu_resources),
+	.resource		= pmu_resources,
+};
+
 static void __init gic_init_irq(void)
 {
 	if (core_tile_eb11mp() || core_tile_a9mp()) {
@@ -407,6 +436,7 @@
 		 * Bits:  .... ...0 0111 1001 0000 .... .... .... */
 		l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
 #endif
+		platform_device_register(&pmu_device);
 	}
 
 	realview_flash_register(&realview_eb_flash_resource, 1);
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 44392e5..96568eb 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -31,8 +31,8 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/hardware/gic.h>
-#include <asm/hardware/icst307.h>
 #include <asm/hardware/cache-l2x0.h>
 
 #include <asm/mach/arch.h>
@@ -44,7 +44,6 @@
 #include <mach/irqs.h>
 
 #include "core.h"
-#include "clock.h"
 
 static struct map_desc realview_pb1176_io_desc[] __initdata = {
 	{
@@ -263,6 +262,19 @@
 	},
 };
 
+static struct resource pmu_resource = {
+	.start		= IRQ_DC1176_CORE_PMU,
+	.end		= IRQ_DC1176_CORE_PMU,
+	.flags		= IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+	.name			= "arm-pmu",
+	.id			= ARM_PMU_DEVICE_CPU,
+	.num_resources		= 1,
+	.resource		= &pmu_resource,
+};
+
 static void __init gic_init_irq(void)
 {
 	/* ARM1176 DevChip GIC, primary */
@@ -324,6 +336,7 @@
 	realview_eth_register(NULL, realview_pb1176_smsc911x_resources);
 	platform_device_register(&realview_i2c_device);
 	realview_usb_register(realview_pb1176_isp1761_resources);
+	platform_device_register(&pmu_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 3e02731..7fbefbb 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -31,8 +31,8 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/hardware/gic.h>
-#include <asm/hardware/icst307.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/localtimer.h>
 
@@ -45,7 +45,6 @@
 #include <mach/irqs.h>
 
 #include "core.h"
-#include "clock.h"
 
 static struct map_desc realview_pb11mp_io_desc[] __initdata = {
 	{
@@ -260,6 +259,36 @@
 	},
 };
 
+static struct resource pmu_resources[] = {
+	[0] = {
+		.start		= IRQ_TC11MP_PMU_CPU0,
+		.end		= IRQ_TC11MP_PMU_CPU0,
+		.flags		= IORESOURCE_IRQ,
+	},
+	[1] = {
+		.start		= IRQ_TC11MP_PMU_CPU1,
+		.end		= IRQ_TC11MP_PMU_CPU1,
+		.flags		= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start		= IRQ_TC11MP_PMU_CPU2,
+		.end		= IRQ_TC11MP_PMU_CPU2,
+		.flags		= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start		= IRQ_TC11MP_PMU_CPU3,
+		.end		= IRQ_TC11MP_PMU_CPU3,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device pmu_device = {
+	.name			= "arm-pmu",
+	.id			= ARM_PMU_DEVICE_CPU,
+	.num_resources		= ARRAY_SIZE(pmu_resources),
+	.resource		= pmu_resources,
+};
+
 static void __init gic_init_irq(void)
 {
 	unsigned int pldctrl;
@@ -329,6 +358,7 @@
 	platform_device_register(&realview_i2c_device);
 	platform_device_register(&realview_cf_device);
 	realview_usb_register(realview_pb11mp_isp1761_resources);
+	platform_device_register(&pmu_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_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index fe4e25c..d3c113b 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -30,8 +30,8 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/hardware/gic.h>
-#include <asm/hardware/icst307.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -42,7 +42,6 @@
 #include <mach/irqs.h>
 
 #include "core.h"
-#include "clock.h"
 
 static struct map_desc realview_pba8_io_desc[] __initdata = {
 	{
@@ -250,6 +249,19 @@
 	},
 };
 
+static struct resource pmu_resource = {
+	.start		= IRQ_PBA8_PMU,
+	.end		= IRQ_PBA8_PMU,
+	.flags		= IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+	.name			= "arm-pmu",
+	.id			= ARM_PMU_DEVICE_CPU,
+	.num_resources		= 1,
+	.resource		= &pmu_resource,
+};
+
 static void __init gic_init_irq(void)
 {
 	/* ARM PB-A8 on-board GIC */
@@ -296,6 +308,7 @@
 	platform_device_register(&realview_i2c_device);
 	platform_device_register(&realview_cf_device);
 	realview_usb_register(realview_pba8_isp1761_resources);
+	platform_device_register(&pmu_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_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index d94857e..a235ba3 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -29,6 +29,7 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/smp_twd.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -270,6 +271,36 @@
 	},
 };
 
+static struct resource pmu_resources[] = {
+	[0] = {
+		.start		= IRQ_PBX_PMU_CPU0,
+		.end		= IRQ_PBX_PMU_CPU0,
+		.flags		= IORESOURCE_IRQ,
+	},
+	[1] = {
+		.start		= IRQ_PBX_PMU_CPU1,
+		.end		= IRQ_PBX_PMU_CPU1,
+		.flags		= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start		= IRQ_PBX_PMU_CPU2,
+		.end		= IRQ_PBX_PMU_CPU2,
+		.flags		= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start		= IRQ_PBX_PMU_CPU3,
+		.end		= IRQ_PBX_PMU_CPU3,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device pmu_device = {
+	.name			= "arm-pmu",
+	.id			= ARM_PMU_DEVICE_CPU,
+	.num_resources		= ARRAY_SIZE(pmu_resources),
+	.resource		= pmu_resources,
+};
+
 static void __init gic_init_irq(void)
 {
 	/* ARM PBX on-board GIC */
@@ -354,6 +385,7 @@
 		/* 16KB way size, 8-way associativity, parity disabled
 		 * Bits:  .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */
 		l2x0_init(l2x0_base, 0x02520000, 0xc0000fff);
+		platform_device_register(&pmu_device);
 	}
 #endif
 
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 5547318..9e5e96f 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -6,6 +6,7 @@
 	bool
 	depends on ARCH_S3C2410
 	select CPU_ARM920T
+	select S3C_GPIO_PULL_UP
 	select S3C2410_CLOCK
 	select S3C2410_GPIO
 	select CPU_LLSERIAL_S3C2410
diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c
index a3f3c7b..8cdeb14 100644
--- a/arch/arm/mach-s3c2410/h1940-bluetooth.c
+++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c
@@ -33,14 +33,15 @@
 		h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER);
 		/* Reset the chip */
 		mdelay(10);
-		s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
+
+		gpio_set_value(S3C2410_GPH(1), 1);
 		mdelay(10);
-		s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
+		gpio_set_value(S3C2410_GPH(1), 0);
 	}
 	else {
-		s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
+		gpio_set_value(S3C2410_GPH(1), 1);
 		mdelay(10);
-		s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
+		gpio_set_value(S3C2410_GPH(1), 0);
 		mdelay(10);
 		h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0);
 	}
@@ -61,15 +62,21 @@
 	struct rfkill *rfk;
 	int ret = 0;
 
+	ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
+	if (ret) {
+		dev_err(&pdev->dev, "could not get GPH1\n");\
+		return ret;
+	}
+
 	/* Configures BT serial port GPIOs */
-	s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
-	s3c2410_gpio_pullup(S3C2410_GPH(0), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
-	s3c2410_gpio_pullup(S3C2410_GPH(1), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
-	s3c2410_gpio_pullup(S3C2410_GPH(2), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
-	s3c2410_gpio_pullup(S3C2410_GPH(3), 1);
+	s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
+	s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
+	s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
+	s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
+	s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
+	s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
+	s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
 
 
 	rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
@@ -100,6 +107,7 @@
 	struct rfkill *rfk = platform_get_drvdata(pdev);
 
 	platform_set_drvdata(pdev, NULL);
+	gpio_free(S3C2410_GPH(1));
 
 	if (rfk) {
 		rfkill_unregister(rfk);
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index 08ac5f9..cf68136 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -54,7 +54,7 @@
 #define DMACH_LOW_LEVEL	(1<<28)	/* use this to specifiy hardware ch no */
 
 /* we have 4 dma channels */
-#ifndef CONFIG_CPU_S3C2443
+#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
 #define S3C_DMA_CHANNELS		(4)
 #else
 #define S3C_DMA_CHANNELS		(6)
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
index 035a493..f453c4f 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
@@ -10,14 +10,28 @@
  * published by the Free Software Foundation.
 */
 
+#ifndef __MACH_GPIO_FNS_H
+#define __MACH_GPIO_FNS_H __FILE__
+
 /* These functions are in the to-be-removed category and it is strongly
  * encouraged not to use these in new code. They will be marked deprecated
  * very soon.
  *
  * Most of the functionality can be either replaced by the gpiocfg calls
  * for the s3c platform or by the generic GPIOlib API.
+ *
+ * As of 2.6.35-rc, these will be removed, with the few drivers using them
+ * either replaced or given a wrapper until the calls can be removed.
 */
 
+#include <plat/gpio-cfg.h>
+
+static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
+{
+	/* 1:1 mapping between cfgpin and setcfg calls at the moment */
+	s3c_gpio_cfgpin(pin, cfg);
+}
+
 /* external functions for GPIO support
  *
  * These allow various different clients to access the same GPIO
@@ -25,17 +39,6 @@
  * GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
 */
 
-/* s3c2410_gpio_cfgpin
- *
- * set the configuration of the given pin to the value passed.
- *
- * eg:
- *    s3c2410_gpio_cfgpin(S3C2410_GPA(0), S3C2410_GPA0_ADDR0);
- *    s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
-*/
-
-extern void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
-
 extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
 
 /* s3c2410_gpio_getirq
@@ -73,6 +76,14 @@
 
 /* s3c2410_gpio_pullup
  *
+ * This call should be replaced with s3c_gpio_setpull().
+ *
+ * As a note, there is currently no distinction between pull-up and pull-down
+ * in the s3c24xx series devices with only an on/off configuration.
+ */
+
+/* s3c2410_gpio_pullup
+ *
  * configure the pull-up control on the given pin
  *
  * to = 1 => disable the pull-up
@@ -86,18 +97,8 @@
 
 extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
 
-/* s3c2410_gpio_getpull
- *
- * Read the state of the pull-up on a given pin
- *
- * return:
- *	< 0 => error code
- *	  0 => enabled
- *	  1 => disabled
-*/
-
-extern int s3c2410_gpio_getpull(unsigned int pin);
-
 extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
 
 extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
+
+#endif /* __MACH_GPIO_FNS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
index 2edbb9c..f3182ff 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
@@ -34,6 +34,10 @@
 #define S3C2410_GPIO_F_NR	(32)
 #define S3C2410_GPIO_G_NR	(32)
 #define S3C2410_GPIO_H_NR	(32)
+#define S3C2410_GPIO_J_NR	(32)	/* technically 16. */
+#define S3C2410_GPIO_K_NR	(32)	/* technically 16. */
+#define S3C2410_GPIO_L_NR	(32)	/* technically 15. */
+#define S3C2410_GPIO_M_NR	(32)	/* technically 2. */
 
 #if CONFIG_S3C_GPIO_SPACE != 0
 #error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment
@@ -53,6 +57,10 @@
 	S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
 	S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
 	S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
+	S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H),
+	S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J),
+	S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K),
+	S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L),
 };
 
 #endif /* __ASSEMBLY__ */
@@ -67,6 +75,10 @@
 #define S3C2410_GPF(_nr)	(S3C2410_GPIO_F_START + (_nr))
 #define S3C2410_GPG(_nr)	(S3C2410_GPIO_G_START + (_nr))
 #define S3C2410_GPH(_nr)	(S3C2410_GPIO_H_START + (_nr))
+#define S3C2410_GPJ(_nr)	(S3C2410_GPIO_J_START + (_nr))
+#define S3C2410_GPK(_nr)	(S3C2410_GPIO_K_START + (_nr))
+#define S3C2410_GPL(_nr)	(S3C2410_GPIO_L_START + (_nr))
+#define S3C2410_GPM(_nr)	(S3C2410_GPIO_M_START + (_nr))
 
 /* compatibility until drivers can be modified */
 
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
index 6c12c63..877c15e 100644
--- a/arch/arm/mach-s3c2410/include/mach/irqs.h
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -115,6 +115,26 @@
 #define IRQ_S3C2412_SDI		S3C2410_IRQSUB(13)
 #define IRQ_S3C2412_CF		S3C2410_IRQSUB(14)
 
+
+#define IRQ_S3C2416_EINT8t15	S3C2410_IRQ(5)
+#define IRQ_S3C2416_DMA		S3C2410_IRQ(17)
+#define IRQ_S3C2416_UART3	S3C2410_IRQ(18)
+#define IRQ_S3C2416_SDI1	S3C2410_IRQ(20)
+#define IRQ_S3C2416_SDI0	S3C2410_IRQ(21)
+
+#define IRQ_S3C2416_LCD2	S3C2410_IRQSUB(15)
+#define IRQ_S3C2416_LCD3	S3C2410_IRQSUB(16)
+#define IRQ_S3C2416_LCD4	S3C2410_IRQSUB(17)
+#define IRQ_S3C2416_DMA0	S3C2410_IRQSUB(18)
+#define IRQ_S3C2416_DMA1	S3C2410_IRQSUB(19)
+#define IRQ_S3C2416_DMA2	S3C2410_IRQSUB(20)
+#define IRQ_S3C2416_DMA3	S3C2410_IRQSUB(21)
+#define IRQ_S3C2416_DMA4	S3C2410_IRQSUB(22)
+#define IRQ_S3C2416_DMA5	S3C2410_IRQSUB(23)
+#define IRQ_S32416_WDT		S3C2410_IRQSUB(27)
+#define IRQ_S32416_AC97		S3C2410_IRQSUB(28)
+
+
 /* extra irqs for s3c2440 */
 
 #define IRQ_S3C2440_CAM_C	S3C2410_IRQSUB(11)	/* S3C2443 too */
@@ -130,7 +150,10 @@
 #define IRQ_S3C2443_HSMMC	S3C2410_IRQ(20)		/* IRQ_SDI */
 #define IRQ_S3C2443_NAND	S3C2410_IRQ(24)		/* reserved */
 
+#define IRQ_S3C2416_HSMMC0	S3C2410_IRQ(21)		/* S3C2416/S3C2450 */
+
 #define IRQ_HSMMC0		IRQ_S3C2443_HSMMC
+#define IRQ_HSMMC1		IRQ_S3C2416_HSMMC0
 
 #define IRQ_S3C2443_LCD1	S3C2410_IRQSUB(14)
 #define IRQ_S3C2443_LCD2	S3C2410_IRQSUB(15)
@@ -152,7 +175,7 @@
 #define IRQ_S3C2443_WDT		S3C2410_IRQSUB(27)
 #define IRQ_S3C2443_AC97	S3C2410_IRQSUB(28)
 
-#ifdef CONFIG_CPU_S3C2443
+#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
 #define NR_IRQS (IRQ_S3C2443_AC97+1)
 #else
 #define NR_IRQS (IRQ_S3C2440_AC97+1)
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index b049e61..f07d680 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -63,9 +63,9 @@
 #define S3C2440_PA_AC97	   (0x5B000000)
 #define S3C2440_SZ_AC97	   SZ_1M
 
-/* S3C2443 High-speed SD/MMC */
+/* S3C2443/S3C2416 High-speed SD/MMC */
 #define S3C2443_PA_HSMMC   (0x4A800000)
-#define S3C2443_SZ_HSMMC   (256)
+#define S3C2416_PA_HSMMC0  (0x4AC00000)
 
 /* S3C2412 memory and IO controls */
 #define S3C2412_PA_SSMC	(0x4F000000)
@@ -110,6 +110,7 @@
 #define S3C_PA_UART	    S3C24XX_PA_UART
 #define S3C_PA_USBHOST	S3C2410_PA_USBHOST
 #define S3C_PA_HSMMC0	    S3C2443_PA_HSMMC
+#define S3C_PA_HSMMC1	    S3C2416_PA_HSMMC0
 #define S3C_PA_NAND	    S3C24XX_PA_NAND
 
 #endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
index 9a0d169..3415b60 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
@@ -161,4 +161,6 @@
 
 #endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
 
+#define S3C2416_CLKDIV2		S3C2410_CLKREG(0x28)
+
 #endif /* __ASM_ARM_REGS_CLOCK */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
index 3c3853c..98fd4a0 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
@@ -19,6 +19,42 @@
 #define S3C2412_DSC1	   S3C2410_GPIOREG(0xe0)
 #endif
 
+#if defined(CONFIG_CPU_S3C2416)
+#define S3C2416_DSC0	   S3C2410_GPIOREG(0xc0)
+#define S3C2416_DSC1	   S3C2410_GPIOREG(0xc4)
+#define S3C2416_DSC2	   S3C2410_GPIOREG(0xc8)
+#define S3C2416_DSC3	   S3C2410_GPIOREG(0x110)
+
+#define S3C2416_SELECT_DSC0	(0 << 30)
+#define S3C2416_SELECT_DSC1	(1 << 30)
+#define S3C2416_SELECT_DSC2	(2 << 30)
+#define S3C2416_SELECT_DSC3	(3 << 30)
+
+#define S3C2416_DSC_GETSHIFT(x)	(x & 30)
+
+#define S3C2416_DSC0_CF		(S3C2416_SELECT_DSC0 | 28)
+#define	S3C2416_DSC0_CF_5mA	(0 << 28)
+#define	S3C2416_DSC0_CF_10mA	(1 << 28)
+#define	S3C2416_DSC0_CF_15mA	(2 << 28)
+#define	S3C2416_DSC0_CF_21mA	(3 << 28)
+#define	S3C2416_DSC0_CF_MASK	(3 << 28)
+
+#define S3C2416_DSC0_nRBE	(S3C2416_SELECT_DSC0 | 26)
+#define	S3C2416_DSC0_nRBE_5mA	(0 << 26)
+#define	S3C2416_DSC0_nRBE_10mA	(1 << 26)
+#define	S3C2416_DSC0_nRBE_15mA	(2 << 26)
+#define	S3C2416_DSC0_nRBE_21mA	(3 << 26)
+#define	S3C2416_DSC0_nRBE_MASK	(3 << 26)
+
+#define S3C2416_DSC0_nROE	(S3C2416_SELECT_DSC0 | 24)
+#define	S3C2416_DSC0_nROE_5mA	(0 << 24)
+#define	S3C2416_DSC0_nROE_10mA	(1 << 24)
+#define	S3C2416_DSC0_nROE_15mA	(2 << 24)
+#define	S3C2416_DSC0_nROE_21mA	(3 << 24)
+#define	S3C2416_DSC0_nROE_MASK	(3 << 24)
+
+#endif
+
 #if defined(CONFIG_CPU_S3C244X)
 
 #define S3C2440_DSC0	   S3C2410_GPIOREG(0xc4)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
index fd672f3..a638423 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -610,35 +610,73 @@
 #define S3C2410_GPHUP	   S3C2410_GPIOREG(0x78)
 
 #define S3C2410_GPH0_nCTS0  (0x02 << 0)
+#define S3C2416_GPH0_TXD0  (0x02 << 0)
 
 #define S3C2410_GPH1_nRTS0  (0x02 << 2)
+#define S3C2416_GPH1_RXD0  (0x02 << 2)
 
 #define S3C2410_GPH2_TXD0   (0x02 << 4)
+#define S3C2416_GPH2_TXD1   (0x02 << 4)
 
 #define S3C2410_GPH3_RXD0   (0x02 << 6)
+#define S3C2416_GPH3_RXD1   (0x02 << 6)
 
 #define S3C2410_GPH4_TXD1   (0x02 << 8)
+#define S3C2416_GPH4_TXD2   (0x02 << 8)
 
 #define S3C2410_GPH5_RXD1   (0x02 << 10)
+#define S3C2416_GPH5_RXD2   (0x02 << 10)
 
 #define S3C2410_GPH6_TXD2   (0x02 << 12)
+#define S3C2416_GPH6_TXD3   (0x02 << 12)
 #define S3C2410_GPH6_nRTS1  (0x03 << 12)
+#define S3C2416_GPH6_nRTS2  (0x03 << 12)
 
 #define S3C2410_GPH7_RXD2   (0x02 << 14)
+#define S3C2416_GPH7_RXD3   (0x02 << 14)
 #define S3C2410_GPH7_nCTS1  (0x03 << 14)
+#define S3C2416_GPH7_nCTS2  (0x03 << 14)
 
 #define S3C2410_GPH8_UCLK   (0x02 << 16)
+#define S3C2416_GPH8_nCTS0  (0x02 << 16)
 
 #define S3C2410_GPH9_CLKOUT0  (0x02 << 18)
 #define S3C2442_GPH9_nSPICS0  (0x03 << 18)
+#define S3C2416_GPH9_nRTS0    (0x02 << 18)
 
 #define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
+#define S3C2416_GPH10_nCTS1   (0x02 << 20)
+
+#define S3C2416_GPH11_nRTS1   (0x02 << 22)
+
+#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24)
+
+#define S3C2416_GPH13_CLKOUT0 (0x02 << 26)
+
+#define S3C2416_GPH14_CLKOUT1 (0x02 << 28)
 
 /* The S3C2412 and S3C2413 move the GPJ register set to after
  * GPH, which means all registers after 0x80 are now offset by 0x10
  * for the 2412/2413 from the 2410/2440/2442
 */
 
+/* S3C2443 and above */
+#define S3C2440_GPJCON	   S3C2410_GPIOREG(0xD0)
+#define S3C2440_GPJDAT	   S3C2410_GPIOREG(0xD4)
+#define S3C2440_GPJUP	   S3C2410_GPIOREG(0xD8)
+
+#define S3C2443_GPKCON	   S3C2410_GPIOREG(0xE0)
+#define S3C2443_GPKDAT	   S3C2410_GPIOREG(0xE4)
+#define S3C2443_GPKUP	   S3C2410_GPIOREG(0xE8)
+
+#define S3C2443_GPLCON	   S3C2410_GPIOREG(0xF0)
+#define S3C2443_GPLDAT	   S3C2410_GPIOREG(0xF4)
+#define S3C2443_GPLUP	   S3C2410_GPIOREG(0xF8)
+
+#define S3C2443_GPMCON	   S3C2410_GPIOREG(0x100)
+#define S3C2443_GPMDAT	   S3C2410_GPIOREG(0x104)
+#define S3C2443_GPMUP	   S3C2410_GPIOREG(0x108)
+
 /* miscellaneous control */
 #define S3C2400_MISCCR	   S3C2410_GPIOREG(0x54)
 #define S3C2410_MISCCR	   S3C2410_GPIOREG(0x80)
@@ -686,6 +724,7 @@
 #define S3C2412_MISCCR_CLK1_CLKsrc  (0<<8)
 
 #define S3C2410_MISCCR_USBSUSPND0   (1<<12)
+#define S3C2416_MISCCR_SEL_SUSPND   (1<<12)
 #define S3C2410_MISCCR_USBSUSPND1   (1<<13)
 
 #define S3C2410_MISCCR_nRSTCON	    (1<<16)
@@ -695,6 +734,9 @@
 #define S3C2410_MISCCR_nEN_SCLKE    (1<<19)	/* not 2412 */
 #define S3C2410_MISCCR_SDSLEEP	    (7<<17)
 
+#define S3C2416_MISCCR_FLT_I2C      (1<<24)
+#define S3C2416_MISCCR_HSSPI_EN2    (1<<31)
+
 /* external interrupt control... */
 /* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
  * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
@@ -762,8 +804,11 @@
 #define S3C2410_GSTATUS1_IDMASK	   (0xffff0000)
 #define S3C2410_GSTATUS1_2410	   (0x32410000)
 #define S3C2410_GSTATUS1_2412	   (0x32412001)
+#define S3C2410_GSTATUS1_2416	   (0x32416003)
 #define S3C2410_GSTATUS1_2440	   (0x32440000)
 #define S3C2410_GSTATUS1_2442	   (0x32440aaa)
+/* some 2416 CPUs report this value also */
+#define S3C2410_GSTATUS1_2450	   (0x32450003)
 
 #define S3C2410_GSTATUS2_WTRESET   (1<<2)
 #define S3C2410_GSTATUS2_OFFRESET  (1<<1)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
index 1202ca5..19575e0 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
@@ -22,85 +22,49 @@
  * pull up works like all other ports.
 */
 
-#define S3C2440_GPIO_BANKJ  (416)
-
-#define S3C2440_GPJCON	    S3C2410_GPIOREG(0xd0)
-#define S3C2440_GPJDAT	    S3C2410_GPIOREG(0xd4)
-#define S3C2440_GPJUP	    S3C2410_GPIOREG(0xd8)
-
 #define S3C2413_GPJCON		S3C2410_GPIOREG(0x80)
 #define S3C2413_GPJDAT		S3C2410_GPIOREG(0x84)
 #define S3C2413_GPJUP		S3C2410_GPIOREG(0x88)
 #define S3C2413_GPJSLPCON	S3C2410_GPIOREG(0x8C)
 
-#define S3C2440_GPJ0            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0)
-#define S3C2440_GPJ0_INP        (0x00 << 0)
 #define S3C2440_GPJ0_OUTP       (0x01 << 0)
 #define S3C2440_GPJ0_CAMDATA0   (0x02 << 0)
 
-#define S3C2440_GPJ1            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 1)
-#define S3C2440_GPJ1_INP        (0x00 << 2)
 #define S3C2440_GPJ1_OUTP       (0x01 << 2)
 #define S3C2440_GPJ1_CAMDATA1   (0x02 << 2)
 
-#define S3C2440_GPJ2            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 2)
-#define S3C2440_GPJ2_INP        (0x00 << 4)
 #define S3C2440_GPJ2_OUTP       (0x01 << 4)
 #define S3C2440_GPJ2_CAMDATA2   (0x02 << 4)
 
-#define S3C2440_GPJ3            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 3)
-#define S3C2440_GPJ3_INP        (0x00 << 6)
 #define S3C2440_GPJ3_OUTP       (0x01 << 6)
 #define S3C2440_GPJ3_CAMDATA3   (0x02 << 6)
 
-#define S3C2440_GPJ4            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 4)
-#define S3C2440_GPJ4_INP        (0x00 << 8)
 #define S3C2440_GPJ4_OUTP       (0x01 << 8)
 #define S3C2440_GPJ4_CAMDATA4   (0x02 << 8)
 
-#define S3C2440_GPJ5            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 5)
-#define S3C2440_GPJ5_INP        (0x00 << 10)
 #define S3C2440_GPJ5_OUTP       (0x01 << 10)
 #define S3C2440_GPJ5_CAMDATA5   (0x02 << 10)
 
-#define S3C2440_GPJ6            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 6)
-#define S3C2440_GPJ6_INP        (0x00 << 12)
 #define S3C2440_GPJ6_OUTP       (0x01 << 12)
 #define S3C2440_GPJ6_CAMDATA6   (0x02 << 12)
 
-#define S3C2440_GPJ7            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 7)
-#define S3C2440_GPJ7_INP        (0x00 << 14)
 #define S3C2440_GPJ7_OUTP       (0x01 << 14)
 #define S3C2440_GPJ7_CAMDATA7   (0x02 << 14)
 
-#define S3C2440_GPJ8            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 8)
-#define S3C2440_GPJ8_INP        (0x00 << 16)
 #define S3C2440_GPJ8_OUTP       (0x01 << 16)
 #define S3C2440_GPJ8_CAMPCLK    (0x02 << 16)
 
-#define S3C2440_GPJ9            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 9)
-#define S3C2440_GPJ9_INP        (0x00 << 18)
 #define S3C2440_GPJ9_OUTP       (0x01 << 18)
 #define S3C2440_GPJ9_CAMVSYNC   (0x02 << 18)
 
-#define S3C2440_GPJ10           S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 10)
-#define S3C2440_GPJ10_INP       (0x00 << 20)
 #define S3C2440_GPJ10_OUTP      (0x01 << 20)
 #define S3C2440_GPJ10_CAMHREF   (0x02 << 20)
 
-#define S3C2440_GPJ11           S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 11)
-#define S3C2440_GPJ11_INP       (0x00 << 22)
 #define S3C2440_GPJ11_OUTP      (0x01 << 22)
 #define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22)
 
-#define S3C2440_GPJ12           S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 12)
-#define S3C2440_GPJ12_INP       (0x00 << 24)
 #define S3C2440_GPJ12_OUTP      (0x01 << 24)
 #define S3C2440_GPJ12_CAMRESET  (0x02 << 24)
 
-#define S3C2443_GPJ13		S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 13)
-#define S3C2443_GPJ14		S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 14)
-#define S3C2443_GPJ15		S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 15)
-
 #endif	/* __ASM_ARCH_REGS_GPIOJ_H */
 
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-irq.h b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
index de86ee8..0f07ba3 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-irq.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
@@ -27,6 +27,16 @@
 #define S3C2410_SUBSRCPND      S3C2410_IRQREG(0x018)
 #define S3C2410_INTSUBMSK      S3C2410_IRQREG(0x01C)
 
+#define S3C2416_PRIORITY_MODE1		S3C2410_IRQREG(0x030)
+#define S3C2416_PRIORITY_UPDATE1	S3C2410_IRQREG(0x034)
+#define S3C2416_SRCPND2			S3C2410_IRQREG(0x040)
+#define S3C2416_INTMOD2			S3C2410_IRQREG(0x044)
+#define S3C2416_INTMSK2			S3C2410_IRQREG(0x048)
+#define S3C2416_INTPND2			S3C2410_IRQREG(0x050)
+#define S3C2416_INTOFFSET2		S3C2410_IRQREG(0x054)
+#define S3C2416_PRIORITY_MODE2		S3C2410_IRQREG(0x070)
+#define S3C2416_PRIORITY_UPDATE2	S3C2410_IRQREG(0x074)
+
 /* mask: 0=enable, 1=disable
  * 1 bit EINT, 4=EINT4, 23=EINT23
  * EINT0,1,2,3 are not handled here.
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
new file mode 100644
index 0000000..2f31b74
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
@@ -0,0 +1,30 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *	as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *	Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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.
+ *
+ * S3C2416 memory register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2416_MEM
+#define __ASM_ARM_REGS_S3C2416_MEM
+
+#ifndef S3C2416_MEMREG
+#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+#endif
+
+#define S3C2416_BANKCFG			S3C2416_MEMREG(0x00)
+#define S3C2416_BANKCON1		S3C2416_MEMREG(0x04)
+#define S3C2416_BANKCON2		S3C2416_MEMREG(0x08)
+#define S3C2416_BANKCON3		S3C2416_MEMREG(0x0C)
+
+#define S3C2416_REFRESH			S3C2416_MEMREG(0x10)
+#define S3C2416_TIMEOUT			S3C2416_MEMREG(0x14)
+
+#endif /*  __ASM_ARM_REGS_S3C2416_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
new file mode 100644
index 0000000..e443167
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *	as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *	Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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.
+ *
+ * S3C2416 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2416_H
+#define __ASM_ARCH_REGS_S3C2416_H "s3c2416"
+
+#define S3C2416_SWRST		(S3C24XX_VA_CLKPWR + 0x44)
+#define S3C2416_SWRST_RESET	(0x533C2416)
+
+/* see regs-power.h for the other registers in the power block. */
+
+#endif	/* __ASM_ARCH_REGS_S3C2416_H */
+
diff --git a/arch/arm/mach-s3c2410/include/mach/uncompress.h b/arch/arm/mach-s3c2410/include/mach/uncompress.h
index 72f756c..8b283f8 100644
--- a/arch/arm/mach-s3c2410/include/mach/uncompress.h
+++ b/arch/arm/mach-s3c2410/include/mach/uncompress.h
@@ -40,7 +40,9 @@
 	cpuid &= S3C2410_GSTATUS1_IDMASK;
 
 	if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
-	    cpuid == S3C2410_GSTATUS1_2442) {
+	    cpuid == S3C2410_GSTATUS1_2442 ||
+	    cpuid == S3C2410_GSTATUS1_2416 ||
+	    cpuid == S3C2410_GSTATUS1_2450) {
 		fifo_mask = S3C2440_UFSTAT_TXMASK;
 		fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
 	} else {
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 7047317..34fc05a 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -56,6 +56,7 @@
 #include <plat/iic.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/gpio-cfg.h>
 
 #ifdef CONFIG_MTD_PARTITIONS
 
@@ -225,8 +226,8 @@
 	} else {
 		enable_irq_wake(IRQ_EINT9);
 		/* configure the suspend/resume status pin */
-		s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
-		s3c2410_gpio_pullup(S3C2410_GPF(2), 0);
+		s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
+		s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP);
 	}
 }
 static void __init amlm5900_init(void)
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 02b1b622..b061ddc 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -61,6 +61,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/cpu-freq.h>
+#include <plat/gpio-cfg.h>
 #include <plat/audio-simtec.h>
 
 #include "usb-simtec.h"
@@ -216,15 +217,13 @@
 static int bast_pm_suspend(struct sys_device *sd, pm_message_t state)
 {
 	/* ensure that an nRESET is not generated on resume. */
-	s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
-
+	gpio_direction_output(S3C2410_GPA(21), 1);
 	return 0;
 }
 
 static int bast_pm_resume(struct sys_device *sd)
 {
-	s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+	s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
 	return 0;
 }
 
@@ -658,6 +657,8 @@
 	nor_simtec_init();
 	simtec_audio_add(NULL, true, &bast_audio);
 
+	WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
+	
 	s3c_cpufreq_setboard(&bast_cpufreq);
 }
 
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index fbedd07..9531b4c 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -50,6 +50,7 @@
 #include <plat/udc.h>
 #include <plat/iic.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -207,16 +208,16 @@
 {
 	gpio_request(S3C2410_GPB(0), "Backlight");
 
-	s3c2410_gpio_setpin(S3C2410_GPB(0), 0);
-	s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
-	s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+	gpio_direction_output(S3C2410_GPB(0), 0);
+	s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+	s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
 
 	return 0;
 }
 
 static void h1940_backlight_exit(struct device *dev)
 {
-	s3c2410_gpio_cfgpin(S3C2410_GPB(0), 1/*S3C2410_GPB0_OUTP*/);
+	gpio_direction_output(S3C2410_GPB(0), 1);
 }
 
 static struct platform_pwm_backlight_data backlight_data = {
@@ -245,18 +246,18 @@
 
 	if (!power) {
 		/* set to 3ec */
-		s3c2410_gpio_setpin(S3C2410_GPC(0), 0);
+		gpio_direction_output(S3C2410_GPC(0), 0);
 		/* wait for 3ac */
 		do {
-			value = s3c2410_gpio_getpin(S3C2410_GPC(6));
+			value = gpio_get_value(S3C2410_GPC(6));
 		} while (value);
 		/* set to 38c */
-		s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
+		gpio_direction_output(S3C2410_GPC(5), 0);
 	} else {
 		/* Set to 3ac */
-		s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
+		gpio_direction_output(S3C2410_GPC(5), 1);
 		/* Set to 3ad */
-		s3c2410_gpio_setpin(S3C2410_GPC(0), 1);
+		gpio_direction_output(S3C2410_GPC(0), 1);
 	}
 }
 
@@ -332,6 +333,7 @@
 	gpio_request(S3C2410_GPC(5), "LCD power");
 	gpio_request(S3C2410_GPC(6), "LCD power");
 
+	gpio_direction_input(S3C2410_GPC(6));
 
 	platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
 }
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 684710f..75a9fd3 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -86,10 +86,10 @@
 {
 	switch (cmd) {
 	case S3C2410_UDC_P_ENABLE :
-		s3c2410_gpio_setpin(S3C2410_GPB(3), 1);
+		gpio_set_value(S3C2410_GPB(3), 1);
 		break;
 	case S3C2410_UDC_P_DISABLE :
-		s3c2410_gpio_setpin(S3C2410_GPB(3), 0);
+		gpio_set_value(S3C2410_GPB(3), 0);
 		break;
 	case S3C2410_UDC_P_RESET :
 		break;
@@ -536,6 +536,9 @@
 
 		platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
 	}
+
+	WARN_ON(gpio_request(S3C2410_GPB(3), "udc pup"));
+	gpio_direction_output(S3C2410_GPB(3), 0);
 }
 
 MACHINE_START(N30, "Acer-N30")
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index 92a4ec3..d0e87b6 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -58,6 +58,7 @@
 #include <plat/iic.h>
 
 #include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/pm.h>
@@ -219,10 +220,10 @@
 {
 	switch (cs) {
 	case BITBANG_CS_ACTIVE:
-		s3c2410_gpio_setpin(S3C2410_GPB(5), 0);
+		gpio_set_value(S3C2410_GPB(5), 0);
 		break;
 	case BITBANG_CS_INACTIVE:
-		s3c2410_gpio_setpin(S3C2410_GPB(5), 1);
+		gpio_set_value(S3C2410_GPB(5), 1);
 		break;
 	}
 }
@@ -347,13 +348,14 @@
 	}
 	s3c24xx_fb_set_platdata(&qt2410_fb_info);
 
-	s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
 	s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
 
 	s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
 	s3c_i2c0_set_platdata(NULL);
 
-	s3c2410_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT);
+	WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
+	gpio_direction_output(S3C2410_GPB(5), 1);
 
 	platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
 	s3c_pm_init();
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 9051f0d..d540d79 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -357,8 +357,7 @@
 
 static void vr1000_power_off(void)
 {
-	s3c2410_gpio_cfgpin(S3C2410_GPB(9), S3C2410_GPIO_OUTPUT);
-	s3c2410_gpio_setpin(S3C2410_GPB(9), 1);
+	gpio_direction_output(S3C2410_GPB(9), 1);
 }
 
 static void __init vr1000_map_io(void)
@@ -395,6 +394,8 @@
 
 	nor_simtec_init();
 	simtec_audio_add(NULL, true, NULL);
+
+	WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
 }
 
 MACHINE_START(VR1000, "Thorcom-VR1000")
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 91ba42f..adc90a3 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
@@ -40,6 +41,10 @@
 #include <plat/clock.h>
 #include <plat/pll.h>
 
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
 /* Initial IO mappings */
 
 static struct map_desc s3c2410_iodesc[] __initdata = {
@@ -65,6 +70,9 @@
 
 void __init s3c2410_map_io(void)
 {
+	s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+	s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+
 	iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
 }
 
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 9a8c065..cef6a65 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -16,7 +16,8 @@
 config CPU_S3C2412_ONLY
 	bool
 	depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
-		   !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412
+		   !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
+		   !CPU_S3C2443 && CPU_S3C2412
 	default y if CPU_S3C2412
 
 config S3C2412_DMA
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index 14f4798..4316018 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -48,6 +48,7 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -357,8 +358,7 @@
 {
 	printk(KERN_DEBUG "%s(%d)\n", __func__, set);
 
-	s3c2410_gpio_setpin(S3C2410_GPG(13), set);
-	s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
+	gpio_set_value(S3C2410_GPG(13), set);
 }
 
 #undef LCD_UPPER_MARGIN
@@ -391,7 +391,7 @@
 
 static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs)
 {
-	s3c2410_gpio_setpin(S3C2410_GPB(7), cs ? 0 : 1);
+	gpio_set_value(S3C2410_GPB(7), cs ? 0 : 1);
 }
 
 static struct s3c2410_spigpio_info jive_lcd_spi = {
@@ -413,7 +413,7 @@
 
 static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs)
 {
-	s3c2410_gpio_setpin(S3C2410_GPH(10), cs ? 0 : 1);
+	gpio_set_value(S3C2410_GPH(10), cs ? 0 : 1);
 }
 
 static struct s3c2410_spigpio_info jive_wm8750_spi = {
@@ -531,7 +531,7 @@
 	printk(KERN_INFO "powering system down...\n");
 
 	s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
 }
 
 static void __init jive_machine_init(void)
@@ -636,22 +636,22 @@
 
 	/* initialise the spi */
 
-	s3c2410_gpio_setpin(S3C2410_GPG(13), 0);
-	s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
+	gpio_request(S3C2410_GPG(13), "lcm reset");
+	gpio_direction_output(S3C2410_GPG(13), 0);
 
-	s3c2410_gpio_setpin(S3C2410_GPB(7), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPB(7), S3C2410_GPIO_OUTPUT);
+	gpio_request(S3C2410_GPB(7), "jive spi");
+	gpio_direction_output(S3C2410_GPB(7), 1);
 
 	s3c2410_gpio_setpin(S3C2410_GPB(6), 0);
-	s3c2410_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
 
 	s3c2410_gpio_setpin(S3C2410_GPG(8), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
 
 	/* initialise the WM8750 spi */
 
-	s3c2410_gpio_setpin(S3C2410_GPH(10), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPH(10), S3C2410_GPIO_OUTPUT);
+	gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
+	gpio_direction_output(S3C2410_GPH(10), 1);
 
 	/* Turn off suspend on both USB ports, and switch the
 	 * selectable USB port to USB device mode. */
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index 0392065..faddb36 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -85,10 +85,10 @@
 	switch (cmd)
 	{
 		case S3C2410_UDC_P_ENABLE :
-			s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
+			gpio_set_value(S3C2410_GPF(2), 1);
 			break;
 		case S3C2410_UDC_P_DISABLE :
-			s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
+			gpio_set_value(S3C2410_GPF(2), 0);
 			break;
 		case S3C2410_UDC_P_RESET :
 			break;
@@ -134,8 +134,8 @@
 {	/* Turn off suspend on both USB ports, and switch the
 	 * selectable USB port to USB device mode. */
 
-	s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
-	s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
+	WARN_ON(gpio_request(S3C2410_GPF(2), "udc pull"));
+	gpio_direction_output(S3C2410_GPF(2), 0);
 
 	s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
 			      S3C2410_MISCCR_USBSUSPND0 |
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
new file mode 100644
index 0000000..29103a6
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -0,0 +1,38 @@
+# arch/arm/mach-s3c2416/Kconfig
+#
+# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+#
+# Licensed under GPLv2
+
+# note, this also supports the S3C2450 which is so similar it has the same
+# ID code as the S3C2416.
+
+config CPU_S3C2416
+	bool
+	depends on ARCH_S3C2410
+	select CPU_ARM926T
+	select S3C2416_DMA if S3C2410_DMA
+	select CPU_LLSERIAL_S3C2440
+	select S3C_GPIO_PULL_UPDOWN
+	select SAMSUNG_CLKSRC
+	select S3C2443_CLOCK
+	help
+	  Support for the S3C2416 SoC from the S3C24XX line
+
+config S3C2416_DMA
+	bool
+	depends on CPU_S3C2416
+	help
+	  Internal config node for S3C2416 DMA support
+
+menu "S3C2416 Machines"
+
+config MACH_SMDK2416
+	bool "SMDK2416"
+	select CPU_S3C2416
+	select S3C_DEV_HSMMC
+	select S3C_DEV_HSMMC1
+	help
+	  Say Y here if you are using an SMDK2416
+
+endmenu
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
new file mode 100644
index 0000000..6c12c7b
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Makefile
@@ -0,0 +1,19 @@
+# arch/arm/mach-s3c2416/Makefile
+#
+# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o clock.o
+obj-$(CONFIG_CPU_S3C2416)	+= irq.o
+
+#obj-$(CONFIG_S3C2416_DMA)	+= dma.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_SMDK2416)	+= mach-smdk2416.o
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
new file mode 100644
index 0000000..7ccf5a2
--- /dev/null
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -0,0 +1,135 @@
+/* linux/arch/arm/mach-s3c2416/clock.c
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * S3C2416 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <plat/s3c2416.h>
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/pll6553x.h>
+#include <plat/pll.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-s3c2443-clock.h>
+
+static unsigned int armdiv[8] = {
+	[0] = 1,
+	[1] = 2,
+	[2] = 3,
+	[3] = 4,
+	[5] = 6,
+	[7] = 8,
+};
+
+/* ID to hardware numbering, 0 is HSMMC1, 1 is HSMMC0 */
+static struct clksrc_clk hsmmc_div[] = {
+	[0] = {
+		.clk = {
+			.name	= "hsmmc-div",
+			.id	= 1,
+			.parent	= &clk_esysclk.clk,
+		},
+		.reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
+	},
+	[1] = {
+		.clk = {
+			.name	= "hsmmc-div",
+			.id	= 0,
+			.parent	= &clk_esysclk.clk,
+		},
+		.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
+	},
+};
+
+static struct clksrc_clk hsmmc_mux[] = {
+	[0] = {
+		.clk	= {
+			.id	= 1,
+			.name	= "hsmmc-if",
+			.ctrlbit = (1 << 6),
+			.enable = s3c2443_clkcon_enable_s,
+		},
+		.sources = &(struct clksrc_sources) {
+			.nr_sources = 2,
+			.sources = (struct clk *[]) {
+				[0] = &hsmmc_div[0].clk,
+				[1] = NULL, /* to fix */
+			},
+		},
+		.reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
+	},
+	[1] = {
+		.clk	= {
+			.id	= 0,
+			.name	= "hsmmc-if",
+			.ctrlbit = (1 << 12),
+			.enable = s3c2443_clkcon_enable_s,
+		},
+		.sources = &(struct clksrc_sources) {
+			.nr_sources = 2,
+			.sources = (struct clk *[]) {
+				[0] = &hsmmc_div[1].clk,
+				[1] = NULL, /* to fix */
+			},
+		},
+		.reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
+	},
+};
+
+
+static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
+{
+	clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+
+	return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+}
+
+void __init_or_cpufreq s3c2416_setup_clocks(void)
+{
+	s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div);
+}
+
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+	&hsmmc_div[0],
+	&hsmmc_div[1],
+	&hsmmc_mux[0],
+	&hsmmc_mux[1],
+};
+
+void __init s3c2416_init_clocks(int xtal)
+{
+	u32 epllcon = __raw_readl(S3C2443_EPLLCON);
+	u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
+	int ptr;
+
+	/* s3c2416 EPLL compatible with s3c64xx */
+	clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
+
+	clk_epll.parent = &clk_epllref.clk;
+
+	s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div);
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+		s3c_register_clksrc(clksrcs[ptr], 1);
+
+	s3c_pwmclk_init();
+
+}
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
new file mode 100644
index 0000000..89f521d
--- /dev/null
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -0,0 +1,254 @@
+/* linux/arch/arm/mach-s3c2416/irq.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *	as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *	Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
+{
+	unsigned int subsrc, submsk;
+	unsigned int end;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc  &= ~submsk;
+	subsrc >>= (irq - S3C2410_IRQSUB(0));
+	subsrc  &= (1 << len)-1;
+
+	end = len + irq;
+
+	for (; irq < end && subsrc; irq++) {
+		if (subsrc & 1)
+			generic_handle_irq(irq);
+
+		subsrc >>= 1;
+	}
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97	(1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97	INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2416_irq_wdtac97_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2416_irq_wdtac97 = {
+	.mask	    = s3c2416_irq_wdtac97_mask,
+	.unmask	    = s3c2416_irq_wdtac97_unmask,
+	.ack	    = s3c2416_irq_wdtac97_ack,
+};
+
+
+/* LCD sub interrupts */
+
+static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD	(1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD	INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2416_irq_lcd_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2416_irq_lcd = {
+	.mask	    = s3c2416_irq_lcd_mask,
+	.unmask	    = s3c2416_irq_lcd_unmask,
+	.ack	    = s3c2416_irq_lcd_ack,
+};
+
+
+/* DMA sub interrupts */
+
+static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA	INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+
+static void s3c2416_irq_dma_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2416_irq_dma_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_DMA);
+}
+
+static void s3c2416_irq_dma_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2416_irq_dma = {
+	.mask	    = s3c2416_irq_dma_mask,
+	.unmask	    = s3c2416_irq_dma_unmask,
+	.ack	    = s3c2416_irq_dma_ack,
+};
+
+
+/* UART3 sub interrupts */
+
+static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+	s3c2416_irq_demux(IRQ_S3C2443_UART3, 3);
+}
+
+#define INTMSK_UART3	(1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3	(0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+
+static void s3c2416_irq_uart3_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2416_irq_uart3 = {
+	.mask	    = s3c2416_irq_uart3_mask,
+	.unmask	    = s3c2416_irq_uart3_unmask,
+	.ack	    = s3c2416_irq_uart3_ack,
+};
+
+
+/* IRQ initialisation code */
+
+static int __init s3c2416_add_sub(unsigned int base,
+				   void (*demux)(unsigned int,
+						 struct irq_desc *),
+				   struct irq_chip *chip,
+				   unsigned int start, unsigned int end)
+{
+	unsigned int irqno;
+
+	set_irq_chip(base, &s3c_irq_level_chip);
+	set_irq_handler(base, handle_level_irq);
+	set_irq_chained_handler(base, demux);
+
+	for (irqno = start; irqno <= end; irqno++) {
+		set_irq_chip(irqno, chip);
+		set_irq_handler(irqno, handle_level_irq);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static int __init s3c2416_irq_add(struct sys_device *sysdev)
+{
+	printk(KERN_INFO "S3C2416: IRQ Support\n");
+
+	s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
+			IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
+
+	s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
+			&s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+	s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
+			&s3c2416_irq_uart3,
+			IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+	s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
+			&s3c2416_irq_wdtac97,
+			IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2416_irq_driver = {
+	.add		= s3c2416_irq_add,
+};
+
+static int __init s3c2416_irq_init(void)
+{
+	return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_irq_driver);
+}
+
+arch_initcall(s3c2416_irq_init);
+
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
new file mode 100644
index 0000000..99d24c4
--- /dev/null
+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
@@ -0,0 +1,150 @@
+/* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *	as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *	Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+#include <mach/leds-gpio.h>
+#include <plat/iic.h>
+
+#include <plat/s3c2416.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/nand.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2416_iodesc[] __initdata = {
+	/* ISA IO Space map (memory space selected by A24) */
+
+	{
+		.virtual	= (u32)S3C24XX_VA_ISA_WORD,
+		.pfn		= __phys_to_pfn(S3C2410_CS2),
+		.length		= 0x10000,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+		.pfn		= __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+		.length		= SZ_4M,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_BYTE,
+		.pfn		= __phys_to_pfn(S3C2410_CS2),
+		.length		= 0x10000,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+		.pfn		= __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+		.length		= SZ_4M,
+		.type		= MT_DEVICE,
+	}
+};
+
+#define UCON (S3C2410_UCON_DEFAULT	| \
+		S3C2440_UCON_PCLK	| \
+		S3C2443_UCON_RXERR_IRQEN)
+
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+
+#define UFCON (S3C2410_UFCON_RXTRIG8	| \
+		S3C2410_UFCON_FIFOMODE	| \
+		S3C2440_UFCON_TXTRIG16)
+
+static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	/* IR port */
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON | 0x50,
+		.ufcon	     = UFCON,
+	}
+};
+
+static struct platform_device *smdk2416_devices[] __initdata = {
+	&s3c_device_wdt,
+	&s3c_device_ohci,
+	&s3c_device_i2c0,
+	&s3c_device_hsmmc0,
+	&s3c_device_hsmmc1,
+};
+
+static void __init smdk2416_map_io(void)
+{
+
+	s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
+
+}
+
+static void __init smdk2416_machine_init(void)
+{
+	s3c_i2c0_set_platdata(NULL);
+
+	gpio_request(S3C2410_GPB(4), "USBHost Power");
+	gpio_direction_output(S3C2410_GPB(4), 1);
+
+	platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
+	smdk_machine_init();
+}
+
+MACHINE_START(SMDK2416, "SMDK2416")
+	/* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+
+	.init_irq	= s3c24xx_init_irq,
+	.map_io		= smdk2416_map_io,
+	.init_machine	= smdk2416_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
new file mode 100644
index 0000000..3bff057
--- /dev/null
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -0,0 +1,128 @@
+/* linux/arch/arm/mach-s3c2416/s3c2416.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *	as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *	Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * Samsung S3C2416 Mobile CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <mach/reset.h>
+#include <mach/idle.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/s3c2416.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/iic-core.h>
+
+static struct map_desc s3c2416_iodesc[] __initdata = {
+	IODESC_ENT(WATCHDOG),
+	IODESC_ENT(CLKPWR),
+	IODESC_ENT(TIMER),
+};
+
+struct sysdev_class s3c2416_sysclass = {
+	.name = "s3c2416-core",
+};
+
+static struct sys_device s3c2416_sysdev = {
+	.cls		= &s3c2416_sysclass,
+};
+
+static void s3c2416_hard_reset(void)
+{
+	__raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
+}
+
+int __init s3c2416_init(void)
+{
+	printk(KERN_INFO "S3C2416: Initializing architecture\n");
+
+	s3c24xx_reset_hook = s3c2416_hard_reset;
+	/* s3c24xx_idle = s3c2416_idle;	*/
+
+	/* change WDT IRQ number */
+	s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
+	s3c_device_wdt.resource[1].end   = IRQ_S3C2443_WDT;
+
+	/* the i2c devices are directly compatible with s3c2440 */
+	s3c_i2c0_setname("s3c2440-i2c");
+	s3c_i2c1_setname("s3c2440-i2c");
+
+	return sysdev_register(&s3c2416_sysdev);
+}
+
+void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+
+	s3c_device_nand.name = "s3c2416-nand";
+}
+
+/* s3c2416_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2416_map_io(void)
+{
+	s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown;
+	s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown;
+
+	iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2416 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2416_core_init(void)
+{
+	return sysdev_class_register(&s3c2416_sysclass);
+}
+
+core_initcall(s3c2416_core_init);
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 7f46526..9d102b9 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -6,6 +6,7 @@
 	bool
 	depends on ARCH_S3C2410
 	select CPU_ARM920T
+	select S3C_GPIO_PULL_UP
 	select S3C2410_CLOCK
 	select S3C2410_PM if PM
 	select S3C2410_GPIO
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
index 571b176..a76bcda 100644
--- a/arch/arm/mach-s3c2440/mach-mini2440.c
+++ b/arch/arm/mach-s3c2440/mach-mini2440.c
@@ -53,6 +53,7 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -102,10 +103,10 @@
 
 	switch (cmd) {
 		case S3C2410_UDC_P_ENABLE :
-			s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
+			gpio_set_value(S3C2410_GPC(5), 1);
 			break;
 		case S3C2410_UDC_P_DISABLE :
-			s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
+			gpio_set_value(S3C2410_GPC(5), 0);
 			break;
 		case S3C2410_UDC_P_RESET :
 			break;
@@ -632,25 +633,25 @@
 	mini2440_parse_features(&features, mini2440_features_str);
 
 	/* turn LCD on */
-	s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
+	s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
 
 	/* Turn the backlight early on */
-	s3c2410_gpio_setpin(S3C2410_GPG(4), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT);
+	WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));
+	gpio_direction_output(S3C2410_GPG(4), 1);
 
 	/* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
-	s3c2410_gpio_pullup(S3C2410_GPB(1), 0);
+	s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
 	s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
-	s3c2410_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
+	s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
 
 	/* Make sure the D+ pullup pin is output */
-	s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
+	WARN_ON(gpio_request(S3C2410_GPC(5), "udc pup"));
+	gpio_direction_output(S3C2410_GPC(5), 0);
 
 	/* mark the key as input, without pullups (there is one on the board) */
 	for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
-		s3c2410_gpio_pullup(mini2440_buttons[i].gpio, 0);
-		s3c2410_gpio_cfgpin(mini2440_buttons[i].gpio,
-					S3C2410_GPIO_INPUT);
+		s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
+		s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
 	}
 	if (features.lcd_index != -1) {
 		int li;
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index 3420415..3ff62de 100644
--- a/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -40,6 +40,7 @@
 #include <plat/regs-serial.h>
 #include <plat/iic.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/s3c2410.h>
 #include <plat/s3c244x.h>
 #include <plat/clock.h>
@@ -122,15 +123,15 @@
 {
 	// Initialize SCCB bus
 	s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
-	s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
 	s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
-	s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
 
 	// Power up the sensor board
 	s3c2410_gpio_setpin(S3C2410_GPF(1), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
+	s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
 	s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
-	s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
+	s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
 }
 
 static void __init nexcoder_map_io(void)
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index f35371d..319458d 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -49,6 +49,7 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -298,7 +299,7 @@
 
 	/* ensure that an nRESET is not generated on resume. */
 	s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
-	s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
 
 	return 0;
 }
@@ -310,7 +311,7 @@
 
 	__raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
 
-	s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+	s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
 
 	return 0;
 }
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index 2b68f7e..d50f3ae 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
+#include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
@@ -33,6 +34,10 @@
 #include <plat/cpu.h>
 #include <plat/s3c244x.h>
 
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
 static struct sys_device s3c2440_sysdev = {
 	.cls		= &s3c2440_sysclass,
 };
@@ -41,6 +46,9 @@
 {
 	printk("S3C2440: Initialising architecture\n");
 
+	s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+	s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+
 	/* change irq for watchdog */
 
 	s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
index 698140a..4fef723 100644
--- a/arch/arm/mach-s3c2443/Kconfig
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -8,6 +8,7 @@
 	select S3C2443_DMA if S3C2410_DMA
 	select CPU_LLSERIAL_S3C2440
 	select SAMSUNG_CLKSRC
+	select S3C2443_CLOCK
 	help
 	  Support for the S3C2443 SoC from the S3C24XX line
 
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 62cd4ea..83b1aa6 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -21,6 +21,7 @@
 */
 
 #include <linux/init.h>
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -54,111 +55,13 @@
  * set the correct muxing at initialisation
 */
 
-static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
-{
-	u32 ctrlbit = clk->ctrlbit;
-	u32 con = __raw_readl(reg);
-
-	if (enable)
-		con |= ctrlbit;
-	else
-		con &= ~ctrlbit;
-
-	__raw_writel(con, reg);
-	return 0;
-}
-
-static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
-{
-	return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
-}
-
-static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
-{
-	return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
-}
-
-static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
-{
-	return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
-}
-
 /* clock selections */
 
-/* mpllref is a direct descendant of clk_xtal by default, but it is not
- * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
- * such directly equating the two source clocks is impossible.
- */
-static struct clk clk_mpllref = {
-	.name		= "mpllref",
-	.parent		= &clk_xtal,
-	.id		= -1,
-};
-
 static struct clk clk_i2s_ext = {
 	.name		= "i2s-ext",
 	.id		= -1,
 };
 
-static struct clk *clk_epllref_sources[] = {
-	[0] = &clk_mpllref,
-	[1] = &clk_mpllref,
-	[2] = &clk_xtal,
-	[3] = &clk_ext,
-};
-
-static struct clksrc_clk clk_epllref = {
-	.clk	= {
-		.name		= "epllref",
-		.id		= -1,
-	},
-	.sources = &(struct clksrc_sources) {
-		.sources = clk_epllref_sources,
-		.nr_sources = ARRAY_SIZE(clk_epllref_sources),
-	},
-	.reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
-};
-
-static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long div = __raw_readl(S3C2443_CLKDIV0);
-
-	div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
-	div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);	/* x2 */
-
-	return parent_rate / (div + 1);
-}
-
-static struct clk clk_mdivclk = {
-	.name		= "mdivclk",
-	.parent		= &clk_mpllref,
-	.id		= -1,
-	.ops		= &(struct clk_ops) {
-		.get_rate	= s3c2443_getrate_mdivclk,
-	},
-};
-
-static struct clk *clk_msysclk_sources[] = {
-	[0] = &clk_mpllref,
-	[1] = &clk_mpll,
-	[2] = &clk_mdivclk,
-	[3] = &clk_mpllref,
-};
-
-static struct clksrc_clk clk_msysclk = {
-	.clk	= {
-		.name		= "msysclk",
-		.parent		= &clk_xtal,
-		.id		= -1,
-	},
-	.sources = &(struct clksrc_sources) {
-		.sources = clk_msysclk_sources,
-		.nr_sources = ARRAY_SIZE(clk_msysclk_sources),
-	},
-	.reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
-};
-
 /* armdiv
  *
  * this clock is sourced from msysclk and can have a number of
@@ -266,44 +169,6 @@
 	.reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
 };
 
-/* esysclk
- *
- * this is sourced from either the EPLL or the EPLLref clock
-*/
-
-static struct clk *clk_sysclk_sources[] = {
-	[0] = &clk_epllref.clk,
-	[1] = &clk_epll,
-};
-
-static struct clksrc_clk clk_esysclk = {
-	.clk	= {
-		.name		= "esysclk",
-		.parent		= &clk_epll,
-		.id		= -1,
-	},
-	.sources = &(struct clksrc_sources) {
-		.sources = clk_sysclk_sources,
-		.nr_sources = ARRAY_SIZE(clk_sysclk_sources),
-	},
-	.reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
-};
-
-/* uartclk
- *
- * UART baud-rate clock sourced from esysclk via a divisor
-*/
-
-static struct clksrc_clk clk_uart = {
-	.clk	= {
-		.name		= "uartclk",
-		.id		= -1,
-		.parent		= &clk_esysclk.clk,
-	},
-	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
-};
-
-
 /* hsspi
  *
  * high-speed spi clock, sourced from esysclk
@@ -320,21 +185,6 @@
 	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
 };
 
-/* usbhost
- *
- * usb host bus-clock, usually 48MHz to provide USB bus clock timing
-*/
-
-static struct clksrc_clk clk_usb_bus_host = {
-	.clk	= {
-		.name		= "usb-bus-host-parent",
-		.id		= -1,
-		.parent		= &clk_esysclk.clk,
-		.ctrlbit	= S3C2443_SCLKCON_USBHOST,
-		.enable		= s3c2443_clkcon_enable_s,
-	},
-	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
-};
 
 /* clk_hsmcc_div
  *
@@ -433,89 +283,16 @@
 	.reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
 };
 
-/* cam-if
- *
- * camera interface bus-clock, divided down from esysclk
-*/
-
-static struct clksrc_clk clk_cam = {
-	.clk	= {
-		.name		= "camif-upll",	/* same as 2440 name */
-		.id		= -1,
-		.parent		= &clk_esysclk.clk,
-		.ctrlbit	= S3C2443_SCLKCON_CAMCLK,
-		.enable		= s3c2443_clkcon_enable_s,
-	},
-	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
-};
-
-/* display-if
- *
- * display interface clock, divided from esysclk
-*/
-
-static struct clksrc_clk clk_display = {
-	.clk	= {
-		.name		= "display-if",
-		.id		= -1,
-		.parent		= &clk_esysclk.clk,
-		.ctrlbit	= S3C2443_SCLKCON_DISPCLK,
-		.enable		= s3c2443_clkcon_enable_s,
-	},
-	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
-};
-
-/* prediv
- *
- * this divides the msysclk down to pass to h/p/etc.
- */
-
-static unsigned long s3c2443_prediv_getrate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
-
-	clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
-	clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
-
-	return rate / (clkdiv0 + 1);
-}
-
-static struct clk clk_prediv = {
-	.name		= "prediv",
-	.id		= -1,
-	.parent		= &clk_msysclk.clk,
-	.ops		= &(struct clk_ops) {
-		.get_rate	= s3c2443_prediv_getrate,
-	},
-};
-
 /* standard clock definitions */
 
-static struct clk init_clocks_disable[] = {
+static struct clk init_clocks_off[] = {
 	{
-		.name		= "nand",
-		.id		= -1,
-		.parent		= &clk_h,
-	}, {
 		.name		= "sdi",
 		.id		= -1,
 		.parent		= &clk_p,
 		.enable		= s3c2443_clkcon_enable_p,
 		.ctrlbit	= S3C2443_PCLKCON_SDI,
 	}, {
-		.name		= "adc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2443_clkcon_enable_p,
-		.ctrlbit	= S3C2443_PCLKCON_ADC,
-	}, {
-		.name		= "i2c",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2443_clkcon_enable_p,
-		.ctrlbit	= S3C2443_PCLKCON_IIC,
-	}, {
 		.name		= "iis",
 		.id		= -1,
 		.parent		= &clk_p,
@@ -537,179 +314,12 @@
 };
 
 static struct clk init_clocks[] = {
-	{
-		.name		= "dma",
-		.id		= 0,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_DMA0,
-	}, {
-		.name		= "dma",
-		.id		= 1,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_DMA1,
-	}, {
-		.name		= "dma",
-		.id		= 2,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_DMA2,
-	}, {
-		.name		= "dma",
-		.id		= 3,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_DMA3,
-	}, {
-		.name		= "dma",
-		.id		= 4,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_DMA4,
-	}, {
-		.name		= "dma",
-		.id		= 5,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_DMA5,
-	}, {
-		.name		= "lcd",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_LCDC,
-	}, {
-		.name		= "gpio",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2443_clkcon_enable_p,
-		.ctrlbit	= S3C2443_PCLKCON_GPIO,
-	}, {
-		.name		= "usb-host",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_USBH,
-	}, {
-		.name		= "usb-device",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_USBD,
-	}, {
-		.name		= "hsmmc",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_HSMMC,
-	}, {
-		.name		= "cfc",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_CFC,
-	}, {
-		.name		= "ssmc",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s3c2443_clkcon_enable_h,
-		.ctrlbit	= S3C2443_HCLKCON_SSMC,
-	}, {
-		.name		= "timers",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2443_clkcon_enable_p,
-		.ctrlbit	= S3C2443_PCLKCON_PWMT,
-	}, {
-		.name		= "uart",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s3c2443_clkcon_enable_p,
-		.ctrlbit	= S3C2443_PCLKCON_UART0,
-	}, {
-		.name		= "uart",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s3c2443_clkcon_enable_p,
-		.ctrlbit	= S3C2443_PCLKCON_UART1,
-	}, {
-		.name		= "uart",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s3c2443_clkcon_enable_p,
-		.ctrlbit	= S3C2443_PCLKCON_UART2,
-	}, {
-		.name		= "uart",
-		.id		= 3,
-		.parent		= &clk_p,
-		.enable		= s3c2443_clkcon_enable_p,
-		.ctrlbit	= S3C2443_PCLKCON_UART3,
-	}, {
-		.name		= "rtc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s3c2443_clkcon_enable_p,
-		.ctrlbit	= S3C2443_PCLKCON_RTC,
-	}, {
-		.name		= "watchdog",
-		.id		= -1,
-		.parent		= &clk_p,
-		.ctrlbit	= S3C2443_PCLKCON_WDT,
-	}, {
-		.name		= "usb-bus-host",
-		.id		= -1,
-		.parent		= &clk_usb_bus_host.clk,
-	}, {
-		.name		= "ac97",
-		.id		= -1,
-		.parent		= &clk_p,
-		.ctrlbit	= S3C2443_PCLKCON_AC97,
-	}
 };
 
-/* clocks to add where we need to check their parentage */
-
-static struct clksrc_clk __initdata *init_list[] = {
-	&clk_epllref, /* should be first */
-	&clk_esysclk,
-	&clk_msysclk,
-	&clk_arm,
-	&clk_i2s_eplldiv,
-	&clk_i2s,
-	&clk_cam,
-	&clk_uart,
-	&clk_display,
-	&clk_hsmmc_div,
-	&clk_usb_bus_host,
-};
-
-static void __init s3c2443_clk_initparents(void)
-{
-	int ptr;
-
-	for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++)
-		s3c_set_clksrc(init_list[ptr], true);
-}
-
-static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
-{
-	clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
-
-	return clkcon0 + 1;
-}
-
 /* clocks to add straight away */
 
 static struct clksrc_clk *clksrcs[] __initdata = {
-	&clk_usb_bus_host,
-	&clk_epllref,
-	&clk_esysclk,
-	&clk_msysclk,
 	&clk_arm,
-	&clk_uart,
-	&clk_display,
-	&clk_cam,
 	&clk_i2s_eplldiv,
 	&clk_i2s,
 	&clk_hsspi,
@@ -717,91 +327,31 @@
 };
 
 static struct clk *clks[] __initdata = {
-	&clk_ext,
-	&clk_epll,
-	&clk_usb_bus,
-	&clk_mpllref,
 	&clk_hsmmc,
 	&clk_armdiv,
-	&clk_prediv,
 };
 
 void __init_or_cpufreq s3c2443_setup_clocks(void)
 {
-	unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
-	unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
-	struct clk *xtal_clk;
-	unsigned long xtal;
-	unsigned long pll;
-	unsigned long fclk;
-	unsigned long hclk;
-	unsigned long pclk;
-
-	xtal_clk = clk_get(NULL, "xtal");
-	xtal = clk_get_rate(xtal_clk);
-	clk_put(xtal_clk);
-
-	pll = s3c2443_get_mpll(mpllcon, xtal);
-	clk_msysclk.clk.rate = pll;
-
-	fclk = pll / s3c2443_fclk_div(clkdiv0);
-	hclk = s3c2443_prediv_getrate(&clk_prediv);
-	hclk /= s3c2443_get_hdiv(clkdiv0);
- 	pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
-
-	s3c24xx_setup_clocks(fclk, hclk, pclk);
-
-	printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
-	       (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
-	       print_mhz(pll), print_mhz(fclk),
-	       print_mhz(hclk), print_mhz(pclk));
-
-	s3c24xx_setup_clocks(fclk, hclk, pclk);
+	s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div);
 }
 
 void __init s3c2443_init_clocks(int xtal)
 {
-	struct clk *clkp;
 	unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
-	int ret;
 	int ptr;
 
-	/* s3c2443 parents h and p clocks from prediv */
-	clk_h.parent = &clk_prediv;
-	clk_p.parent = &clk_prediv;
-
-	s3c24xx_register_baseclocks(xtal);
-	s3c2443_setup_clocks();
-	s3c2443_clk_initparents();
-
-	for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
-		clkp = clks[ptr];
-
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
-
-	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
-		s3c_register_clksrc(clksrcs[ptr], 1);
-
 	clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
 	clk_epll.parent = &clk_epllref.clk;
-	clk_usb_bus.parent = &clk_usb_bus_host.clk;
 
-	/* ensure usb bus clock is within correct rate of 48MHz */
+	s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div);
 
-	if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
-		printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
-		clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
-	}
+	s3c2443_setup_clocks();
 
-	printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
-	       (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
-	       print_mhz(clk_get_rate(&clk_epll)),
-	       print_mhz(clk_get_rate(&clk_usb_bus)));
+	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+		s3c_register_clksrc(clksrcs[ptr], 1);
 
 	/* register clocks from clock array */
 
@@ -819,17 +369,8 @@
 
 	/* install (and disable) the clocks we do not need immediately */
 
-	clkp = init_clocks_disable;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-
-		(clkp->enable)(clkp, 0);
-	}
+	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
 	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
index 66e6794..60c929a 100644
--- a/arch/arm/mach-s3c64xx/gpiolib.c
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -51,6 +51,7 @@
 
 static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
 	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.get_config	= s3c_gpio_getcfg_s3c64xx_4bit,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
 };
@@ -58,12 +59,14 @@
 static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
 	.cfg_eint	= 7,
 	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.get_config	= s3c_gpio_getcfg_s3c64xx_4bit,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
 };
 
 static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
 	.cfg_eint	= 3,
+	.get_config	= s3c_gpio_getcfg_s3c64xx_4bit,
 	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
@@ -171,6 +174,7 @@
 
 static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
 	.set_config	= s3c_gpio_setcfg_s3c24xx,
+	.get_config	= s3c_gpio_getcfg_s3c24xx,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
 };
@@ -178,6 +182,7 @@
 static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
 	.cfg_eint	= 2,
 	.set_config	= s3c_gpio_setcfg_s3c24xx,
+	.get_config	= s3c_gpio_getcfg_s3c24xx,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
 };
@@ -185,6 +190,7 @@
 static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
 	.cfg_eint	= 3,
 	.set_config	= s3c_gpio_setcfg_s3c24xx,
+	.get_config	= s3c_gpio_getcfg_s3c24xx,
 	.set_pull	= s3c_gpio_setpull_updown,
 	.get_pull	= s3c_gpio_getpull_updown,
 };
diff --git a/arch/arm/mach-s3c64xx/include/mach/pll.h b/arch/arm/mach-s3c64xx/include/mach/pll.h
index 90bbd72..5ef0bb6 100644
--- a/arch/arm/mach-s3c64xx/include/mach/pll.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pll.h
@@ -20,6 +20,7 @@
 #define S3C6400_PLL_SDIV_SHIFT	(0)
 
 #include <asm/div64.h>
+#include <plat/pll6553x.h>
 
 static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
 					    u32 pllcon)
@@ -37,38 +38,8 @@
 	return (unsigned long)fvco;
 }
 
-#define S3C6400_EPLL_MDIV_MASK	((1 << (23-16)) - 1)
-#define S3C6400_EPLL_PDIV_MASK	((1 << (13-8)) - 1)
-#define S3C6400_EPLL_SDIV_MASK	((1 << (2-0)) - 1)
-#define S3C6400_EPLL_MDIV_SHIFT	(16)
-#define S3C6400_EPLL_PDIV_SHIFT	(8)
-#define S3C6400_EPLL_SDIV_SHIFT	(0)
-#define S3C6400_EPLL_KDIV_MASK  (0xffff)
-
 static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
 {
-	unsigned long result;
-	u32 epll0 = __raw_readl(S3C_EPLL_CON0);
-	u32 epll1 = __raw_readl(S3C_EPLL_CON1);
-	u32 mdiv, pdiv, sdiv, kdiv;
-	u64 tmp;
-
-	mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK;
-	pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK;
-	sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK;
-	kdiv = epll1 & S3C6400_EPLL_KDIV_MASK;
-
-	/* We need to multiple baseclk by mdiv (the integer part) and kdiv
-	 * which is in 2^16ths, so shift mdiv up (does not overflow) and
-	 * add kdiv before multiplying. The use of tmp is to avoid any
-	 * overflows before shifting bac down into result when multipling
-	 * by the mdiv and kdiv pair.
-	 */
-
-	tmp = baseclk;
-	tmp *= (mdiv << 16) + kdiv;
-	do_div(tmp, (pdiv << sdiv));
-	result = tmp >> 16;
-
-	return result;
+	return s3c_get_pll6553x(baseclk, __raw_readl(S3C_EPLL_CON0),
+				__raw_readl(S3C_EPLL_CON1));
 }
diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p6440/gpio.c
index b0ea741..262dc75 100644
--- a/arch/arm/mach-s5p6440/gpio.c
+++ b/arch/arm/mach-s5p6440/gpio.c
@@ -161,12 +161,15 @@
 	}, {
 		.cfg_eint	= 0,
 		.set_config	= s3c_gpio_setcfg_s3c24xx,
+		.get_config	= s3c_gpio_getcfg_s3c24xx,
 	}, {
 		.cfg_eint	= 2,
 		.set_config	= s3c_gpio_setcfg_s3c24xx,
+		.get_config	= s3c_gpio_getcfg_s3c24xx,
 	}, {
 		.cfg_eint	= 3,
 		.set_config	= s3c_gpio_setcfg_s3c24xx,
+		.get_config	= s3c_gpio_getcfg_s3c24xx,
 	},
 };
 
@@ -279,6 +282,8 @@
 	for (; nr_chips > 0; nr_chips--, chipcfg++) {
 		if (!chipcfg->set_config)
 			chipcfg->set_config	= s3c_gpio_setcfg_s3c64xx_4bit;
+		if (!chipcfg->get_config)
+			chipcfg->get_config	= s3c_gpio_getcfg_s3c64xx_4bit;
 		if (!chipcfg->set_pull)
 			chipcfg->set_pull	= s3c_gpio_setpull_updown;
 		if (!chipcfg->get_pull)
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index aeceb9b..f2b88c5 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -7,7 +7,6 @@
 	select CPU_V6
 	select HAVE_CLK
 	select COMMON_CLKDEV
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 
 config ARCH_SH7377
@@ -15,7 +14,6 @@
 	select CPU_V7
 	select HAVE_CLK
 	select COMMON_CLKDEV
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 
 config ARCH_SH7372
@@ -23,7 +21,6 @@
 	select CPU_V7
 	select HAVE_CLK
 	select COMMON_CLKDEV
-	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 
 comment "SH-Mobile Board Type"
diff --git a/arch/arm/mach-spear3xx/Kconfig b/arch/arm/mach-spear3xx/Kconfig
new file mode 100644
index 0000000..20d1317
--- /dev/null
+++ b/arch/arm/mach-spear3xx/Kconfig
@@ -0,0 +1,33 @@
+#
+# SPEAr3XX Machine configuration file
+#
+
+if ARCH_SPEAR3XX
+
+choice
+	prompt "SPEAr3XX Family"
+	default MACH_SPEAR300
+
+config MACH_SPEAR300
+	bool "SPEAr300"
+	help
+	  Supports ST SPEAr300 Machine
+
+config MACH_SPEAR310
+	bool "SPEAr310"
+	help
+	  Supports ST SPEAr310 Machine
+
+config MACH_SPEAR320
+	bool "SPEAr320"
+	help
+	  Supports ST SPEAr320 Machine
+
+endchoice
+
+# Adding SPEAr3XX machine specific configuration files
+source "arch/arm/mach-spear3xx/Kconfig300"
+source "arch/arm/mach-spear3xx/Kconfig310"
+source "arch/arm/mach-spear3xx/Kconfig320"
+
+endif #ARCH_SPEAR3XX
diff --git a/arch/arm/mach-spear3xx/Kconfig300 b/arch/arm/mach-spear3xx/Kconfig300
new file mode 100644
index 0000000..c519a05
--- /dev/null
+++ b/arch/arm/mach-spear3xx/Kconfig300
@@ -0,0 +1,17 @@
+#
+# SPEAr300 machine configuration file
+#
+
+if MACH_SPEAR300
+
+choice
+	prompt "SPEAr300 Boards"
+	default BOARD_SPEAR300_EVB
+
+config BOARD_SPEAR300_EVB
+	bool "SPEAr300 Evaluation Board"
+	help
+	  Supports ST SPEAr300 Evaluation Board
+endchoice
+
+endif	#MACH_SPEAR300
diff --git a/arch/arm/mach-spear3xx/Kconfig310 b/arch/arm/mach-spear3xx/Kconfig310
new file mode 100644
index 0000000..60e7442
--- /dev/null
+++ b/arch/arm/mach-spear3xx/Kconfig310
@@ -0,0 +1,17 @@
+#
+# SPEAr310 machine configuration file
+#
+
+if MACH_SPEAR310
+
+choice
+	prompt "SPEAr310 Boards"
+	default BOARD_SPEAR310_EVB
+
+config BOARD_SPEAR310_EVB
+	bool "SPEAr310 Evaluation Board"
+	help
+	  Supports ST SPEAr310 Evaluation Board
+endchoice
+
+endif	#MACH_SPEAR310
diff --git a/arch/arm/mach-spear3xx/Kconfig320 b/arch/arm/mach-spear3xx/Kconfig320
new file mode 100644
index 0000000..1c1d438
--- /dev/null
+++ b/arch/arm/mach-spear3xx/Kconfig320
@@ -0,0 +1,17 @@
+#
+# SPEAr320 machine configuration file
+#
+
+if MACH_SPEAR320
+
+choice
+	prompt "SPEAr320 Boards"
+	default BOARD_SPEAR320_EVB
+
+config BOARD_SPEAR320_EVB
+	bool "SPEAr320 Evaluation Board"
+	help
+	  Supports ST SPEAr320 Evaluation Board
+endchoice
+
+endif	#MACH_SPEAR320
diff --git a/arch/arm/mach-spear3xx/Makefile b/arch/arm/mach-spear3xx/Makefile
new file mode 100644
index 0000000..b248624
--- /dev/null
+++ b/arch/arm/mach-spear3xx/Makefile
@@ -0,0 +1,26 @@
+#
+# Makefile for SPEAr3XX machine series
+#
+
+# common files
+obj-y	+= spear3xx.o clock.o
+
+# spear300 specific files
+obj-$(CONFIG_MACH_SPEAR300) += spear300.o
+
+# spear300 boards files
+obj-$(CONFIG_BOARD_SPEAR300_EVB) += spear300_evb.o
+
+
+# spear310 specific files
+obj-$(CONFIG_MACH_SPEAR310) += spear310.o
+
+# spear310 boards files
+obj-$(CONFIG_BOARD_SPEAR310_EVB) += spear310_evb.o
+
+
+# spear320 specific files
+obj-$(CONFIG_MACH_SPEAR320) += spear320.o
+
+# spear320 boards files
+obj-$(CONFIG_BOARD_SPEAR320_EVB) += spear320_evb.o
diff --git a/arch/arm/mach-spear3xx/Makefile.boot b/arch/arm/mach-spear3xx/Makefile.boot
new file mode 100644
index 0000000..7a1f3c0
--- /dev/null
+++ b/arch/arm/mach-spear3xx/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
new file mode 100644
index 0000000..39f6ccf
--- /dev/null
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -0,0 +1,389 @@
+/*
+ * arch/arm/mach-spear3xx/clock.c
+ *
+ * SPEAr3xx machines clock framework source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/init.h>
+#include <linux/kernel.h>
+#include <mach/misc_regs.h>
+#include <plat/clock.h>
+
+/* root clks */
+/* 32 KHz oscillator clock */
+static struct clk osc_32k_clk = {
+	.flags = ALWAYS_ENABLED,
+	.rate = 32000,
+};
+
+/* 24 MHz oscillator clock */
+static struct clk osc_24m_clk = {
+	.flags = ALWAYS_ENABLED,
+	.rate = 24000000,
+};
+
+/* clock derived from 32 KHz osc clk */
+/* rtc clock */
+static struct clk rtc_clk = {
+	.pclk = &osc_32k_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = RTC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from 24 MHz osc clk */
+/* pll1 configuration structure */
+static struct pll_clk_config pll1_config = {
+	.mode_reg = PLL1_CTR,
+	.cfg_reg = PLL1_FRQ,
+};
+
+/* PLL1 clock */
+static struct clk pll1_clk = {
+	.pclk = &osc_24m_clk,
+	.en_reg = PLL1_CTR,
+	.en_reg_bit = PLL_ENABLE,
+	.recalc = &pll1_clk_recalc,
+	.private_data = &pll1_config,
+};
+
+/* PLL3 48 MHz clock */
+static struct clk pll3_48m_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &osc_24m_clk,
+	.rate = 48000000,
+};
+
+/* watch dog timer clock */
+static struct clk wdt_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &osc_24m_clk,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from pll1 clk */
+/* cpu clock */
+static struct clk cpu_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.recalc = &follow_parent,
+};
+
+/* ahb configuration structure */
+static struct bus_clk_config ahb_config = {
+	.reg = CORE_CLK_CFG,
+	.mask = PLL_HCLK_RATIO_MASK,
+	.shift = PLL_HCLK_RATIO_SHIFT,
+};
+
+/* ahb clock */
+static struct clk ahb_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.recalc = &bus_clk_recalc,
+	.private_data = &ahb_config,
+};
+
+/* uart configurations */
+static struct aux_clk_config uart_config = {
+	.synth_reg = UART_CLK_SYNT,
+};
+
+/* uart parents */
+static struct pclk_info uart_pclk_info[] = {
+	{
+		.pclk = &pll1_clk,
+		.pclk_mask = AUX_CLK_PLL1_MASK,
+		.scalable = 1,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_mask = AUX_CLK_PLL3_MASK,
+		.scalable = 0,
+	},
+};
+
+/* uart parent select structure */
+static struct pclk_sel uart_pclk_sel = {
+	.pclk_info = uart_pclk_info,
+	.pclk_count = ARRAY_SIZE(uart_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = UART_CLK_MASK,
+};
+
+/* uart clock */
+static struct clk uart_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = UART_CLK_ENB,
+	.pclk_sel = &uart_pclk_sel,
+	.pclk_sel_shift = UART_CLK_SHIFT,
+	.recalc = &aux_clk_recalc,
+	.private_data = &uart_config,
+};
+
+/* firda configurations */
+static struct aux_clk_config firda_config = {
+	.synth_reg = FIRDA_CLK_SYNT,
+};
+
+/* firda parents */
+static struct pclk_info firda_pclk_info[] = {
+	{
+		.pclk = &pll1_clk,
+		.pclk_mask = AUX_CLK_PLL1_MASK,
+		.scalable = 1,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_mask = AUX_CLK_PLL3_MASK,
+		.scalable = 0,
+	},
+};
+
+/* firda parent select structure */
+static struct pclk_sel firda_pclk_sel = {
+	.pclk_info = firda_pclk_info,
+	.pclk_count = ARRAY_SIZE(firda_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = FIRDA_CLK_MASK,
+};
+
+/* firda clock */
+static struct clk firda_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = FIRDA_CLK_ENB,
+	.pclk_sel = &firda_pclk_sel,
+	.pclk_sel_shift = FIRDA_CLK_SHIFT,
+	.recalc = &aux_clk_recalc,
+	.private_data = &firda_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt_pclk_info[] = {
+	{
+		.pclk = &pll1_clk,
+		.pclk_mask = AUX_CLK_PLL1_MASK,
+		.scalable = 1,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_mask = AUX_CLK_PLL3_MASK,
+		.scalable = 0,
+	},
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt_pclk_sel = {
+	.pclk_info = gpt_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt0 configurations */
+static struct aux_clk_config gpt0_config = {
+	.synth_reg = PRSC1_CLK_CFG,
+};
+
+/* gpt0 timer clock */
+static struct clk gpt0_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT0_CLK_SHIFT,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt0_config,
+};
+
+/* gpt1 configurations */
+static struct aux_clk_config gpt1_config = {
+	.synth_reg = PRSC2_CLK_CFG,
+};
+
+/* gpt1 timer clock */
+static struct clk gpt1_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPT1_CLK_ENB,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT1_CLK_SHIFT,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt1_config,
+};
+
+/* gpt2 configurations */
+static struct aux_clk_config gpt2_config = {
+	.synth_reg = PRSC3_CLK_CFG,
+};
+
+/* gpt2 timer clock */
+static struct clk gpt2_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPT2_CLK_ENB,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT2_CLK_SHIFT,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt2_config,
+};
+
+/* clock derived from pll3 clk */
+/* usbh clock */
+static struct clk usbh_clk = {
+	.pclk = &pll3_48m_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = USBH_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* usbd clock */
+static struct clk usbd_clk = {
+	.pclk = &pll3_48m_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = USBD_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* clcd clock */
+static struct clk clcd_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll3_48m_clk,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from ahb clk */
+/* apb configuration structure */
+static struct bus_clk_config apb_config = {
+	.reg = CORE_CLK_CFG,
+	.mask = HCLK_PCLK_RATIO_MASK,
+	.shift = HCLK_PCLK_RATIO_SHIFT,
+};
+
+/* apb clock */
+static struct clk apb_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ahb_clk,
+	.recalc = &bus_clk_recalc,
+	.private_data = &apb_config,
+};
+
+/* i2c clock */
+static struct clk i2c_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = I2C_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* dma clock */
+static struct clk dma_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = DMA_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* jpeg clock */
+static struct clk jpeg_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = JPEG_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* gmac clock */
+static struct clk gmac_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GMAC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* smi clock */
+static struct clk smi_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SMI_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* c3 clock */
+static struct clk c3_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = C3_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from apb clk */
+/* adc clock */
+static struct clk adc_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = ADC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* ssp clock */
+static struct clk ssp_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SSP_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* gpio clock */
+static struct clk gpio_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPIO_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* array of all spear 3xx clock lookups */
+static struct clk_lookup spear_clk_lookups[] = {
+	/* root clks */
+	{ .con_id = "osc_32k_clk",	.clk = &osc_32k_clk},
+	{ .con_id = "osc_24m_clk",	.clk = &osc_24m_clk},
+	/* clock derived from 32 KHz osc clk */
+	{ .dev_id = "rtc",		.clk = &rtc_clk},
+	/* clock derived from 24 MHz osc clk */
+	{ .con_id = "pll1_clk",		.clk = &pll1_clk},
+	{ .con_id = "pll3_48m_clk",	.clk = &pll3_48m_clk},
+	{ .dev_id = "wdt",		.clk = &wdt_clk},
+	/* clock derived from pll1 clk */
+	{ .con_id = "cpu_clk",		.clk = &cpu_clk},
+	{ .con_id = "ahb_clk",		.clk = &ahb_clk},
+	{ .dev_id = "uart",		.clk = &uart_clk},
+	{ .dev_id = "firda",		.clk = &firda_clk},
+	{ .dev_id = "gpt0",		.clk = &gpt0_clk},
+	{ .dev_id = "gpt1",		.clk = &gpt1_clk},
+	{ .dev_id = "gpt2",		.clk = &gpt2_clk},
+	/* clock derived from pll3 clk */
+	{ .dev_id = "usbh",		.clk = &usbh_clk},
+	{ .dev_id = "usbd",		.clk = &usbd_clk},
+	{ .dev_id = "clcd",		.clk = &clcd_clk},
+	/* clock derived from ahb clk */
+	{ .con_id = "apb_clk",		.clk = &apb_clk},
+	{ .dev_id = "i2c",		.clk = &i2c_clk},
+	{ .dev_id = "dma",		.clk = &dma_clk},
+	{ .dev_id = "jpeg",		.clk = &jpeg_clk},
+	{ .dev_id = "gmac",		.clk = &gmac_clk},
+	{ .dev_id = "smi",		.clk = &smi_clk},
+	{ .dev_id = "c3",		.clk = &c3_clk},
+	/* clock derived from apb clk */
+	{ .dev_id = "adc",		.clk = &adc_clk},
+	{ .dev_id = "ssp",		.clk = &ssp_clk},
+	{ .dev_id = "gpio",		.clk = &gpio_clk},
+};
+
+void __init clk_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+		clk_register(&spear_clk_lookups[i]);
+
+	recalc_root_clocks();
+}
diff --git a/arch/arm/mach-spear3xx/include/mach/clkdev.h b/arch/arm/mach-spear3xx/include/mach/clkdev.h
new file mode 100644
index 0000000..a3d0733
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/clkdev.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/clkdev.h
+ *
+ * Clock Dev framework definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+#include <plat/clkdev.h>
+
+#endif /* __MACH_CLKDEV_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/debug-macro.S b/arch/arm/mach-spear3xx/include/mach/debug-macro.S
new file mode 100644
index 0000000..590519f
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/debug-macro.S
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header spear3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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 <plat/debug-macro.S>
diff --git a/arch/arm/mach-spear3xx/include/mach/entry-macro.S b/arch/arm/mach-spear3xx/include/mach/entry-macro.S
new file mode 100644
index 0000000..947625d
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/entry-macro.S
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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 <mach/hardware.h>
+#include <mach/spear.h>
+#include <asm/hardware/vic.h>
+
+		.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
+		ldr	\base, =VA_SPEAR3XX_ML1_VIC_BASE
+		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get status
+		teq	\irqstat, #0
+		beq	1001f				@ this will set/reset
+							@ zero register
+		/*
+		 * Following code will find bit position of least significang
+		 * bit set in irqstat, using following equation
+		 * least significant bit set in n = (n & ~(n-1))
+		 */
+		sub	\tmp, \irqstat, #1		@ tmp = irqstat - 1
+		mvn	\tmp, \tmp			@ tmp = ~tmp
+		and	\irqstat, \irqstat, \tmp	@ irqstat &= tmp
+		/* Now, irqstat is = bit no. of 1st bit set in vic irq status */
+		clz	\tmp, \irqstat			@ tmp = leading zeros
+		rsb	\irqnr, \tmp, #0x1F		@ irqnr = 32 - tmp - 1
+
+1001:		/* EQ will be set if no irqs pending */
+		.endm
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
new file mode 100644
index 0000000..af7e02c
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -0,0 +1,205 @@
+/*
+ * arch/arm/mach-spear3xx/generic.h
+ *
+ * SPEAr3XX machine family generic header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <plat/padmux.h>
+
+/* spear3xx declarations */
+/*
+ * Each GPT has 2 timer channels
+ * Following GPT channels will be used as clock source and clockevent
+ */
+#define SPEAR_GPT0_BASE		SPEAR3XX_ML1_TMR_BASE
+#define SPEAR_GPT0_CHAN0_IRQ	IRQ_CPU_GPT1_1
+#define SPEAR_GPT0_CHAN1_IRQ	IRQ_CPU_GPT1_2
+
+/* Add spear3xx family device structure declarations here */
+extern struct amba_device gpio_device;
+extern struct amba_device uart_device;
+extern struct sys_timer spear_sys_timer;
+
+/* Add spear3xx family function declarations here */
+void __init clk_init(void);
+void __init spear3xx_map_io(void);
+void __init spear3xx_init_irq(void);
+void __init spear3xx_init(void);
+void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size);
+
+/* pad mux declarations */
+#define PMX_FIRDA_MASK		(1 << 14)
+#define PMX_I2C_MASK		(1 << 13)
+#define PMX_SSP_CS_MASK		(1 << 12)
+#define PMX_SSP_MASK		(1 << 11)
+#define PMX_MII_MASK		(1 << 10)
+#define PMX_GPIO_PIN0_MASK	(1 << 9)
+#define PMX_GPIO_PIN1_MASK	(1 << 8)
+#define PMX_GPIO_PIN2_MASK	(1 << 7)
+#define PMX_GPIO_PIN3_MASK	(1 << 6)
+#define PMX_GPIO_PIN4_MASK	(1 << 5)
+#define PMX_GPIO_PIN5_MASK	(1 << 4)
+#define PMX_UART0_MODEM_MASK	(1 << 3)
+#define PMX_UART0_MASK		(1 << 2)
+#define PMX_TIMER_3_4_MASK	(1 << 1)
+#define PMX_TIMER_1_2_MASK	(1 << 0)
+
+/* pad mux devices */
+extern struct pmx_dev pmx_firda;
+extern struct pmx_dev pmx_i2c;
+extern struct pmx_dev pmx_ssp_cs;
+extern struct pmx_dev pmx_ssp;
+extern struct pmx_dev pmx_mii;
+extern struct pmx_dev pmx_gpio_pin0;
+extern struct pmx_dev pmx_gpio_pin1;
+extern struct pmx_dev pmx_gpio_pin2;
+extern struct pmx_dev pmx_gpio_pin3;
+extern struct pmx_dev pmx_gpio_pin4;
+extern struct pmx_dev pmx_gpio_pin5;
+extern struct pmx_dev pmx_uart0_modem;
+extern struct pmx_dev pmx_uart0;
+extern struct pmx_dev pmx_timer_3_4;
+extern struct pmx_dev pmx_timer_1_2;
+
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* padmux plgpio devices */
+extern struct pmx_dev pmx_plgpio_0_1;
+extern struct pmx_dev pmx_plgpio_2_3;
+extern struct pmx_dev pmx_plgpio_4_5;
+extern struct pmx_dev pmx_plgpio_6_9;
+extern struct pmx_dev pmx_plgpio_10_27;
+extern struct pmx_dev pmx_plgpio_28;
+extern struct pmx_dev pmx_plgpio_29;
+extern struct pmx_dev pmx_plgpio_30;
+extern struct pmx_dev pmx_plgpio_31;
+extern struct pmx_dev pmx_plgpio_32;
+extern struct pmx_dev pmx_plgpio_33;
+extern struct pmx_dev pmx_plgpio_34_36;
+extern struct pmx_dev pmx_plgpio_37_42;
+extern struct pmx_dev pmx_plgpio_43_44_47_48;
+extern struct pmx_dev pmx_plgpio_45_46_49_50;
+#endif
+
+extern struct pmx_driver pmx_driver;
+
+/* spear300 declarations */
+#ifdef CONFIG_MACH_SPEAR300
+/* Add spear300 machine device structure declarations here */
+extern struct amba_device gpio1_device;
+
+/* pad mux modes */
+extern struct pmx_mode nand_mode;
+extern struct pmx_mode nor_mode;
+extern struct pmx_mode photo_frame_mode;
+extern struct pmx_mode lend_ip_phone_mode;
+extern struct pmx_mode hend_ip_phone_mode;
+extern struct pmx_mode lend_wifi_phone_mode;
+extern struct pmx_mode hend_wifi_phone_mode;
+extern struct pmx_mode ata_pabx_wi2s_mode;
+extern struct pmx_mode ata_pabx_i2s_mode;
+extern struct pmx_mode caml_lcdw_mode;
+extern struct pmx_mode camu_lcd_mode;
+extern struct pmx_mode camu_wlcd_mode;
+extern struct pmx_mode caml_lcd_mode;
+
+/* pad mux devices */
+extern struct pmx_dev pmx_fsmc_2_chips;
+extern struct pmx_dev pmx_fsmc_4_chips;
+extern struct pmx_dev pmx_keyboard;
+extern struct pmx_dev pmx_clcd;
+extern struct pmx_dev pmx_telecom_gpio;
+extern struct pmx_dev pmx_telecom_tdm;
+extern struct pmx_dev pmx_telecom_spi_cs_i2c_clk;
+extern struct pmx_dev pmx_telecom_camera;
+extern struct pmx_dev pmx_telecom_dac;
+extern struct pmx_dev pmx_telecom_i2s;
+extern struct pmx_dev pmx_telecom_boot_pins;
+extern struct pmx_dev pmx_telecom_sdio_4bit;
+extern struct pmx_dev pmx_telecom_sdio_8bit;
+extern struct pmx_dev pmx_gpio1;
+
+void spear300_pmx_init(void);
+
+/* Add spear300 machine function declarations here */
+void __init spear300_init(void);
+
+#endif /* CONFIG_MACH_SPEAR300 */
+
+/* spear310 declarations */
+#ifdef CONFIG_MACH_SPEAR310
+/* Add spear310 machine device structure declarations here */
+
+/* pad mux devices */
+extern struct pmx_dev pmx_emi_cs_0_1_4_5;
+extern struct pmx_dev pmx_emi_cs_2_3;
+extern struct pmx_dev pmx_uart1;
+extern struct pmx_dev pmx_uart2;
+extern struct pmx_dev pmx_uart3_4_5;
+extern struct pmx_dev pmx_fsmc;
+extern struct pmx_dev pmx_rs485_0_1;
+extern struct pmx_dev pmx_tdm0;
+
+void spear310_pmx_init(void);
+
+/* Add spear310 machine function declarations here */
+void __init spear310_init(void);
+
+#endif /* CONFIG_MACH_SPEAR310 */
+
+/* spear320 declarations */
+#ifdef CONFIG_MACH_SPEAR320
+/* Add spear320 machine device structure declarations here */
+
+/* pad mux modes */
+extern struct pmx_mode auto_net_smii_mode;
+extern struct pmx_mode auto_net_mii_mode;
+extern struct pmx_mode auto_exp_mode;
+extern struct pmx_mode small_printers_mode;
+
+/* pad mux devices */
+extern struct pmx_dev pmx_clcd;
+extern struct pmx_dev pmx_emi;
+extern struct pmx_dev pmx_fsmc;
+extern struct pmx_dev pmx_spp;
+extern struct pmx_dev pmx_sdio;
+extern struct pmx_dev pmx_i2s;
+extern struct pmx_dev pmx_uart1;
+extern struct pmx_dev pmx_uart1_modem;
+extern struct pmx_dev pmx_uart2;
+extern struct pmx_dev pmx_touchscreen;
+extern struct pmx_dev pmx_can;
+extern struct pmx_dev pmx_sdio_led;
+extern struct pmx_dev pmx_pwm0;
+extern struct pmx_dev pmx_pwm1;
+extern struct pmx_dev pmx_pwm2;
+extern struct pmx_dev pmx_pwm3;
+extern struct pmx_dev pmx_ssp1;
+extern struct pmx_dev pmx_ssp2;
+extern struct pmx_dev pmx_mii1;
+extern struct pmx_dev pmx_smii0;
+extern struct pmx_dev pmx_smii1;
+extern struct pmx_dev pmx_i2c1;
+
+void spear320_pmx_init(void);
+
+/* Add spear320 machine function declarations here */
+void __init spear320_init(void);
+
+#endif /* CONFIG_MACH_SPEAR320 */
+
+#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/gpio.h b/arch/arm/mach-spear3xx/include/mach/gpio.h
new file mode 100644
index 0000000..451b208
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/gpio.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/gpio.h
+ *
+ * GPIO macros for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_GPIO_H
+#define __MACH_GPIO_H
+
+#include <plat/gpio.h>
+
+#endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/hardware.h b/arch/arm/mach-spear3xx/include/mach/hardware.h
new file mode 100644
index 0000000..4a86e6a
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/hardware.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/hardware.h
+ *
+ * Hardware definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/* Vitual to physical translation of statically mapped space */
+#define IO_ADDRESS(x)		(x | 0xF0000000)
+
+#endif /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/io.h b/arch/arm/mach-spear3xx/include/mach/io.h
new file mode 100644
index 0000000..30cff8a
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/io.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/io.h
+ *
+ * IO definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#include <plat/io.h>
+
+#endif /* __MACH_IO_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
new file mode 100644
index 0000000..7f940b8
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -0,0 +1,152 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/irqs.h
+ *
+ * IRQ helper macros for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+/* SPEAr3xx IRQ definitions */
+#define IRQ_HW_ACCEL_MOD_0			0
+#define IRQ_INTRCOMM_RAS_ARM			1
+#define IRQ_CPU_GPT1_1				2
+#define IRQ_CPU_GPT1_2				3
+#define IRQ_BASIC_GPT1_1			4
+#define IRQ_BASIC_GPT1_2			5
+#define IRQ_BASIC_GPT2_1			6
+#define IRQ_BASIC_GPT2_2			7
+#define IRQ_BASIC_DMA				8
+#define IRQ_BASIC_SMI				9
+#define IRQ_BASIC_RTC				10
+#define IRQ_BASIC_GPIO				11
+#define IRQ_BASIC_WDT				12
+#define IRQ_DDR_CONTROLLER			13
+#define IRQ_SYS_ERROR				14
+#define IRQ_WAKEUP_RCV				15
+#define IRQ_JPEG				16
+#define IRQ_IRDA				17
+#define IRQ_ADC					18
+#define IRQ_UART				19
+#define IRQ_SSP					20
+#define IRQ_I2C					21
+#define IRQ_MAC_1				22
+#define IRQ_MAC_2				23
+#define IRQ_USB_DEV				24
+#define IRQ_USB_H_OHCI_0			25
+#define IRQ_USB_H_EHCI_0			26
+#define IRQ_USB_H_EHCI_1			IRQ_USB_H_EHCI_0
+#define IRQ_USB_H_OHCI_1			27
+#define IRQ_GEN_RAS_1				28
+#define IRQ_GEN_RAS_2				29
+#define IRQ_GEN_RAS_3				30
+#define IRQ_HW_ACCEL_MOD_1			31
+#define IRQ_VIC_END				32
+
+#define VIRQ_START				IRQ_VIC_END
+
+/* SPEAr300 Virtual irq definitions */
+#ifdef CONFIG_MACH_SPEAR300
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define VIRQ_IT_PERS_S				(VIRQ_START + 0)
+#define VIRQ_IT_CHANGE_S			(VIRQ_START + 1)
+#define VIRQ_I2S				(VIRQ_START + 2)
+#define VIRQ_TDM				(VIRQ_START + 3)
+#define VIRQ_CAMERA_L				(VIRQ_START + 4)
+#define VIRQ_CAMERA_F				(VIRQ_START + 5)
+#define VIRQ_CAMERA_V				(VIRQ_START + 6)
+#define VIRQ_KEYBOARD				(VIRQ_START + 7)
+#define VIRQ_GPIO1				(VIRQ_START + 8)
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define IRQ_CLCD				IRQ_GEN_RAS_3
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define IRQ_SDIO				IRQ_INTRCOMM_RAS_ARM
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE			(VIRQ_START + 9)
+#define SPEAR_GPIO1_INT_BASE			(SPEAR_GPIO_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END			(SPEAR_GPIO1_INT_BASE + 8)
+
+/* SPEAr310 Virtual irq definitions */
+#elif defined(CONFIG_MACH_SPEAR310)
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define VIRQ_SMII0				(VIRQ_START + 0)
+#define VIRQ_SMII1				(VIRQ_START + 1)
+#define VIRQ_SMII2				(VIRQ_START + 2)
+#define VIRQ_SMII3				(VIRQ_START + 3)
+#define VIRQ_WAKEUP_SMII0			(VIRQ_START + 4)
+#define VIRQ_WAKEUP_SMII1			(VIRQ_START + 5)
+#define VIRQ_WAKEUP_SMII2			(VIRQ_START + 6)
+#define VIRQ_WAKEUP_SMII3			(VIRQ_START + 7)
+
+/* IRQs sharing IRQ_GEN_RAS_2 */
+#define VIRQ_UART1				(VIRQ_START + 8)
+#define VIRQ_UART2				(VIRQ_START + 9)
+#define VIRQ_UART3				(VIRQ_START + 10)
+#define VIRQ_UART4				(VIRQ_START + 11)
+#define VIRQ_UART5				(VIRQ_START + 12)
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define VIRQ_EMI				(VIRQ_START + 13)
+#define VIRQ_PLGPIO				(VIRQ_START + 14)
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define VIRQ_TDM_HDLC				(VIRQ_START + 15)
+#define VIRQ_RS485_0				(VIRQ_START + 16)
+#define VIRQ_RS485_1				(VIRQ_START + 17)
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE			(VIRQ_START + 18)
+
+/* SPEAr320 Virtual irq definitions */
+#else
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define VIRQ_EMI				(VIRQ_START + 0)
+#define VIRQ_CLCD				(VIRQ_START + 1)
+#define VIRQ_SPP				(VIRQ_START + 2)
+
+/* IRQs sharing IRQ_GEN_RAS_2 */
+#define IRQ_SDIO				IRQ_GEN_RAS_2
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define VIRQ_PLGPIO				(VIRQ_START + 3)
+#define VIRQ_I2S_PLAY				(VIRQ_START + 4)
+#define VIRQ_I2S_REC				(VIRQ_START + 5)
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define VIRQ_CANU				(VIRQ_START + 6)
+#define VIRQ_CANL				(VIRQ_START + 7)
+#define VIRQ_UART1				(VIRQ_START + 8)
+#define VIRQ_UART2				(VIRQ_START + 9)
+#define VIRQ_SSP1				(VIRQ_START + 10)
+#define VIRQ_SSP2				(VIRQ_START + 11)
+#define VIRQ_SMII0				(VIRQ_START + 12)
+#define VIRQ_MII1_SMII1				(VIRQ_START + 13)
+#define VIRQ_WAKEUP_SMII0			(VIRQ_START + 14)
+#define VIRQ_WAKEUP_MII1_SMII1			(VIRQ_START + 15)
+#define VIRQ_I2C				(VIRQ_START + 16)
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE			(VIRQ_START + 17)
+
+#endif
+
+/* PLGPIO Virtual IRQs */
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+#define SPEAR_PLGPIO_INT_BASE			(SPEAR_GPIO_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END			(SPEAR_PLGPIO_INT_BASE + 102)
+#endif
+
+#define VIRQ_END				SPEAR_GPIO_INT_END
+#define NR_IRQS					VIRQ_END
+
+#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/memory.h b/arch/arm/mach-spear3xx/include/mach/memory.h
new file mode 100644
index 0000000..5173522
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/memory.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/memory.h
+ *
+ * Memory map for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#include <plat/memory.h>
+
+#endif /* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
new file mode 100644
index 0000000..38d767a
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
@@ -0,0 +1,163 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/misc_regs.h
+ *
+ * Miscellaneous registers definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_MISC_REGS_H
+#define __MACH_MISC_REGS_H
+
+#include <mach/spear.h>
+
+#define MISC_BASE		VA_SPEAR3XX_ICM3_MISC_REG_BASE
+
+#define SOC_CFG_CTR		((unsigned int *)(MISC_BASE + 0x000))
+#define DIAG_CFG_CTR		((unsigned int *)(MISC_BASE + 0x004))
+#define PLL1_CTR		((unsigned int *)(MISC_BASE + 0x008))
+#define PLL1_FRQ		((unsigned int *)(MISC_BASE + 0x00C))
+#define PLL1_MOD		((unsigned int *)(MISC_BASE + 0x010))
+#define PLL2_CTR		((unsigned int *)(MISC_BASE + 0x014))
+/* PLL_CTR register masks */
+#define PLL_ENABLE		2
+#define PLL_MODE_SHIFT		4
+#define PLL_MODE_MASK		0x3
+#define PLL_MODE_NORMAL		0
+#define PLL_MODE_FRACTION	1
+#define PLL_MODE_DITH_DSB	2
+#define PLL_MODE_DITH_SSB	3
+
+#define PLL2_FRQ		((unsigned int *)(MISC_BASE + 0x018))
+/* PLL FRQ register masks */
+#define PLL_DIV_N_SHIFT		0
+#define PLL_DIV_N_MASK		0xFF
+#define PLL_DIV_P_SHIFT		8
+#define PLL_DIV_P_MASK		0x7
+#define PLL_NORM_FDBK_M_SHIFT	24
+#define PLL_NORM_FDBK_M_MASK	0xFF
+#define PLL_DITH_FDBK_M_SHIFT	16
+#define PLL_DITH_FDBK_M_MASK	0xFFFF
+
+#define PLL2_MOD		((unsigned int *)(MISC_BASE + 0x01C))
+#define PLL_CLK_CFG		((unsigned int *)(MISC_BASE + 0x020))
+#define CORE_CLK_CFG		((unsigned int *)(MISC_BASE + 0x024))
+/* CORE CLK CFG register masks */
+#define PLL_HCLK_RATIO_SHIFT	10
+#define PLL_HCLK_RATIO_MASK	0x3
+#define HCLK_PCLK_RATIO_SHIFT	8
+#define HCLK_PCLK_RATIO_MASK	0x3
+
+#define PERIP_CLK_CFG		((unsigned int *)(MISC_BASE + 0x028))
+/* PERIP_CLK_CFG register masks */
+#define UART_CLK_SHIFT		4
+#define UART_CLK_MASK		0x1
+#define FIRDA_CLK_SHIFT		5
+#define FIRDA_CLK_MASK		0x3
+#define GPT0_CLK_SHIFT		8
+#define GPT1_CLK_SHIFT		11
+#define GPT2_CLK_SHIFT		12
+#define GPT_CLK_MASK		0x1
+#define AUX_CLK_PLL3_MASK	0
+#define AUX_CLK_PLL1_MASK	1
+
+#define PERIP1_CLK_ENB		((unsigned int *)(MISC_BASE + 0x02C))
+/* PERIP1_CLK_ENB register masks */
+#define UART_CLK_ENB		3
+#define SSP_CLK_ENB		5
+#define I2C_CLK_ENB		7
+#define JPEG_CLK_ENB		8
+#define FIRDA_CLK_ENB		10
+#define GPT1_CLK_ENB		11
+#define GPT2_CLK_ENB		12
+#define ADC_CLK_ENB		15
+#define RTC_CLK_ENB		17
+#define GPIO_CLK_ENB		18
+#define DMA_CLK_ENB		19
+#define SMI_CLK_ENB		21
+#define GMAC_CLK_ENB		23
+#define USBD_CLK_ENB		24
+#define USBH_CLK_ENB		25
+#define C3_CLK_ENB		31
+
+#define SOC_CORE_ID		((unsigned int *)(MISC_BASE + 0x030))
+#define RAS_CLK_ENB		((unsigned int *)(MISC_BASE + 0x034))
+#define PERIP1_SOF_RST		((unsigned int *)(MISC_BASE + 0x038))
+/* PERIP1_SOF_RST register masks */
+#define JPEG_SOF_RST		8
+
+#define SOC_USER_ID		((unsigned int *)(MISC_BASE + 0x03C))
+#define RAS_SOF_RST		((unsigned int *)(MISC_BASE + 0x040))
+#define PRSC1_CLK_CFG		((unsigned int *)(MISC_BASE + 0x044))
+#define PRSC2_CLK_CFG		((unsigned int *)(MISC_BASE + 0x048))
+#define PRSC3_CLK_CFG		((unsigned int *)(MISC_BASE + 0x04C))
+/* gpt synthesizer register masks */
+#define GPT_MSCALE_SHIFT	0
+#define GPT_MSCALE_MASK		0xFFF
+#define GPT_NSCALE_SHIFT	12
+#define GPT_NSCALE_MASK		0xF
+
+#define AMEM_CLK_CFG		((unsigned int *)(MISC_BASE + 0x050))
+#define EXPI_CLK_CFG		((unsigned int *)(MISC_BASE + 0x054))
+#define CLCD_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x05C))
+#define FIRDA_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x060))
+#define UART_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x064))
+#define GMAC_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x068))
+#define RAS1_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x06C))
+#define RAS2_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x070))
+#define RAS3_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x074))
+#define RAS4_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x078))
+/* aux clk synthesiser register masks for irda to ras4 */
+#define AUX_EQ_SEL_SHIFT	30
+#define AUX_EQ_SEL_MASK		1
+#define AUX_EQ1_SEL		0
+#define AUX_EQ2_SEL		1
+#define AUX_XSCALE_SHIFT	16
+#define AUX_XSCALE_MASK		0xFFF
+#define AUX_YSCALE_SHIFT	0
+#define AUX_YSCALE_MASK		0xFFF
+
+#define ICM1_ARB_CFG		((unsigned int *)(MISC_BASE + 0x07C))
+#define ICM2_ARB_CFG		((unsigned int *)(MISC_BASE + 0x080))
+#define ICM3_ARB_CFG		((unsigned int *)(MISC_BASE + 0x084))
+#define ICM4_ARB_CFG		((unsigned int *)(MISC_BASE + 0x088))
+#define ICM5_ARB_CFG		((unsigned int *)(MISC_BASE + 0x08C))
+#define ICM6_ARB_CFG		((unsigned int *)(MISC_BASE + 0x090))
+#define ICM7_ARB_CFG		((unsigned int *)(MISC_BASE + 0x094))
+#define ICM8_ARB_CFG		((unsigned int *)(MISC_BASE + 0x098))
+#define ICM9_ARB_CFG		((unsigned int *)(MISC_BASE + 0x09C))
+#define DMA_CHN_CFG		((unsigned int *)(MISC_BASE + 0x0A0))
+#define USB2_PHY_CFG		((unsigned int *)(MISC_BASE + 0x0A4))
+#define GMAC_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0A8))
+#define EXPI_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0AC))
+#define PRC1_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x0C0))
+#define PRC2_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x0C4))
+#define PRC3_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x0C8))
+#define PRC4_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x0CC))
+#define PRC1_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x0D0))
+#define PRC2_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x0D4))
+#define PRC3_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x0D8))
+#define PRC4_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x0DC))
+#define PWRDOWN_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0E0))
+#define COMPSSTL_1V8_CFG	((unsigned int *)(MISC_BASE + 0x0E4))
+#define COMPSSTL_2V5_CFG	((unsigned int *)(MISC_BASE + 0x0E8))
+#define COMPCOR_3V3_CFG		((unsigned int *)(MISC_BASE + 0x0EC))
+#define SSTLPAD_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0F0))
+#define BIST1_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0F4))
+#define BIST2_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0F8))
+#define BIST3_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0FC))
+#define BIST4_CFG_CTR		((unsigned int *)(MISC_BASE + 0x100))
+#define BIST5_CFG_CTR		((unsigned int *)(MISC_BASE + 0x104))
+#define BIST1_STS_RES		((unsigned int *)(MISC_BASE + 0x108))
+#define BIST2_STS_RES		((unsigned int *)(MISC_BASE + 0x10C))
+#define BIST3_STS_RES		((unsigned int *)(MISC_BASE + 0x110))
+#define BIST4_STS_RES		((unsigned int *)(MISC_BASE + 0x114))
+#define BIST5_STS_RES		((unsigned int *)(MISC_BASE + 0x118))
+#define SYSERR_CFG_CTR		((unsigned int *)(MISC_BASE + 0x11C))
+
+#endif /* __MACH_MISC_REGS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h
new file mode 100644
index 0000000..dcca856
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/spear.h
@@ -0,0 +1,144 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear.h
+ *
+ * SPEAr3xx Machine family specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_SPEAR3XX_H
+#define __MACH_SPEAR3XX_H
+
+#include <mach/hardware.h>
+#include <mach/spear300.h>
+#include <mach/spear310.h>
+#include <mach/spear320.h>
+
+#define SPEAR3XX_ML_SDRAM_BASE		0x00000000
+#define SPEAR3XX_ML_SDRAM_SIZE		0x40000000
+
+#define SPEAR3XX_ICM9_BASE		0xC0000000
+#define SPEAR3XX_ICM9_SIZE		0x10000000
+
+/* ICM1 - Low speed connection */
+#define SPEAR3XX_ICM1_2_BASE		0xD0000000
+#define SPEAR3XX_ICM1_2_SIZE		0x10000000
+
+#define SPEAR3XX_ICM1_UART_BASE		0xD0000000
+#define VA_SPEAR3XX_ICM1_UART_BASE	IO_ADDRESS(SPEAR3XX_ICM1_UART_BASE)
+#define SPEAR3XX_ICM1_UART_SIZE		0x00080000
+
+#define SPEAR3XX_ICM1_ADC_BASE		0xD0080000
+#define SPEAR3XX_ICM1_ADC_SIZE		0x00080000
+
+#define SPEAR3XX_ICM1_SSP_BASE		0xD0100000
+#define SPEAR3XX_ICM1_SSP_SIZE		0x00080000
+
+#define SPEAR3XX_ICM1_I2C_BASE		0xD0180000
+#define SPEAR3XX_ICM1_I2C_SIZE		0x00080000
+
+#define SPEAR3XX_ICM1_JPEG_BASE		0xD0800000
+#define SPEAR3XX_ICM1_JPEG_SIZE		0x00800000
+
+#define SPEAR3XX_ICM1_IRDA_BASE		0xD1000000
+#define SPEAR3XX_ICM1_IRDA_SIZE		0x00080000
+
+#define SPEAR3XX_ICM1_SRAM_BASE		0xD2800000
+#define SPEAR3XX_ICM1_SRAM_SIZE		0x05800000
+
+/* ICM2 - Application Subsystem */
+#define SPEAR3XX_ICM2_HWACCEL0_BASE	0xD8800000
+#define SPEAR3XX_ICM2_HWACCEL0_SIZE	0x00800000
+
+#define SPEAR3XX_ICM2_HWACCEL1_BASE	0xD9000000
+#define SPEAR3XX_ICM2_HWACCEL1_SIZE	0x00800000
+
+/* ICM4 - High Speed Connection */
+#define SPEAR3XX_ICM4_BASE		0xE0000000
+#define SPEAR3XX_ICM4_SIZE		0x08000000
+
+#define SPEAR3XX_ICM4_MII_BASE		0xE0800000
+#define SPEAR3XX_ICM4_MII_SIZE		0x00800000
+
+#define SPEAR3XX_ICM4_USBD_FIFO_BASE	0xE1000000
+#define SPEAR3XX_ICM4_USBD_FIFO_SIZE	0x00100000
+
+#define SPEAR3XX_ICM4_USBD_CSR_BASE	0xE1100000
+#define SPEAR3XX_ICM4_USBD_CSR_SIZE	0x00100000
+
+#define SPEAR3XX_ICM4_USBD_PLDT_BASE	0xE1200000
+#define SPEAR3XX_ICM4_USBD_PLDT_SIZE	0x00100000
+
+#define SPEAR3XX_ICM4_USB_EHCI0_1_BASE	0xE1800000
+#define SPEAR3XX_ICM4_USB_EHCI0_1_SIZE	0x00100000
+
+#define SPEAR3XX_ICM4_USB_OHCI0_BASE	0xE1900000
+#define SPEAR3XX_ICM4_USB_OHCI0_SIZE	0x00100000
+
+#define SPEAR3XX_ICM4_USB_OHCI1_BASE	0xE2100000
+#define SPEAR3XX_ICM4_USB_OHCI1_SIZE	0x00100000
+
+#define SPEAR3XX_ICM4_USB_ARB_BASE	0xE2800000
+#define SPEAR3XX_ICM4_USB_ARB_SIZE	0x00010000
+
+/* ML1 - Multi Layer CPU Subsystem */
+#define SPEAR3XX_ICM3_ML1_2_BASE	0xF0000000
+#define SPEAR3XX_ICM3_ML1_2_SIZE	0x0F000000
+
+#define SPEAR3XX_ML1_TMR_BASE		0xF0000000
+#define SPEAR3XX_ML1_TMR_SIZE		0x00100000
+
+#define SPEAR3XX_ML1_VIC_BASE		0xF1100000
+#define VA_SPEAR3XX_ML1_VIC_BASE	IO_ADDRESS(SPEAR3XX_ML1_VIC_BASE)
+#define SPEAR3XX_ML1_VIC_SIZE		0x00100000
+
+/* ICM3 - Basic Subsystem */
+#define SPEAR3XX_ICM3_SMEM_BASE		0xF8000000
+#define SPEAR3XX_ICM3_SMEM_SIZE		0x04000000
+
+#define SPEAR3XX_ICM3_SMI_CTRL_BASE	0xFC000000
+#define SPEAR3XX_ICM3_SMI_CTRL_SIZE	0x00200000
+
+#define SPEAR3XX_ICM3_DMA_BASE		0xFC400000
+#define SPEAR3XX_ICM3_DMA_SIZE		0x00200000
+
+#define SPEAR3XX_ICM3_SDRAM_CTRL_BASE	0xFC600000
+#define SPEAR3XX_ICM3_SDRAM_CTRL_SIZE	0x00200000
+
+#define SPEAR3XX_ICM3_TMR0_BASE		0xFC800000
+#define SPEAR3XX_ICM3_TMR0_SIZE		0x00080000
+
+#define SPEAR3XX_ICM3_WDT_BASE		0xFC880000
+#define SPEAR3XX_ICM3_WDT_SIZE		0x00080000
+
+#define SPEAR3XX_ICM3_RTC_BASE		0xFC900000
+#define SPEAR3XX_ICM3_RTC_SIZE		0x00080000
+
+#define SPEAR3XX_ICM3_GPIO_BASE		0xFC980000
+#define SPEAR3XX_ICM3_GPIO_SIZE		0x00080000
+
+#define SPEAR3XX_ICM3_SYS_CTRL_BASE	0xFCA00000
+#define VA_SPEAR3XX_ICM3_SYS_CTRL_BASE	IO_ADDRESS(SPEAR3XX_ICM3_SYS_CTRL_BASE)
+#define SPEAR3XX_ICM3_SYS_CTRL_SIZE	0x00080000
+
+#define SPEAR3XX_ICM3_MISC_REG_BASE	0xFCA80000
+#define VA_SPEAR3XX_ICM3_MISC_REG_BASE	IO_ADDRESS(SPEAR3XX_ICM3_MISC_REG_BASE)
+#define SPEAR3XX_ICM3_MISC_REG_SIZE	0x00080000
+
+#define SPEAR3XX_ICM3_TMR1_BASE		0xFCB00000
+#define SPEAR3XX_ICM3_TMR1_SIZE		0x00080000
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE		SPEAR3XX_ICM1_UART_BASE
+#define VA_SPEAR_DBG_UART_BASE		VA_SPEAR3XX_ICM1_UART_BASE
+
+/* Sysctl base for spear platform */
+#define SPEAR_SYS_CTRL_BASE		SPEAR3XX_ICM3_SYS_CTRL_BASE
+#define VA_SPEAR_SYS_CTRL_BASE		VA_SPEAR3XX_ICM3_SYS_CTRL_BASE
+
+#endif /* __MACH_SPEAR3XX_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h
new file mode 100644
index 0000000..ccaa765
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/spear300.h
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear300.h
+ *
+ * SPEAr300 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifdef	CONFIG_MACH_SPEAR300
+
+#ifndef __MACH_SPEAR300_H
+#define __MACH_SPEAR300_H
+
+/* Base address of various IPs */
+#define SPEAR300_TELECOM_BASE		0x50000000
+#define SPEAR300_TELECOM_SIZE		0x10000000
+
+/* Interrupt registers offsets and masks */
+#define SPEAR300_TELECOM_REG_SIZE	0x00010000
+#define INT_ENB_MASK_REG		0x54
+#define INT_STS_MASK_REG		0x58
+#define IT_PERS_S_IRQ_MASK		(1 << 0)
+#define IT_CHANGE_S_IRQ_MASK		(1 << 1)
+#define I2S_IRQ_MASK			(1 << 2)
+#define TDM_IRQ_MASK			(1 << 3)
+#define CAMERA_L_IRQ_MASK		(1 << 4)
+#define CAMERA_F_IRQ_MASK		(1 << 5)
+#define CAMERA_V_IRQ_MASK		(1 << 6)
+#define KEYBOARD_IRQ_MASK		(1 << 7)
+#define GPIO1_IRQ_MASK			(1 << 8)
+
+#define SHIRQ_RAS1_MASK			0x1FF
+
+#define SPEAR300_CLCD_BASE		0x60000000
+#define SPEAR300_CLCD_SIZE		0x10000000
+
+#define SPEAR300_SDIO_BASE		0x70000000
+#define SPEAR300_SDIO_SIZE		0x10000000
+
+#define SPEAR300_NAND_0_BASE		0x80000000
+#define SPEAR300_NAND_0_SIZE		0x04000000
+
+#define SPEAR300_NAND_1_BASE		0x84000000
+#define SPEAR300_NAND_1_SIZE		0x04000000
+
+#define SPEAR300_NAND_2_BASE		0x88000000
+#define SPEAR300_NAND_2_SIZE		0x04000000
+
+#define SPEAR300_NAND_3_BASE		0x8c000000
+#define SPEAR300_NAND_3_SIZE		0x04000000
+
+#define SPEAR300_NOR_0_BASE		0x90000000
+#define SPEAR300_NOR_0_SIZE		0x01000000
+
+#define SPEAR300_NOR_1_BASE		0x91000000
+#define SPEAR300_NOR_1_SIZE		0x01000000
+
+#define SPEAR300_NOR_2_BASE		0x92000000
+#define SPEAR300_NOR_2_SIZE		0x01000000
+
+#define SPEAR300_NOR_3_BASE		0x93000000
+#define SPEAR300_NOR_3_SIZE		0x01000000
+
+#define SPEAR300_FSMC_BASE		0x94000000
+#define SPEAR300_FSMC_SIZE		0x05000000
+
+#define SPEAR300_SOC_CONFIG_BASE	0x99000000
+#define SPEAR300_SOC_CONFIG_SIZE	0x00000008
+
+#define SPEAR300_KEYBOARD_BASE		0xA0000000
+#define SPEAR300_KEYBOARD_SIZE		0x09000000
+
+#define SPEAR300_GPIO_BASE		0xA9000000
+#define SPEAR300_GPIO_SIZE		0x07000000
+
+#endif /* __MACH_SPEAR300_H */
+
+#endif /* CONFIG_MACH_SPEAR300 */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h
new file mode 100644
index 0000000..b27bb8a
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/spear310.h
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear310.h
+ *
+ * SPEAr310 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifdef	CONFIG_MACH_SPEAR310
+
+#ifndef __MACH_SPEAR310_H
+#define __MACH_SPEAR310_H
+
+#define SPEAR310_NAND_BASE		0x40000000
+#define SPEAR310_NAND_SIZE		0x04000000
+
+#define SPEAR310_FSMC_BASE		0x44000000
+#define SPEAR310_FSMC_SIZE		0x01000000
+
+#define SPEAR310_UART1_BASE		0xB2000000
+#define SPEAR310_UART2_BASE		0xB2080000
+#define SPEAR310_UART3_BASE		0xB2100000
+#define SPEAR310_UART4_BASE		0xB2180000
+#define SPEAR310_UART5_BASE		0xB2200000
+#define SPEAR310_UART_SIZE		0x00080000
+
+#define SPEAR310_HDLC_BASE		0xB2800000
+#define SPEAR310_HDLC_SIZE		0x00800000
+
+#define SPEAR310_RS485_0_BASE		0xB3000000
+#define SPEAR310_RS485_0_SIZE		0x00800000
+
+#define SPEAR310_RS485_1_BASE		0xB3800000
+#define SPEAR310_RS485_1_SIZE		0x00800000
+
+#define SPEAR310_SOC_CONFIG_BASE	0xB4000000
+#define SPEAR310_SOC_CONFIG_SIZE	0x00000070
+/* Interrupt registers offsets and masks */
+#define INT_STS_MASK_REG		0x04
+#define SMII0_IRQ_MASK			(1 << 0)
+#define SMII1_IRQ_MASK			(1 << 1)
+#define SMII2_IRQ_MASK			(1 << 2)
+#define SMII3_IRQ_MASK			(1 << 3)
+#define WAKEUP_SMII0_IRQ_MASK		(1 << 4)
+#define WAKEUP_SMII1_IRQ_MASK		(1 << 5)
+#define WAKEUP_SMII2_IRQ_MASK		(1 << 6)
+#define WAKEUP_SMII3_IRQ_MASK		(1 << 7)
+#define UART1_IRQ_MASK			(1 << 8)
+#define UART2_IRQ_MASK			(1 << 9)
+#define UART3_IRQ_MASK			(1 << 10)
+#define UART4_IRQ_MASK			(1 << 11)
+#define UART5_IRQ_MASK			(1 << 12)
+#define EMI_IRQ_MASK			(1 << 13)
+#define TDM_HDLC_IRQ_MASK		(1 << 14)
+#define RS485_0_IRQ_MASK		(1 << 15)
+#define RS485_1_IRQ_MASK		(1 << 16)
+
+#define SHIRQ_RAS1_MASK			0x000FF
+#define SHIRQ_RAS2_MASK			0x01F00
+#define SHIRQ_RAS3_MASK			0x02000
+#define SHIRQ_INTRCOMM_RAS_MASK		0x1C000
+
+#endif /* __MACH_SPEAR310_H */
+
+#endif /* CONFIG_MACH_SPEAR310 */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
new file mode 100644
index 0000000..cacf17a
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear320.h
+ *
+ * SPEAr320 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifdef	CONFIG_MACH_SPEAR320
+
+#ifndef __MACH_SPEAR320_H
+#define __MACH_SPEAR320_H
+
+#define SPEAR320_EMI_CTRL_BASE		0x40000000
+#define SPEAR320_EMI_CTRL_SIZE		0x08000000
+
+#define SPEAR320_FSMC_BASE		0x4C000000
+#define SPEAR320_FSMC_SIZE		0x01000000
+
+#define SPEAR320_I2S_BASE		0x60000000
+#define SPEAR320_I2S_SIZE		0x10000000
+
+#define SPEAR320_SDIO_BASE		0x70000000
+#define SPEAR320_SDIO_SIZE		0x10000000
+
+#define SPEAR320_CLCD_BASE		0x90000000
+#define SPEAR320_CLCD_SIZE		0x10000000
+
+#define SPEAR320_PAR_PORT_BASE		0xA0000000
+#define SPEAR320_PAR_PORT_SIZE		0x01000000
+
+#define SPEAR320_CAN0_BASE		0xA1000000
+#define SPEAR320_CAN0_SIZE		0x01000000
+
+#define SPEAR320_CAN1_BASE		0xA2000000
+#define SPEAR320_CAN1_SIZE		0x01000000
+
+#define SPEAR320_UART1_BASE		0xA3000000
+#define SPEAR320_UART2_BASE		0xA4000000
+#define SPEAR320_UART_SIZE		0x01000000
+
+#define SPEAR320_SSP0_BASE		0xA5000000
+#define SPEAR320_SSP0_SIZE		0x01000000
+
+#define SPEAR320_SSP1_BASE		0xA6000000
+#define SPEAR320_SSP1_SIZE		0x01000000
+
+#define SPEAR320_I2C_BASE		0xA7000000
+#define SPEAR320_I2C_SIZE		0x01000000
+
+#define SPEAR320_PWM_BASE		0xA8000000
+#define SPEAR320_PWM_SIZE		0x01000000
+
+#define SPEAR320_SMII0_BASE		0xAA000000
+#define SPEAR320_SMII0_SIZE		0x01000000
+
+#define SPEAR320_SMII1_BASE		0xAB000000
+#define SPEAR320_SMII1_SIZE		0x01000000
+
+#define SPEAR320_SOC_CONFIG_BASE	0xB4000000
+#define SPEAR320_SOC_CONFIG_SIZE	0x00000070
+/* Interrupt registers offsets and masks */
+#define INT_STS_MASK_REG		0x04
+#define INT_CLR_MASK_REG		0x04
+#define INT_ENB_MASK_REG		0x08
+#define GPIO_IRQ_MASK			(1 << 0)
+#define I2S_PLAY_IRQ_MASK		(1 << 1)
+#define I2S_REC_IRQ_MASK		(1 << 2)
+#define EMI_IRQ_MASK			(1 << 7)
+#define CLCD_IRQ_MASK			(1 << 8)
+#define SPP_IRQ_MASK			(1 << 9)
+#define SDIO_IRQ_MASK			(1 << 10)
+#define CAN_U_IRQ_MASK			(1 << 11)
+#define CAN_L_IRQ_MASK			(1 << 12)
+#define UART1_IRQ_MASK			(1 << 13)
+#define UART2_IRQ_MASK			(1 << 14)
+#define SSP1_IRQ_MASK			(1 << 15)
+#define SSP2_IRQ_MASK			(1 << 16)
+#define SMII0_IRQ_MASK			(1 << 17)
+#define MII1_SMII1_IRQ_MASK		(1 << 18)
+#define WAKEUP_SMII0_IRQ_MASK		(1 << 19)
+#define WAKEUP_MII1_SMII1_IRQ_MASK	(1 << 20)
+#define I2C1_IRQ_MASK			(1 << 21)
+
+#define SHIRQ_RAS1_MASK			0x000380
+#define SHIRQ_RAS3_MASK			0x000007
+#define SHIRQ_INTRCOMM_RAS_MASK		0x3FF800
+
+#endif /* __MACH_SPEAR320_H */
+
+#endif /* CONFIG_MACH_SPEAR320 */
diff --git a/arch/arm/mach-spear3xx/include/mach/system.h b/arch/arm/mach-spear3xx/include/mach/system.h
new file mode 100644
index 0000000..92cee63
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/system.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/system.h
+ *
+ * SPEAr3xx Machine family specific architecture functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <plat/system.h>
+
+#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/timex.h b/arch/arm/mach-spear3xx/include/mach/timex.h
new file mode 100644
index 0000000..a38cc9d
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/timex.h
+ *
+ * SPEAr3XX machine family specific timex definitions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+#include <plat/timex.h>
+
+#endif /* __MACH_TIMEX_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/uncompress.h b/arch/arm/mach-spear3xx/include/mach/uncompress.h
new file mode 100644
index 0000000..53ba8bb
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/uncompress.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <plat/uncompress.h>
+
+#endif /* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/vmalloc.h b/arch/arm/mach-spear3xx/include/mach/vmalloc.h
new file mode 100644
index 0000000..df977b3
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/vmalloc.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/vmalloc.h
+ *
+ * Defining Vmalloc area for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#include <plat/vmalloc.h>
+
+#endif /* __MACH_VMALLOC_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
new file mode 100644
index 0000000..3560f8c
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -0,0 +1,468 @@
+/*
+ * arch/arm/mach-spear3xx/spear300.c
+ *
+ * SPEAr300 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/types.h>
+#include <linux/amba/pl061.h>
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+#include <plat/shirq.h>
+
+/* pad multiplexing support */
+/* muxing registers */
+#define PAD_MUX_CONFIG_REG	0x00
+#define MODE_CONFIG_REG		0x04
+
+/* modes */
+#define NAND_MODE			(1 << 0)
+#define NOR_MODE			(1 << 1)
+#define PHOTO_FRAME_MODE		(1 << 2)
+#define LEND_IP_PHONE_MODE		(1 << 3)
+#define HEND_IP_PHONE_MODE		(1 << 4)
+#define LEND_WIFI_PHONE_MODE		(1 << 5)
+#define HEND_WIFI_PHONE_MODE		(1 << 6)
+#define ATA_PABX_WI2S_MODE		(1 << 7)
+#define ATA_PABX_I2S_MODE		(1 << 8)
+#define CAML_LCDW_MODE			(1 << 9)
+#define CAMU_LCD_MODE			(1 << 10)
+#define CAMU_WLCD_MODE			(1 << 11)
+#define CAML_LCD_MODE			(1 << 12)
+#define ALL_MODES			0x1FFF
+
+struct pmx_mode nand_mode = {
+	.id = NAND_MODE,
+	.name = "nand mode",
+	.mask = 0x00,
+};
+
+struct pmx_mode nor_mode = {
+	.id = NOR_MODE,
+	.name = "nor mode",
+	.mask = 0x01,
+};
+
+struct pmx_mode photo_frame_mode = {
+	.id = PHOTO_FRAME_MODE,
+	.name = "photo frame mode",
+	.mask = 0x02,
+};
+
+struct pmx_mode lend_ip_phone_mode = {
+	.id = LEND_IP_PHONE_MODE,
+	.name = "lend ip phone mode",
+	.mask = 0x03,
+};
+
+struct pmx_mode hend_ip_phone_mode = {
+	.id = HEND_IP_PHONE_MODE,
+	.name = "hend ip phone mode",
+	.mask = 0x04,
+};
+
+struct pmx_mode lend_wifi_phone_mode = {
+	.id = LEND_WIFI_PHONE_MODE,
+	.name = "lend wifi phone mode",
+	.mask = 0x05,
+};
+
+struct pmx_mode hend_wifi_phone_mode = {
+	.id = HEND_WIFI_PHONE_MODE,
+	.name = "hend wifi phone mode",
+	.mask = 0x06,
+};
+
+struct pmx_mode ata_pabx_wi2s_mode = {
+	.id = ATA_PABX_WI2S_MODE,
+	.name = "ata pabx wi2s mode",
+	.mask = 0x07,
+};
+
+struct pmx_mode ata_pabx_i2s_mode = {
+	.id = ATA_PABX_I2S_MODE,
+	.name = "ata pabx i2s mode",
+	.mask = 0x08,
+};
+
+struct pmx_mode caml_lcdw_mode = {
+	.id = CAML_LCDW_MODE,
+	.name = "caml lcdw mode",
+	.mask = 0x0C,
+};
+
+struct pmx_mode camu_lcd_mode = {
+	.id = CAMU_LCD_MODE,
+	.name = "camu lcd mode",
+	.mask = 0x0D,
+};
+
+struct pmx_mode camu_wlcd_mode = {
+	.id = CAMU_WLCD_MODE,
+	.name = "camu wlcd mode",
+	.mask = 0x0E,
+};
+
+struct pmx_mode caml_lcd_mode = {
+	.id = CAML_LCD_MODE,
+	.name = "caml lcd mode",
+	.mask = 0x0F,
+};
+
+/* devices */
+struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = {
+	{
+		.ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+			ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+		.mask = PMX_FIRDA_MASK,
+	},
+};
+
+struct pmx_dev pmx_fsmc_2_chips = {
+	.name = "fsmc_2_chips",
+	.modes = pmx_fsmc_2_chips_modes,
+	.mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = {
+	{
+		.ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+			ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+		.mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
+	},
+};
+
+struct pmx_dev pmx_fsmc_4_chips = {
+	.name = "fsmc_4_chips",
+	.modes = pmx_fsmc_4_chips_modes,
+	.mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_keyboard_modes[] = {
+	{
+		.ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
+			LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+			CAML_LCDW_MODE | CAMU_LCD_MODE | CAMU_WLCD_MODE |
+			CAML_LCD_MODE,
+		.mask = 0x0,
+	},
+};
+
+struct pmx_dev pmx_keyboard = {
+	.name = "keyboard",
+	.modes = pmx_keyboard_modes,
+	.mode_count = ARRAY_SIZE(pmx_keyboard_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_clcd_modes[] = {
+	{
+		.ids = PHOTO_FRAME_MODE,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK ,
+	}, {
+		.ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+			CAMU_LCD_MODE | CAML_LCD_MODE,
+		.mask = PMX_TIMER_3_4_MASK,
+	},
+};
+
+struct pmx_dev pmx_clcd = {
+	.name = "clcd",
+	.modes = pmx_clcd_modes,
+	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_gpio_modes[] = {
+	{
+		.ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE,
+		.mask = PMX_MII_MASK,
+	}, {
+		.ids = LEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE,
+		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+	}, {
+		.ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_WLCD_MODE,
+		.mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK,
+	}, {
+		.ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE,
+		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK,
+	}, {
+		.ids = ATA_PABX_WI2S_MODE,
+		.mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK
+			| PMX_UART0_MODEM_MASK,
+	},
+};
+
+struct pmx_dev pmx_telecom_gpio = {
+	.name = "telecom_gpio",
+	.modes = pmx_telecom_gpio_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_tdm_modes[] = {
+	{
+		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE
+			| HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE
+			| ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+			| CAMU_WLCD_MODE | CAML_LCD_MODE,
+		.mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+	},
+};
+
+struct pmx_dev pmx_telecom_tdm = {
+	.name = "telecom_tdm",
+	.modes = pmx_telecom_tdm_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = {
+	{
+		.ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
+			LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE
+			| ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE |
+			CAML_LCDW_MODE | CAML_LCD_MODE,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+	},
+};
+
+struct pmx_dev pmx_telecom_spi_cs_i2c_clk = {
+	.name = "telecom_spi_cs_i2c_clk",
+	.modes = pmx_telecom_spi_cs_i2c_clk_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_camera_modes[] = {
+	{
+		.ids = CAML_LCDW_MODE | CAML_LCD_MODE,
+		.mask = PMX_MII_MASK,
+	}, {
+		.ids = CAMU_LCD_MODE | CAMU_WLCD_MODE,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_telecom_camera = {
+	.name = "telecom_camera",
+	.modes = pmx_telecom_camera_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_camera_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_dac_modes[] = {
+	{
+		.ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+			| CAMU_WLCD_MODE | CAML_LCD_MODE,
+		.mask = PMX_TIMER_1_2_MASK,
+	},
+};
+
+struct pmx_dev pmx_telecom_dac = {
+	.name = "telecom_dac",
+	.modes = pmx_telecom_dac_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_dac_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_i2s_modes[] = {
+	{
+		.ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE
+			| LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+			ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+			| CAMU_WLCD_MODE | CAML_LCD_MODE,
+		.mask = PMX_UART0_MODEM_MASK,
+	},
+};
+
+struct pmx_dev pmx_telecom_i2s = {
+	.name = "telecom_i2s",
+	.modes = pmx_telecom_i2s_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = {
+	{
+		.ids = NAND_MODE | NOR_MODE,
+		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
+			PMX_TIMER_3_4_MASK,
+	},
+};
+
+struct pmx_dev pmx_telecom_boot_pins = {
+	.name = "telecom_boot_pins",
+	.modes = pmx_telecom_boot_pins_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_sdio_4bit_modes[] = {
+	{
+		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+			HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+			CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE |
+			ATA_PABX_I2S_MODE,
+		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+	},
+};
+
+struct pmx_dev pmx_telecom_sdio_4bit = {
+	.name = "telecom_sdio_4bit",
+	.modes = pmx_telecom_sdio_4bit_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_sdio_4bit_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_sdio_8bit_modes[] = {
+	{
+		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+			HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+			CAMU_WLCD_MODE | CAML_LCD_MODE,
+		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+			PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_telecom_sdio_8bit = {
+	.name = "telecom_sdio_8bit",
+	.modes = pmx_telecom_sdio_8bit_modes,
+	.mode_count = ARRAY_SIZE(pmx_telecom_sdio_8bit_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_gpio1_modes[] = {
+	{
+		.ids = PHOTO_FRAME_MODE,
+		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
+			PMX_TIMER_3_4_MASK,
+	},
+};
+
+struct pmx_dev pmx_gpio1 = {
+	.name = "arm gpio1",
+	.modes = pmx_gpio1_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpio1_modes),
+	.enb_on_reset = 1,
+};
+
+/* pmx driver structure */
+struct pmx_driver pmx_driver = {
+	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f},
+	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
+};
+
+/* Add spear300 specific devices here */
+/* arm gpio1 device registeration */
+static struct pl061_platform_data gpio1_plat_data = {
+	.gpio_base	= 8,
+	.irq_base	= SPEAR_GPIO1_INT_BASE,
+};
+
+struct amba_device gpio1_device = {
+	.dev = {
+		.init_name = "gpio1",
+		.platform_data = &gpio1_plat_data,
+	},
+	.res = {
+		.start = SPEAR300_GPIO_BASE,
+		.end = SPEAR300_GPIO_BASE + SPEAR300_GPIO_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {VIRQ_GPIO1, NO_IRQ},
+};
+
+/* spear3xx shared irq */
+struct shirq_dev_config shirq_ras1_config[] = {
+	{
+		.virq = VIRQ_IT_PERS_S,
+		.enb_mask = IT_PERS_S_IRQ_MASK,
+		.status_mask = IT_PERS_S_IRQ_MASK,
+	}, {
+		.virq = VIRQ_IT_CHANGE_S,
+		.enb_mask = IT_CHANGE_S_IRQ_MASK,
+		.status_mask = IT_CHANGE_S_IRQ_MASK,
+	}, {
+		.virq = VIRQ_I2S,
+		.enb_mask = I2S_IRQ_MASK,
+		.status_mask = I2S_IRQ_MASK,
+	}, {
+		.virq = VIRQ_TDM,
+		.enb_mask = TDM_IRQ_MASK,
+		.status_mask = TDM_IRQ_MASK,
+	}, {
+		.virq = VIRQ_CAMERA_L,
+		.enb_mask = CAMERA_L_IRQ_MASK,
+		.status_mask = CAMERA_L_IRQ_MASK,
+	}, {
+		.virq = VIRQ_CAMERA_F,
+		.enb_mask = CAMERA_F_IRQ_MASK,
+		.status_mask = CAMERA_F_IRQ_MASK,
+	}, {
+		.virq = VIRQ_CAMERA_V,
+		.enb_mask = CAMERA_V_IRQ_MASK,
+		.status_mask = CAMERA_V_IRQ_MASK,
+	}, {
+		.virq = VIRQ_KEYBOARD,
+		.enb_mask = KEYBOARD_IRQ_MASK,
+		.status_mask = KEYBOARD_IRQ_MASK,
+	}, {
+		.virq = VIRQ_GPIO1,
+		.enb_mask = GPIO1_IRQ_MASK,
+		.status_mask = GPIO1_IRQ_MASK,
+	},
+};
+
+struct spear_shirq shirq_ras1 = {
+	.irq = IRQ_GEN_RAS_1,
+	.dev_config = shirq_ras1_config,
+	.dev_count = ARRAY_SIZE(shirq_ras1_config),
+	.regs = {
+		.enb_reg = INT_ENB_MASK_REG,
+		.status_reg = INT_STS_MASK_REG,
+		.status_reg_mask = SHIRQ_RAS1_MASK,
+		.clear_reg = -1,
+	},
+};
+
+/* spear300 routines */
+void __init spear300_init(void)
+{
+	int ret = 0;
+
+	/* call spear3xx family common init function */
+	spear3xx_init();
+
+	/* shared irq registeration */
+	shirq_ras1.regs.base =
+		ioremap(SPEAR300_TELECOM_BASE, SPEAR300_TELECOM_REG_SIZE);
+	if (shirq_ras1.regs.base) {
+		ret = spear_shirq_register(&shirq_ras1);
+		if (ret)
+			printk(KERN_ERR "Error registering Shared IRQ\n");
+	}
+}
+
+void spear300_pmx_init(void)
+{
+	spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE,
+			SPEAR300_SOC_CONFIG_SIZE);
+}
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
new file mode 100644
index 0000000..bb21db1
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-spear3xx/spear300_evb.c
+ *
+ * SPEAr300 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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 <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+	/* spear3xx specific devices */
+	&pmx_i2c,
+	&pmx_ssp_cs,
+	&pmx_ssp,
+	&pmx_mii,
+	&pmx_uart0,
+
+	/* spear300 specific devices */
+	&pmx_fsmc_2_chips,
+	&pmx_clcd,
+	&pmx_telecom_sdio_4bit,
+	&pmx_gpio1,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+	/* spear3xx specific devices */
+	&gpio_device,
+	&uart_device,
+
+	/* spear300 specific devices */
+	&gpio1_device,
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+	/* spear3xx specific devices */
+
+	/* spear300 specific devices */
+};
+
+static void __init spear300_evb_init(void)
+{
+	unsigned int i;
+
+	/* call spear300 machine init function */
+	spear300_init();
+
+	/* padmux initialization */
+	pmx_driver.mode = &photo_frame_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
+	spear300_pmx_init();
+
+	/* Add Platform Devices */
+	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+	/* Add Amba Devices */
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+		amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR300, "ST-SPEAR300-EVB")
+	.boot_params	=	0x00000100,
+	.map_io		=	spear3xx_map_io,
+	.init_irq	=	spear3xx_init_irq,
+	.timer		=	&spear_sys_timer,
+	.init_machine	=	spear300_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
new file mode 100644
index 0000000..96a1ab8
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -0,0 +1,302 @@
+/*
+ * arch/arm/mach-spear3xx/spear310.c
+ *
+ * SPEAr310 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+#include <plat/shirq.h>
+
+/* pad multiplexing support */
+/* muxing registers */
+#define PAD_MUX_CONFIG_REG	0x08
+
+/* devices */
+struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_TIMER_3_4_MASK,
+	},
+};
+
+struct pmx_dev pmx_emi_cs_0_1_4_5 = {
+	.name = "emi_cs_0_1_4_5",
+	.modes = pmx_emi_cs_0_1_4_5_modes,
+	.mode_count = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_TIMER_1_2_MASK,
+	},
+};
+
+struct pmx_dev pmx_emi_cs_2_3 = {
+	.name = "emi_cs_2_3",
+	.modes = pmx_emi_cs_2_3_modes,
+	.mode_count = ARRAY_SIZE(pmx_emi_cs_2_3_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart1_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_FIRDA_MASK,
+	},
+};
+
+struct pmx_dev pmx_uart1 = {
+	.name = "uart1",
+	.modes = pmx_uart1_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart2_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_TIMER_1_2_MASK,
+	},
+};
+
+struct pmx_dev pmx_uart2 = {
+	.name = "uart2",
+	.modes = pmx_uart2_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_UART0_MODEM_MASK,
+	},
+};
+
+struct pmx_dev pmx_uart3_4_5 = {
+	.name = "uart3_4_5",
+	.modes = pmx_uart3_4_5_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart3_4_5_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_fsmc_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_SSP_CS_MASK,
+	},
+};
+
+struct pmx_dev pmx_fsmc = {
+	.name = "fsmc",
+	.modes = pmx_fsmc_modes,
+	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_rs485_0_1 = {
+	.name = "rs485_0_1",
+	.modes = pmx_rs485_0_1_modes,
+	.mode_count = ARRAY_SIZE(pmx_rs485_0_1_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_tdm0_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_tdm0 = {
+	.name = "tdm0",
+	.modes = pmx_tdm0_modes,
+	.mode_count = ARRAY_SIZE(pmx_tdm0_modes),
+	.enb_on_reset = 1,
+};
+
+/* pmx driver structure */
+struct pmx_driver pmx_driver = {
+	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
+};
+
+/* Add spear310 specific devices here */
+
+/* spear3xx shared irq */
+struct shirq_dev_config shirq_ras1_config[] = {
+	{
+		.virq = VIRQ_SMII0,
+		.status_mask = SMII0_IRQ_MASK,
+	}, {
+		.virq = VIRQ_SMII1,
+		.status_mask = SMII1_IRQ_MASK,
+	}, {
+		.virq = VIRQ_SMII2,
+		.status_mask = SMII2_IRQ_MASK,
+	}, {
+		.virq = VIRQ_SMII3,
+		.status_mask = SMII3_IRQ_MASK,
+	}, {
+		.virq = VIRQ_WAKEUP_SMII0,
+		.status_mask = WAKEUP_SMII0_IRQ_MASK,
+	}, {
+		.virq = VIRQ_WAKEUP_SMII1,
+		.status_mask = WAKEUP_SMII1_IRQ_MASK,
+	}, {
+		.virq = VIRQ_WAKEUP_SMII2,
+		.status_mask = WAKEUP_SMII2_IRQ_MASK,
+	}, {
+		.virq = VIRQ_WAKEUP_SMII3,
+		.status_mask = WAKEUP_SMII3_IRQ_MASK,
+	},
+};
+
+struct spear_shirq shirq_ras1 = {
+	.irq = IRQ_GEN_RAS_1,
+	.dev_config = shirq_ras1_config,
+	.dev_count = ARRAY_SIZE(shirq_ras1_config),
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = INT_STS_MASK_REG,
+		.status_reg_mask = SHIRQ_RAS1_MASK,
+		.clear_reg = -1,
+	},
+};
+
+struct shirq_dev_config shirq_ras2_config[] = {
+	{
+		.virq = VIRQ_UART1,
+		.status_mask = UART1_IRQ_MASK,
+	}, {
+		.virq = VIRQ_UART2,
+		.status_mask = UART2_IRQ_MASK,
+	}, {
+		.virq = VIRQ_UART3,
+		.status_mask = UART3_IRQ_MASK,
+	}, {
+		.virq = VIRQ_UART4,
+		.status_mask = UART4_IRQ_MASK,
+	}, {
+		.virq = VIRQ_UART5,
+		.status_mask = UART5_IRQ_MASK,
+	},
+};
+
+struct spear_shirq shirq_ras2 = {
+	.irq = IRQ_GEN_RAS_2,
+	.dev_config = shirq_ras2_config,
+	.dev_count = ARRAY_SIZE(shirq_ras2_config),
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = INT_STS_MASK_REG,
+		.status_reg_mask = SHIRQ_RAS2_MASK,
+		.clear_reg = -1,
+	},
+};
+
+struct shirq_dev_config shirq_ras3_config[] = {
+	{
+		.virq = VIRQ_EMI,
+		.status_mask = EMI_IRQ_MASK,
+	},
+};
+
+struct spear_shirq shirq_ras3 = {
+	.irq = IRQ_GEN_RAS_3,
+	.dev_config = shirq_ras3_config,
+	.dev_count = ARRAY_SIZE(shirq_ras3_config),
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = INT_STS_MASK_REG,
+		.status_reg_mask = SHIRQ_RAS3_MASK,
+		.clear_reg = -1,
+	},
+};
+
+struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+	{
+		.virq = VIRQ_TDM_HDLC,
+		.status_mask = TDM_HDLC_IRQ_MASK,
+	}, {
+		.virq = VIRQ_RS485_0,
+		.status_mask = RS485_0_IRQ_MASK,
+	}, {
+		.virq = VIRQ_RS485_1,
+		.status_mask = RS485_1_IRQ_MASK,
+	},
+};
+
+struct spear_shirq shirq_intrcomm_ras = {
+	.irq = IRQ_INTRCOMM_RAS_ARM,
+	.dev_config = shirq_intrcomm_ras_config,
+	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = INT_STS_MASK_REG,
+		.status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
+		.clear_reg = -1,
+	},
+};
+
+/* spear310 routines */
+void __init spear310_init(void)
+{
+	void __iomem *base;
+	int ret = 0;
+
+	/* call spear3xx family common init function */
+	spear3xx_init();
+
+	/* shared irq registeration */
+	base = ioremap(SPEAR310_SOC_CONFIG_BASE, SPEAR310_SOC_CONFIG_SIZE);
+	if (base) {
+		/* shirq 1 */
+		shirq_ras1.regs.base = base;
+		ret = spear_shirq_register(&shirq_ras1);
+		if (ret)
+			printk(KERN_ERR "Error registering Shared IRQ 1\n");
+
+		/* shirq 2 */
+		shirq_ras2.regs.base = base;
+		ret = spear_shirq_register(&shirq_ras2);
+		if (ret)
+			printk(KERN_ERR "Error registering Shared IRQ 2\n");
+
+		/* shirq 3 */
+		shirq_ras3.regs.base = base;
+		ret = spear_shirq_register(&shirq_ras3);
+		if (ret)
+			printk(KERN_ERR "Error registering Shared IRQ 3\n");
+
+		/* shirq 4 */
+		shirq_intrcomm_ras.regs.base = base;
+		ret = spear_shirq_register(&shirq_intrcomm_ras);
+		if (ret)
+			printk(KERN_ERR "Error registering Shared IRQ 4\n");
+	}
+}
+
+void spear310_pmx_init(void)
+{
+	spear_pmx_init(&pmx_driver, SPEAR310_SOC_CONFIG_BASE,
+			SPEAR310_SOC_CONFIG_SIZE);
+}
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
new file mode 100644
index 0000000..7facf66
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-spear3xx/spear310_evb.c
+ *
+ * SPEAr310 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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 <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+	/* spear3xx specific devices */
+	&pmx_i2c,
+	&pmx_ssp,
+	&pmx_gpio_pin0,
+	&pmx_gpio_pin1,
+	&pmx_gpio_pin2,
+	&pmx_gpio_pin3,
+	&pmx_gpio_pin4,
+	&pmx_gpio_pin5,
+	&pmx_uart0,
+
+	/* spear310 specific devices */
+	&pmx_emi_cs_0_1_4_5,
+	&pmx_emi_cs_2_3,
+	&pmx_uart1,
+	&pmx_uart2,
+	&pmx_uart3_4_5,
+	&pmx_fsmc,
+	&pmx_rs485_0_1,
+	&pmx_tdm0,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+	/* spear3xx specific devices */
+	&gpio_device,
+	&uart_device,
+
+	/* spear310 specific devices */
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+	/* spear3xx specific devices */
+
+	/* spear310 specific devices */
+};
+
+static void __init spear310_evb_init(void)
+{
+	unsigned int i;
+
+	/* call spear310 machine init function */
+	spear310_init();
+
+	/* padmux initialization */
+	pmx_driver.mode = NULL;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
+	spear310_pmx_init();
+
+	/* Add Platform Devices */
+	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+	/* Add Amba Devices */
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+		amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR310, "ST-SPEAR310-EVB")
+	.boot_params	=	0x00000100,
+	.map_io		=	spear3xx_map_io,
+	.init_irq	=	spear3xx_init_irq,
+	.timer		=	&spear_sys_timer,
+	.init_machine	=	spear310_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
new file mode 100644
index 0000000..6a121954
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -0,0 +1,549 @@
+/*
+ * arch/arm/mach-spear3xx/spear320.c
+ *
+ * SPEAr320 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+#include <plat/shirq.h>
+
+/* pad multiplexing support */
+/* muxing registers */
+#define PAD_MUX_CONFIG_REG	0x0C
+#define MODE_CONFIG_REG		0x10
+
+/* modes */
+#define AUTO_NET_SMII_MODE	(1 << 0)
+#define AUTO_NET_MII_MODE	(1 << 1)
+#define AUTO_EXP_MODE		(1 << 2)
+#define SMALL_PRINTERS_MODE	(1 << 3)
+#define ALL_MODES		0xF
+
+struct pmx_mode auto_net_smii_mode = {
+	.id = AUTO_NET_SMII_MODE,
+	.name = "Automation Networking SMII Mode",
+	.mask = 0x00,
+};
+
+struct pmx_mode auto_net_mii_mode = {
+	.id = AUTO_NET_MII_MODE,
+	.name = "Automation Networking MII Mode",
+	.mask = 0x01,
+};
+
+struct pmx_mode auto_exp_mode = {
+	.id = AUTO_EXP_MODE,
+	.name = "Automation Expanded Mode",
+	.mask = 0x02,
+};
+
+struct pmx_mode small_printers_mode = {
+	.id = SMALL_PRINTERS_MODE,
+	.name = "Small Printers Mode",
+	.mask = 0x03,
+};
+
+/* devices */
+struct pmx_dev_mode pmx_clcd_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE,
+		.mask = 0x0,
+	},
+};
+
+struct pmx_dev pmx_clcd = {
+	.name = "clcd",
+	.modes = pmx_clcd_modes,
+	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_emi_modes[] = {
+	{
+		.ids = AUTO_EXP_MODE,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+	},
+};
+
+struct pmx_dev pmx_emi = {
+	.name = "emi",
+	.modes = pmx_emi_modes,
+	.mode_count = ARRAY_SIZE(pmx_emi_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_fsmc_modes[] = {
+	{
+		.ids = ALL_MODES,
+		.mask = 0x0,
+	},
+};
+
+struct pmx_dev pmx_fsmc = {
+	.name = "fsmc",
+	.modes = pmx_fsmc_modes,
+	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_spp_modes[] = {
+	{
+		.ids = SMALL_PRINTERS_MODE,
+		.mask = 0x0,
+	},
+};
+
+struct pmx_dev pmx_spp = {
+	.name = "spp",
+	.modes = pmx_spp_modes,
+	.mode_count = ARRAY_SIZE(pmx_spp_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_sdio_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE |
+			SMALL_PRINTERS_MODE,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+	},
+};
+
+struct pmx_dev pmx_sdio = {
+	.name = "sdio",
+	.modes = pmx_sdio_modes,
+	.mode_count = ARRAY_SIZE(pmx_sdio_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_i2s_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mask = PMX_UART0_MODEM_MASK,
+	},
+};
+
+struct pmx_dev pmx_i2s = {
+	.name = "i2s",
+	.modes = pmx_i2s_modes,
+	.mode_count = ARRAY_SIZE(pmx_i2s_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart1_modes[] = {
+	{
+		.ids = ALL_MODES,
+		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
+	},
+};
+
+struct pmx_dev pmx_uart1 = {
+	.name = "uart1",
+	.modes = pmx_uart1_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart1_modem_modes[] = {
+	{
+		.ids = AUTO_EXP_MODE,
+		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK |
+			PMX_SSP_CS_MASK,
+	}, {
+		.ids = SMALL_PRINTERS_MODE,
+		.mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
+			PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
+	},
+};
+
+struct pmx_dev pmx_uart1_modem = {
+	.name = "uart1_modem",
+	.modes = pmx_uart1_modem_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart1_modem_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart2_modes[] = {
+	{
+		.ids = ALL_MODES,
+		.mask = PMX_FIRDA_MASK,
+	},
+};
+
+struct pmx_dev pmx_uart2 = {
+	.name = "uart2",
+	.modes = pmx_uart2_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_touchscreen_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE,
+		.mask = PMX_SSP_CS_MASK,
+	},
+};
+
+struct pmx_dev pmx_touchscreen = {
+	.name = "touchscreen",
+	.modes = pmx_touchscreen_modes,
+	.mode_count = ARRAY_SIZE(pmx_touchscreen_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_can_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE,
+		.mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+			PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+	},
+};
+
+struct pmx_dev pmx_can = {
+	.name = "can",
+	.modes = pmx_can_modes,
+	.mode_count = ARRAY_SIZE(pmx_can_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_sdio_led_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mask = PMX_SSP_CS_MASK,
+	},
+};
+
+struct pmx_dev pmx_sdio_led = {
+	.name = "sdio_led",
+	.modes = pmx_sdio_led_modes,
+	.mode_count = ARRAY_SIZE(pmx_sdio_led_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_pwm0_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mask = PMX_UART0_MODEM_MASK,
+	}, {
+		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_pwm0 = {
+	.name = "pwm0",
+	.modes = pmx_pwm0_modes,
+	.mode_count = ARRAY_SIZE(pmx_pwm0_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_pwm1_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mask = PMX_UART0_MODEM_MASK,
+	}, {
+		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_pwm1 = {
+	.name = "pwm1",
+	.modes = pmx_pwm1_modes,
+	.mode_count = ARRAY_SIZE(pmx_pwm1_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_pwm2_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+		.mask = PMX_SSP_CS_MASK,
+	}, {
+		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_pwm2 = {
+	.name = "pwm2",
+	.modes = pmx_pwm2_modes,
+	.mode_count = ARRAY_SIZE(pmx_pwm2_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_pwm3_modes[] = {
+	{
+		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_pwm3 = {
+	.name = "pwm3",
+	.modes = pmx_pwm3_modes,
+	.mode_count = ARRAY_SIZE(pmx_pwm3_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_ssp1_modes[] = {
+	{
+		.ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_ssp1 = {
+	.name = "ssp1",
+	.modes = pmx_ssp1_modes,
+	.mode_count = ARRAY_SIZE(pmx_ssp1_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_ssp2_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_ssp2 = {
+	.name = "ssp2",
+	.modes = pmx_ssp2_modes,
+	.mode_count = ARRAY_SIZE(pmx_ssp2_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_mii1_modes[] = {
+	{
+		.ids = AUTO_NET_MII_MODE,
+		.mask = 0x0,
+	},
+};
+
+struct pmx_dev pmx_mii1 = {
+	.name = "mii1",
+	.modes = pmx_mii1_modes,
+	.mode_count = ARRAY_SIZE(pmx_mii1_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_smii0_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_smii0 = {
+	.name = "smii0",
+	.modes = pmx_smii0_modes,
+	.mode_count = ARRAY_SIZE(pmx_smii0_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_smii1_modes[] = {
+	{
+		.ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_smii1 = {
+	.name = "smii1",
+	.modes = pmx_smii1_modes,
+	.mode_count = ARRAY_SIZE(pmx_smii1_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_i2c1_modes[] = {
+	{
+		.ids = AUTO_EXP_MODE,
+		.mask = 0x0,
+	},
+};
+
+struct pmx_dev pmx_i2c1 = {
+	.name = "i2c1",
+	.modes = pmx_i2c1_modes,
+	.mode_count = ARRAY_SIZE(pmx_i2c1_modes),
+	.enb_on_reset = 1,
+};
+
+/* pmx driver structure */
+struct pmx_driver pmx_driver = {
+	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007},
+	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
+};
+
+/* Add spear320 specific devices here */
+
+/* spear3xx shared irq */
+struct shirq_dev_config shirq_ras1_config[] = {
+	{
+		.virq = VIRQ_EMI,
+		.status_mask = EMI_IRQ_MASK,
+		.clear_mask = EMI_IRQ_MASK,
+	}, {
+		.virq = VIRQ_CLCD,
+		.status_mask = CLCD_IRQ_MASK,
+		.clear_mask = CLCD_IRQ_MASK,
+	}, {
+		.virq = VIRQ_SPP,
+		.status_mask = SPP_IRQ_MASK,
+		.clear_mask = SPP_IRQ_MASK,
+	},
+};
+
+struct spear_shirq shirq_ras1 = {
+	.irq = IRQ_GEN_RAS_1,
+	.dev_config = shirq_ras1_config,
+	.dev_count = ARRAY_SIZE(shirq_ras1_config),
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = INT_STS_MASK_REG,
+		.status_reg_mask = SHIRQ_RAS1_MASK,
+		.clear_reg = INT_CLR_MASK_REG,
+		.reset_to_clear = 1,
+	},
+};
+
+struct shirq_dev_config shirq_ras3_config[] = {
+	{
+		.virq = VIRQ_PLGPIO,
+		.enb_mask = GPIO_IRQ_MASK,
+		.status_mask = GPIO_IRQ_MASK,
+		.clear_mask = GPIO_IRQ_MASK,
+	}, {
+		.virq = VIRQ_I2S_PLAY,
+		.enb_mask = I2S_PLAY_IRQ_MASK,
+		.status_mask = I2S_PLAY_IRQ_MASK,
+		.clear_mask = I2S_PLAY_IRQ_MASK,
+	}, {
+		.virq = VIRQ_I2S_REC,
+		.enb_mask = I2S_REC_IRQ_MASK,
+		.status_mask = I2S_REC_IRQ_MASK,
+		.clear_mask = I2S_REC_IRQ_MASK,
+	},
+};
+
+struct spear_shirq shirq_ras3 = {
+	.irq = IRQ_GEN_RAS_3,
+	.dev_config = shirq_ras3_config,
+	.dev_count = ARRAY_SIZE(shirq_ras3_config),
+	.regs = {
+		.enb_reg = INT_ENB_MASK_REG,
+		.reset_to_enb = 1,
+		.status_reg = INT_STS_MASK_REG,
+		.status_reg_mask = SHIRQ_RAS3_MASK,
+		.clear_reg = INT_CLR_MASK_REG,
+		.reset_to_clear = 1,
+	},
+};
+
+struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+	{
+		.virq = VIRQ_CANU,
+		.status_mask = CAN_U_IRQ_MASK,
+		.clear_mask = CAN_U_IRQ_MASK,
+	}, {
+		.virq = VIRQ_CANL,
+		.status_mask = CAN_L_IRQ_MASK,
+		.clear_mask = CAN_L_IRQ_MASK,
+	}, {
+		.virq = VIRQ_UART1,
+		.status_mask = UART1_IRQ_MASK,
+		.clear_mask = UART1_IRQ_MASK,
+	}, {
+		.virq = VIRQ_UART2,
+		.status_mask = UART2_IRQ_MASK,
+		.clear_mask = UART2_IRQ_MASK,
+	}, {
+		.virq = VIRQ_SSP1,
+		.status_mask = SSP1_IRQ_MASK,
+		.clear_mask = SSP1_IRQ_MASK,
+	}, {
+		.virq = VIRQ_SSP2,
+		.status_mask = SSP2_IRQ_MASK,
+		.clear_mask = SSP2_IRQ_MASK,
+	}, {
+		.virq = VIRQ_SMII0,
+		.status_mask = SMII0_IRQ_MASK,
+		.clear_mask = SMII0_IRQ_MASK,
+	}, {
+		.virq = VIRQ_MII1_SMII1,
+		.status_mask = MII1_SMII1_IRQ_MASK,
+		.clear_mask = MII1_SMII1_IRQ_MASK,
+	}, {
+		.virq = VIRQ_WAKEUP_SMII0,
+		.status_mask = WAKEUP_SMII0_IRQ_MASK,
+		.clear_mask = WAKEUP_SMII0_IRQ_MASK,
+	}, {
+		.virq = VIRQ_WAKEUP_MII1_SMII1,
+		.status_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
+		.clear_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
+	}, {
+		.virq = VIRQ_I2C,
+		.status_mask = I2C1_IRQ_MASK,
+		.clear_mask = I2C1_IRQ_MASK,
+	},
+};
+
+struct spear_shirq shirq_intrcomm_ras = {
+	.irq = IRQ_INTRCOMM_RAS_ARM,
+	.dev_config = shirq_intrcomm_ras_config,
+	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = INT_STS_MASK_REG,
+		.status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
+		.clear_reg = INT_CLR_MASK_REG,
+		.reset_to_clear = 1,
+	},
+};
+
+/* spear320 routines */
+void __init spear320_init(void)
+{
+	void __iomem *base;
+	int ret = 0;
+
+	/* call spear3xx family common init function */
+	spear3xx_init();
+
+	/* shared irq registeration */
+	base = ioremap(SPEAR320_SOC_CONFIG_BASE, SPEAR320_SOC_CONFIG_SIZE);
+	if (base) {
+		/* shirq 1 */
+		shirq_ras1.regs.base = base;
+		ret = spear_shirq_register(&shirq_ras1);
+		if (ret)
+			printk(KERN_ERR "Error registering Shared IRQ 1\n");
+
+		/* shirq 3 */
+		shirq_ras3.regs.base = base;
+		ret = spear_shirq_register(&shirq_ras3);
+		if (ret)
+			printk(KERN_ERR "Error registering Shared IRQ 3\n");
+
+		/* shirq 4 */
+		shirq_intrcomm_ras.regs.base = base;
+		ret = spear_shirq_register(&shirq_intrcomm_ras);
+		if (ret)
+			printk(KERN_ERR "Error registering Shared IRQ 4\n");
+	}
+}
+
+void spear320_pmx_init(void)
+{
+	spear_pmx_init(&pmx_driver, SPEAR320_SOC_CONFIG_BASE,
+			SPEAR320_SOC_CONFIG_SIZE);
+}
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
new file mode 100644
index 0000000..62ac685
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/mach-spear3xx/spear320_evb.c
+ *
+ * SPEAr320 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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 <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+	/* spear3xx specific devices */
+	&pmx_i2c,
+	&pmx_ssp,
+	&pmx_mii,
+	&pmx_uart0,
+
+	/* spear320 specific devices */
+	&pmx_fsmc,
+	&pmx_sdio,
+	&pmx_i2s,
+	&pmx_uart1,
+	&pmx_uart2,
+	&pmx_can,
+	&pmx_pwm0,
+	&pmx_pwm1,
+	&pmx_pwm2,
+	&pmx_mii1,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+	/* spear3xx specific devices */
+	&gpio_device,
+	&uart_device,
+
+	/* spear320 specific devices */
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+	/* spear3xx specific devices */
+
+	/* spear320 specific devices */
+};
+
+static void __init spear320_evb_init(void)
+{
+	unsigned int i;
+
+	/* call spear320 machine init function */
+	spear320_init();
+
+	/* padmux initialization */
+	pmx_driver.mode = &auto_net_mii_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
+	spear320_pmx_init();
+
+	/* Add Platform Devices */
+	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+	/* Add Amba Devices */
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+		amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR320, "ST-SPEAR320-EVB")
+	.boot_params	=	0x00000100,
+	.map_io		=	spear3xx_map_io,
+	.init_irq	=	spear3xx_init_irq,
+	.timer		=	&spear_sys_timer,
+	.init_machine	=	spear320_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
new file mode 100644
index 0000000..e87313a
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -0,0 +1,548 @@
+/*
+ * arch/arm/mach-spear3xx/spear3xx.c
+ *
+ * SPEAr3XX machines common source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/types.h>
+#include <linux/amba/pl061.h>
+#include <linux/ptrace.h>
+#include <linux/io.h>
+#include <asm/hardware/vic.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* Add spear3xx machines common devices here */
+/* gpio device registeration */
+static struct pl061_platform_data gpio_plat_data = {
+	.gpio_base	= 0,
+	.irq_base	= SPEAR_GPIO_INT_BASE,
+};
+
+struct amba_device gpio_device = {
+	.dev = {
+		.init_name = "gpio",
+		.platform_data = &gpio_plat_data,
+	},
+	.res = {
+		.start = SPEAR3XX_ICM3_GPIO_BASE,
+		.end = SPEAR3XX_ICM3_GPIO_BASE + SPEAR3XX_ICM3_GPIO_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_BASIC_GPIO, NO_IRQ},
+};
+
+/* uart device registeration */
+struct amba_device uart_device = {
+	.dev = {
+		.init_name = "uart",
+	},
+	.res = {
+		.start = SPEAR3XX_ICM1_UART_BASE,
+		.end = SPEAR3XX_ICM1_UART_BASE + SPEAR3XX_ICM1_UART_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_UART, NO_IRQ},
+};
+
+/* Do spear3xx familiy common initialization part here */
+void __init spear3xx_init(void)
+{
+	/* nothing to do for now */
+}
+
+/* This will initialize vic */
+void __init spear3xx_init_irq(void)
+{
+	vic_init((void __iomem *)VA_SPEAR3XX_ML1_VIC_BASE, 0, ~0, 0);
+}
+
+/* Following will create static virtual/physical mappings */
+struct map_desc spear3xx_io_desc[] __initdata = {
+	{
+		.virtual	= VA_SPEAR3XX_ICM1_UART_BASE,
+		.pfn		= __phys_to_pfn(SPEAR3XX_ICM1_UART_BASE),
+		.length		= SPEAR3XX_ICM1_UART_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= VA_SPEAR3XX_ML1_VIC_BASE,
+		.pfn		= __phys_to_pfn(SPEAR3XX_ML1_VIC_BASE),
+		.length		= SPEAR3XX_ML1_VIC_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= VA_SPEAR3XX_ICM3_SYS_CTRL_BASE,
+		.pfn		= __phys_to_pfn(SPEAR3XX_ICM3_SYS_CTRL_BASE),
+		.length		= SPEAR3XX_ICM3_SYS_CTRL_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= VA_SPEAR3XX_ICM3_MISC_REG_BASE,
+		.pfn		= __phys_to_pfn(SPEAR3XX_ICM3_MISC_REG_BASE),
+		.length		= SPEAR3XX_ICM3_MISC_REG_SIZE,
+		.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));
+
+	/* This will initialize clock framework */
+	clk_init();
+}
+
+/* pad multiplexing support */
+/* devices */
+struct pmx_dev_mode pmx_firda_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_FIRDA_MASK,
+	},
+};
+
+struct pmx_dev pmx_firda = {
+	.name = "firda",
+	.modes = pmx_firda_modes,
+	.mode_count = ARRAY_SIZE(pmx_firda_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_i2c_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_I2C_MASK,
+	},
+};
+
+struct pmx_dev pmx_i2c = {
+	.name = "i2c",
+	.modes = pmx_i2c_modes,
+	.mode_count = ARRAY_SIZE(pmx_i2c_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_ssp_cs_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_SSP_CS_MASK,
+	},
+};
+
+struct pmx_dev pmx_ssp_cs = {
+	.name = "ssp_chip_selects",
+	.modes = pmx_ssp_cs_modes,
+	.mode_count = ARRAY_SIZE(pmx_ssp_cs_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_ssp_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_SSP_MASK,
+	},
+};
+
+struct pmx_dev pmx_ssp = {
+	.name = "ssp",
+	.modes = pmx_ssp_modes,
+	.mode_count = ARRAY_SIZE(pmx_ssp_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_mii_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_mii = {
+	.name = "mii",
+	.modes = pmx_mii_modes,
+	.mode_count = ARRAY_SIZE(pmx_mii_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_GPIO_PIN0_MASK,
+	},
+};
+
+struct pmx_dev pmx_gpio_pin0 = {
+	.name = "gpio_pin0",
+	.modes = pmx_gpio_pin0_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_GPIO_PIN1_MASK,
+	},
+};
+
+struct pmx_dev pmx_gpio_pin1 = {
+	.name = "gpio_pin1",
+	.modes = pmx_gpio_pin1_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_GPIO_PIN2_MASK,
+	},
+};
+
+struct pmx_dev pmx_gpio_pin2 = {
+	.name = "gpio_pin2",
+	.modes = pmx_gpio_pin2_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_GPIO_PIN3_MASK,
+	},
+};
+
+struct pmx_dev pmx_gpio_pin3 = {
+	.name = "gpio_pin3",
+	.modes = pmx_gpio_pin3_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_GPIO_PIN4_MASK,
+	},
+};
+
+struct pmx_dev pmx_gpio_pin4 = {
+	.name = "gpio_pin4",
+	.modes = pmx_gpio_pin4_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_GPIO_PIN5_MASK,
+	},
+};
+
+struct pmx_dev pmx_gpio_pin5 = {
+	.name = "gpio_pin5",
+	.modes = pmx_gpio_pin5_modes,
+	.mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_uart0_modem_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_UART0_MODEM_MASK,
+	},
+};
+
+struct pmx_dev pmx_uart0_modem = {
+	.name = "uart0_modem",
+	.modes = pmx_uart0_modem_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart0_modem_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_uart0_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_UART0_MASK,
+	},
+};
+
+struct pmx_dev pmx_uart0 = {
+	.name = "uart0",
+	.modes = pmx_uart0_modes,
+	.mode_count = ARRAY_SIZE(pmx_uart0_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_timer_3_4_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_TIMER_3_4_MASK,
+	},
+};
+
+struct pmx_dev pmx_timer_3_4 = {
+	.name = "timer_3_4",
+	.modes = pmx_timer_3_4_modes,
+	.mode_count = ARRAY_SIZE(pmx_timer_3_4_modes),
+	.enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_timer_1_2_modes[] = {
+	{
+		.ids = 0xffffffff,
+		.mask = PMX_TIMER_1_2_MASK,
+	},
+};
+
+struct pmx_dev pmx_timer_1_2 = {
+	.name = "timer_1_2",
+	.modes = pmx_timer_1_2_modes,
+	.mode_count = ARRAY_SIZE(pmx_timer_1_2_modes),
+	.enb_on_reset = 0,
+};
+
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* plgpios devices */
+struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_FIRDA_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_0_1 = {
+	.name = "plgpio 0 and 1",
+	.modes = pmx_plgpio_0_1_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_0_1_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_UART0_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_2_3 = {
+	.name = "plgpio 2 and 3",
+	.modes = pmx_plgpio_2_3_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_2_3_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_I2C_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_4_5 = {
+	.name = "plgpio 4 and 5",
+	.modes = pmx_plgpio_4_5_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_4_5_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_SSP_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_6_9 = {
+	.name = "plgpio 6 to 9",
+	.modes = pmx_plgpio_6_9_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_6_9_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_MII_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_10_27 = {
+	.name = "plgpio 10 to 27",
+	.modes = pmx_plgpio_10_27_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_10_27_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_28_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_GPIO_PIN0_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_28 = {
+	.name = "plgpio 28",
+	.modes = pmx_plgpio_28_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_28_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_29_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_GPIO_PIN1_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_29 = {
+	.name = "plgpio 29",
+	.modes = pmx_plgpio_29_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_29_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_30_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_GPIO_PIN2_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_30 = {
+	.name = "plgpio 30",
+	.modes = pmx_plgpio_30_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_30_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_31_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_GPIO_PIN3_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_31 = {
+	.name = "plgpio 31",
+	.modes = pmx_plgpio_31_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_31_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_32_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_GPIO_PIN4_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_32 = {
+	.name = "plgpio 32",
+	.modes = pmx_plgpio_32_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_32_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_33_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_GPIO_PIN5_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_33 = {
+	.name = "plgpio 33",
+	.modes = pmx_plgpio_33_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_33_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_SSP_CS_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_34_36 = {
+	.name = "plgpio 34 to 36",
+	.modes = pmx_plgpio_34_36_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_34_36_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_UART0_MODEM_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_37_42 = {
+	.name = "plgpio 37 to 42",
+	.modes = pmx_plgpio_37_42_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_37_42_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_TIMER_1_2_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_43_44_47_48 = {
+	.name = "plgpio 43, 44, 47 and 48",
+	.modes = pmx_plgpio_43_44_47_48_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_43_44_47_48_modes),
+	.enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
+	{
+		.ids = 0x00,
+		.mask = PMX_TIMER_3_4_MASK,
+	},
+};
+
+struct pmx_dev pmx_plgpio_45_46_49_50 = {
+	.name = "plgpio 45, 46, 49 and 50",
+	.modes = pmx_plgpio_45_46_49_50_modes,
+	.mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes),
+	.enb_on_reset = 1,
+};
+
+#endif
+
+/* spear padmux initialization function */
+void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size)
+{
+	int ret = 0;
+
+	/* pad mux initialization */
+	pmx_driver->base = ioremap(base, size);
+	if (!pmx_driver->base) {
+		ret = -ENOMEM;
+		goto pmx_fail;
+	}
+
+	ret = pmx_register(pmx_driver);
+	iounmap(pmx_driver->base);
+
+pmx_fail:
+	if (ret)
+		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
+				ret);
+}
diff --git a/arch/arm/mach-spear6xx/Kconfig b/arch/arm/mach-spear6xx/Kconfig
new file mode 100644
index 0000000..bddba03
--- /dev/null
+++ b/arch/arm/mach-spear6xx/Kconfig
@@ -0,0 +1,20 @@
+#
+# SPEAr6XX Machine configuration file
+#
+
+if ARCH_SPEAR6XX
+
+choice
+	prompt "SPEAr6XX Family"
+	default MACH_SPEAR600
+
+config MACH_SPEAR600
+	bool "SPEAr600"
+	help
+	  Supports ST SPEAr600 Machine
+endchoice
+
+# Adding SPEAr6XX machine specific configuration files
+source "arch/arm/mach-spear6xx/Kconfig600"
+
+endif #ARCH_SPEAR6XX
diff --git a/arch/arm/mach-spear6xx/Kconfig600 b/arch/arm/mach-spear6xx/Kconfig600
new file mode 100644
index 0000000..9e19f65
--- /dev/null
+++ b/arch/arm/mach-spear6xx/Kconfig600
@@ -0,0 +1,17 @@
+#
+# SPEAr600 machine configuration file
+#
+
+if MACH_SPEAR600
+
+choice
+	prompt "SPEAr600 Boards"
+	default BOARD_SPEAR600_EVB
+
+config	BOARD_SPEAR600_EVB
+	bool "SPEAr600 Evaluation Board"
+	help
+	  Supports ST SPEAr600 Evaluation Board
+endchoice
+
+endif	#MACH_SPEAR600
diff --git a/arch/arm/mach-spear6xx/Makefile b/arch/arm/mach-spear6xx/Makefile
new file mode 100644
index 0000000..cc1a4d8
--- /dev/null
+++ b/arch/arm/mach-spear6xx/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for SPEAr6XX machine series
+#
+
+# common files
+obj-y	+= clock.o spear6xx.o
+
+# spear600 specific files
+obj-$(CONFIG_MACH_SPEAR600) += spear600.o
+
+# spear600 boards files
+obj-$(CONFIG_BOARD_SPEAR600_EVB) += spear600_evb.o
diff --git a/arch/arm/mach-spear6xx/Makefile.boot b/arch/arm/mach-spear6xx/Makefile.boot
new file mode 100644
index 0000000..7a1f3c0
--- /dev/null
+++ b/arch/arm/mach-spear6xx/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
new file mode 100644
index 0000000..13e27c7
--- /dev/null
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -0,0 +1,483 @@
+/*
+ * arch/arm/mach-spear6xx/clock.c
+ *
+ * SPEAr6xx machines clock framework source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/init.h>
+#include <linux/kernel.h>
+#include <mach/misc_regs.h>
+#include <plat/clock.h>
+
+/* root clks */
+/* 32 KHz oscillator clock */
+static struct clk osc_32k_clk = {
+	.flags = ALWAYS_ENABLED,
+	.rate = 32000,
+};
+
+/* 30 MHz oscillator clock */
+static struct clk osc_30m_clk = {
+	.flags = ALWAYS_ENABLED,
+	.rate = 30000000,
+};
+
+/* clock derived from 32 KHz osc clk */
+/* rtc clock */
+static struct clk rtc_clk = {
+	.pclk = &osc_32k_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = RTC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from 30 MHz osc clk */
+/* pll1 configuration structure */
+static struct pll_clk_config pll1_config = {
+	.mode_reg = PLL1_CTR,
+	.cfg_reg = PLL1_FRQ,
+};
+
+/* PLL1 clock */
+static struct clk pll1_clk = {
+	.pclk = &osc_30m_clk,
+	.en_reg = PLL1_CTR,
+	.en_reg_bit = PLL_ENABLE,
+	.recalc = &pll1_clk_recalc,
+	.private_data = &pll1_config,
+};
+
+/* PLL3 48 MHz clock */
+static struct clk pll3_48m_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &osc_30m_clk,
+	.rate = 48000000,
+};
+
+/* watch dog timer clock */
+static struct clk wdt_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &osc_30m_clk,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from pll1 clk */
+/* cpu clock */
+static struct clk cpu_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.recalc = &follow_parent,
+};
+
+/* ahb configuration structure */
+static struct bus_clk_config ahb_config = {
+	.reg = CORE_CLK_CFG,
+	.mask = PLL_HCLK_RATIO_MASK,
+	.shift = PLL_HCLK_RATIO_SHIFT,
+};
+
+/* ahb clock */
+static struct clk ahb_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &pll1_clk,
+	.recalc = &bus_clk_recalc,
+	.private_data = &ahb_config,
+};
+
+/* uart parents */
+static struct pclk_info uart_pclk_info[] = {
+	{
+		.pclk = &pll1_clk,
+		.pclk_mask = AUX_CLK_PLL1_MASK,
+		.scalable = 1,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_mask = AUX_CLK_PLL3_MASK,
+		.scalable = 0,
+	},
+};
+
+/* uart parent select structure */
+static struct pclk_sel uart_pclk_sel = {
+	.pclk_info = uart_pclk_info,
+	.pclk_count = ARRAY_SIZE(uart_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = UART_CLK_MASK,
+};
+
+/* uart configurations */
+static struct aux_clk_config uart_config = {
+	.synth_reg = UART_CLK_SYNT,
+};
+
+/* uart0 clock */
+static struct clk uart0_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = UART0_CLK_ENB,
+	.pclk_sel = &uart_pclk_sel,
+	.pclk_sel_shift = UART_CLK_SHIFT,
+	.recalc = &aux_clk_recalc,
+	.private_data = &uart_config,
+};
+
+/* uart1 clock */
+static struct clk uart1_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = UART1_CLK_ENB,
+	.pclk_sel = &uart_pclk_sel,
+	.pclk_sel_shift = UART_CLK_SHIFT,
+	.recalc = &aux_clk_recalc,
+	.private_data = &uart_config,
+};
+
+/* firda configurations */
+static struct aux_clk_config firda_config = {
+	.synth_reg = FIRDA_CLK_SYNT,
+};
+
+/* firda parents */
+static struct pclk_info firda_pclk_info[] = {
+	{
+		.pclk = &pll1_clk,
+		.pclk_mask = AUX_CLK_PLL1_MASK,
+		.scalable = 1,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_mask = AUX_CLK_PLL3_MASK,
+		.scalable = 0,
+	},
+};
+
+/* firda parent select structure */
+static struct pclk_sel firda_pclk_sel = {
+	.pclk_info = firda_pclk_info,
+	.pclk_count = ARRAY_SIZE(firda_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = FIRDA_CLK_MASK,
+};
+
+/* firda clock */
+static struct clk firda_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = FIRDA_CLK_ENB,
+	.pclk_sel = &firda_pclk_sel,
+	.pclk_sel_shift = FIRDA_CLK_SHIFT,
+	.recalc = &aux_clk_recalc,
+	.private_data = &firda_config,
+};
+
+/* clcd configurations */
+static struct aux_clk_config clcd_config = {
+	.synth_reg = CLCD_CLK_SYNT,
+};
+
+/* clcd parents */
+static struct pclk_info clcd_pclk_info[] = {
+	{
+		.pclk = &pll1_clk,
+		.pclk_mask = AUX_CLK_PLL1_MASK,
+		.scalable = 1,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_mask = AUX_CLK_PLL3_MASK,
+		.scalable = 0,
+	},
+};
+
+/* clcd parent select structure */
+static struct pclk_sel clcd_pclk_sel = {
+	.pclk_info = clcd_pclk_info,
+	.pclk_count = ARRAY_SIZE(clcd_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = CLCD_CLK_MASK,
+};
+
+/* clcd clock */
+static struct clk clcd_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = CLCD_CLK_ENB,
+	.pclk_sel = &clcd_pclk_sel,
+	.pclk_sel_shift = CLCD_CLK_SHIFT,
+	.recalc = &aux_clk_recalc,
+	.private_data = &clcd_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt_pclk_info[] = {
+	{
+		.pclk = &pll1_clk,
+		.pclk_mask = AUX_CLK_PLL1_MASK,
+		.scalable = 1,
+	}, {
+		.pclk = &pll3_48m_clk,
+		.pclk_mask = AUX_CLK_PLL3_MASK,
+		.scalable = 0,
+	},
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt_pclk_sel = {
+	.pclk_info = gpt_pclk_info,
+	.pclk_count = ARRAY_SIZE(gpt_pclk_info),
+	.pclk_sel_reg = PERIP_CLK_CFG,
+	.pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt0_1 configurations */
+static struct aux_clk_config gpt0_1_config = {
+	.synth_reg = PRSC1_CLK_CFG,
+};
+
+/* gpt0 ARM1 subsystem timer clock */
+static struct clk gpt0_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT0_CLK_SHIFT,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt0_1_config,
+};
+
+/* gpt1 timer clock */
+static struct clk gpt1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT1_CLK_SHIFT,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt0_1_config,
+};
+
+/* gpt2 configurations */
+static struct aux_clk_config gpt2_config = {
+	.synth_reg = PRSC2_CLK_CFG,
+};
+
+/* gpt2 timer clock */
+static struct clk gpt2_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPT2_CLK_ENB,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT2_CLK_SHIFT,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt2_config,
+};
+
+/* gpt3 configurations */
+static struct aux_clk_config gpt3_config = {
+	.synth_reg = PRSC3_CLK_CFG,
+};
+
+/* gpt3 timer clock */
+static struct clk gpt3_clk = {
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPT3_CLK_ENB,
+	.pclk_sel = &gpt_pclk_sel,
+	.pclk_sel_shift = GPT3_CLK_SHIFT,
+	.recalc = &gpt_clk_recalc,
+	.private_data = &gpt3_config,
+};
+
+/* clock derived from pll3 clk */
+/* usbh0 clock */
+static struct clk usbh0_clk = {
+	.pclk = &pll3_48m_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = USBH0_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* usbh1 clock */
+static struct clk usbh1_clk = {
+	.pclk = &pll3_48m_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = USBH1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* usbd clock */
+static struct clk usbd_clk = {
+	.pclk = &pll3_48m_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = USBD_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from ahb clk */
+/* apb configuration structure */
+static struct bus_clk_config apb_config = {
+	.reg = CORE_CLK_CFG,
+	.mask = HCLK_PCLK_RATIO_MASK,
+	.shift = HCLK_PCLK_RATIO_SHIFT,
+};
+
+/* apb clock */
+static struct clk apb_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &ahb_clk,
+	.recalc = &bus_clk_recalc,
+	.private_data = &apb_config,
+};
+
+/* i2c clock */
+static struct clk i2c_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = I2C_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* dma clock */
+static struct clk dma_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = DMA_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* jpeg clock */
+static struct clk jpeg_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = JPEG_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* gmac clock */
+static struct clk gmac_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GMAC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* smi clock */
+static struct clk smi_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SMI_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* fsmc clock */
+static struct clk fsmc_clk = {
+	.pclk = &ahb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = FSMC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* clock derived from apb clk */
+/* adc clock */
+static struct clk adc_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = ADC_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* ssp0 clock */
+static struct clk ssp0_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SSP0_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* ssp1 clock */
+static struct clk ssp1_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SSP1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* ssp2 clock */
+static struct clk ssp2_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = SSP2_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* gpio0 ARM subsystem clock */
+static struct clk gpio0_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &apb_clk,
+	.recalc = &follow_parent,
+};
+
+/* gpio1 clock */
+static struct clk gpio1_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPIO1_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* gpio2 clock */
+static struct clk gpio2_clk = {
+	.pclk = &apb_clk,
+	.en_reg = PERIP1_CLK_ENB,
+	.en_reg_bit = GPIO2_CLK_ENB,
+	.recalc = &follow_parent,
+};
+
+/* array of all spear 6xx clock lookups */
+static struct clk_lookup spear_clk_lookups[] = {
+	/* root clks */
+	{ .con_id = "osc_32k_clk",	.clk = &osc_32k_clk},
+	{ .con_id = "osc_30m_clk",	.clk = &osc_30m_clk},
+	/* clock derived from 32 KHz os		 clk */
+	{ .dev_id = "rtc",		.clk = &rtc_clk},
+	/* clock derived from 30 MHz os		 clk */
+	{ .con_id = "pll1_clk",		.clk = &pll1_clk},
+	{ .con_id = "pll3_48m_clk",	.clk = &pll3_48m_clk},
+	{ .dev_id = "wdt",		.clk = &wdt_clk},
+	/* clock derived from pll1 clk */
+	{ .con_id = "cpu_clk",		.clk = &cpu_clk},
+	{ .con_id = "ahb_clk",		.clk = &ahb_clk},
+	{ .dev_id = "uart0",		.clk = &uart0_clk},
+	{ .dev_id = "uart1",		.clk = &uart1_clk},
+	{ .dev_id = "firda",		.clk = &firda_clk},
+	{ .dev_id = "clcd",		.clk = &clcd_clk},
+	{ .dev_id = "gpt0",		.clk = &gpt0_clk},
+	{ .dev_id = "gpt1",		.clk = &gpt1_clk},
+	{ .dev_id = "gpt2",		.clk = &gpt2_clk},
+	{ .dev_id = "gpt3",		.clk = &gpt3_clk},
+	/* clock derived from pll3 clk */
+	{ .dev_id = "usbh0",		.clk = &usbh0_clk},
+	{ .dev_id = "usbh1",		.clk = &usbh1_clk},
+	{ .dev_id = "usbd",		.clk = &usbd_clk},
+	/* clock derived from ahb clk */
+	{ .con_id = "apb_clk",		.clk = &apb_clk},
+	{ .dev_id = "i2c",		.clk = &i2c_clk},
+	{ .dev_id = "dma",		.clk = &dma_clk},
+	{ .dev_id = "jpeg",		.clk = &jpeg_clk},
+	{ .dev_id = "gmac",		.clk = &gmac_clk},
+	{ .dev_id = "smi",		.clk = &smi_clk},
+	{ .dev_id = "fsmc",		.clk = &fsmc_clk},
+	/* clock derived from apb clk */
+	{ .dev_id = "adc",		.clk = &adc_clk},
+	{ .dev_id = "ssp0",		.clk = &ssp0_clk},
+	{ .dev_id = "ssp1",		.clk = &ssp1_clk},
+	{ .dev_id = "ssp2",		.clk = &ssp2_clk},
+	{ .dev_id = "gpio0",		.clk = &gpio0_clk},
+	{ .dev_id = "gpio1",		.clk = &gpio1_clk},
+	{ .dev_id = "gpio2",		.clk = &gpio2_clk},
+};
+
+void __init clk_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+		clk_register(&spear_clk_lookups[i]);
+
+	recalc_root_clocks();
+}
diff --git a/arch/arm/mach-spear6xx/include/mach/clkdev.h b/arch/arm/mach-spear6xx/include/mach/clkdev.h
new file mode 100644
index 0000000..05676bf
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/clkdev.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/clkdev.h
+ *
+ * Clock Dev framework definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+#include <plat/clkdev.h>
+
+#endif /* __MACH_CLKDEV_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/debug-macro.S b/arch/arm/mach-spear6xx/include/mach/debug-macro.S
new file mode 100644
index 0000000..0f3ea39
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/debug-macro.S
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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 <plat/debug-macro.S>
diff --git a/arch/arm/mach-spear6xx/include/mach/entry-macro.S b/arch/arm/mach-spear6xx/include/mach/entry-macro.S
new file mode 100644
index 0000000..9eaecae
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/entry-macro.S
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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 <mach/hardware.h>
+#include <mach/spear.h>
+#include <asm/hardware/vic.h>
+
+		.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
+		ldr	\base, =VA_SPEAR6XX_CPU_VIC_PRI_BASE
+		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get status
+		mov	\irqnr, #0
+		teq	\irqstat, #0
+		bne	1001f
+		ldr	\base, =VA_SPEAR6XX_CPU_VIC_SEC_BASE
+		ldr	\irqstat, [\base, #VIC_IRQ_STATUS]	@ get status
+		teq	\irqstat, #0
+		beq	1002f				@ this will set/reset
+							@ zero register
+		mov	\irqnr, #32
+1001:
+		/*
+		 * Following code will find bit position of least significang
+		 * bit set in irqstat, using following equation
+		 * least significant bit set in n = (n & ~(n-1))
+		 */
+		sub	\tmp, \irqstat, #1		@ tmp = irqstat - 1
+		mvn	\tmp, \tmp			@ tmp = ~tmp
+		and	\irqstat, \irqstat, \tmp	@ irqstat &= tmp
+		/* Now, irqstat is = bit no. of 1st bit set in vic irq status */
+		clz	\tmp, \irqstat			@ tmp = leading zeros
+
+		rsb	\tmp, \tmp, #0x1F		@ tmp = 32 - tmp - 1
+		add	\irqnr, \irqnr, \tmp
+
+1002:		/* EQ will be set if no irqs pending */
+		.endm
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
new file mode 100644
index 0000000..16205a5
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/generic.h
+ *
+ * SPEAr6XX machine family specific generic header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+
+/*
+ * Each GPT has 2 timer channels
+ * Following GPT channels will be used as clock source and clockevent
+ */
+#define SPEAR_GPT0_BASE		SPEAR6XX_CPU_TMR_BASE
+#define SPEAR_GPT0_CHAN0_IRQ	IRQ_CPU_GPT1_1
+#define SPEAR_GPT0_CHAN1_IRQ	IRQ_CPU_GPT1_2
+
+/* Add spear6xx family device structure declarations here */
+extern struct amba_device gpio_device[];
+extern struct amba_device uart_device[];
+extern struct sys_timer spear_sys_timer;
+
+/* Add spear6xx family function declarations here */
+void __init spear6xx_map_io(void);
+void __init spear6xx_init_irq(void);
+void __init spear6xx_init(void);
+void __init spear600_init(void);
+void __init clk_init(void);
+
+/* Add spear600 machine device structure declarations here */
+
+#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/gpio.h b/arch/arm/mach-spear6xx/include/mach/gpio.h
new file mode 100644
index 0000000..3a789db
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/gpio.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/gpio.h
+ *
+ * GPIO macros for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_GPIO_H
+#define __MACH_GPIO_H
+
+#include <plat/gpio.h>
+
+#endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/hardware.h b/arch/arm/mach-spear6xx/include/mach/hardware.h
new file mode 100644
index 0000000..7545116
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/hardware.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/hardware.h
+ *
+ * Hardware definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/* Vitual to physical translation of statically mapped space */
+#define IO_ADDRESS(x)		(x | 0xF0000000)
+
+#endif /* __MACH_HARDWARE_H */
+
diff --git a/arch/arm/mach-spear6xx/include/mach/io.h b/arch/arm/mach-spear6xx/include/mach/io.h
new file mode 100644
index 0000000..fb7c106
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/io.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/io.h
+ *
+ * IO definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#include <plat/io.h>
+
+#endif	/* __MACH_IO_H */
+
diff --git a/arch/arm/mach-spear6xx/include/mach/irqs.h b/arch/arm/mach-spear6xx/include/mach/irqs.h
new file mode 100644
index 0000000..8f214b0
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/irqs.h
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/irqs.h
+ *
+ * IRQ helper macros for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+/* IRQ definitions */
+/* VIC 1 */
+#define IRQ_INTRCOMM_SW_IRQ			0
+#define IRQ_INTRCOMM_CPU_1			1
+#define IRQ_INTRCOMM_CPU_2			2
+#define IRQ_INTRCOMM_RAS2A11_1			3
+#define IRQ_INTRCOMM_RAS2A11_2			4
+#define IRQ_INTRCOMM_RAS2A12_1			5
+#define IRQ_INTRCOMM_RAS2A12_2			6
+#define IRQ_GEN_RAS_0				7
+#define IRQ_GEN_RAS_1				8
+#define IRQ_GEN_RAS_2				9
+#define IRQ_GEN_RAS_3				10
+#define IRQ_GEN_RAS_4				11
+#define IRQ_GEN_RAS_5				12
+#define IRQ_GEN_RAS_6				13
+#define IRQ_GEN_RAS_7				14
+#define IRQ_GEN_RAS_8				15
+#define IRQ_CPU_GPT1_1				16
+#define IRQ_CPU_GPT1_2				17
+#define IRQ_LOCAL_GPIO				18
+#define IRQ_PLL_UNLOCK				19
+#define IRQ_JPEG				20
+#define IRQ_FSMC				21
+#define IRQ_IRDA				22
+#define IRQ_RESERVED				23
+#define IRQ_UART_0				24
+#define IRQ_UART_1				25
+#define IRQ_SSP_1				26
+#define IRQ_SSP_2				27
+#define IRQ_I2C					28
+#define IRQ_GEN_RAS_9				29
+#define IRQ_GEN_RAS_10				30
+#define IRQ_GEN_RAS_11				31
+
+/* VIC 2 */
+#define IRQ_APPL_GPT1_1				32
+#define IRQ_APPL_GPT1_2				33
+#define IRQ_APPL_GPT2_1				34
+#define IRQ_APPL_GPT2_2				35
+#define IRQ_APPL_GPIO				36
+#define IRQ_APPL_SSP				37
+#define IRQ_APPL_ADC				38
+#define IRQ_APPL_RESERVED			39
+#define IRQ_AHB_EXP_MASTER			40
+#define IRQ_DDR_CONTROLLER			41
+#define IRQ_BASIC_DMA				42
+#define IRQ_BASIC_RESERVED1			43
+#define IRQ_BASIC_SMI				44
+#define IRQ_BASIC_CLCD				45
+#define IRQ_EXP_AHB_1				46
+#define IRQ_EXP_AHB_2				47
+#define IRQ_BASIC_GPT1_1			48
+#define IRQ_BASIC_GPT1_2			49
+#define IRQ_BASIC_RTC				50
+#define IRQ_BASIC_GPIO				51
+#define IRQ_BASIC_WDT				52
+#define IRQ_BASIC_RESERVED			53
+#define IRQ_AHB_EXP_SLAVE			54
+#define IRQ_GMAC_1				55
+#define IRQ_GMAC_2				56
+#define IRQ_USB_DEV				57
+#define IRQ_USB_H_OHCI_0			58
+#define IRQ_USB_H_EHCI_0			59
+#define IRQ_USB_H_OHCI_1			60
+#define IRQ_USB_H_EHCI_1			61
+#define IRQ_EXP_AHB_3				62
+#define IRQ_EXP_AHB_4				63
+
+#define IRQ_VIC_END				64
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE	IRQ_VIC_END
+#define SPEAR_GPIO0_INT_BASE	SPEAR_GPIO_INT_BASE
+#define SPEAR_GPIO1_INT_BASE	(SPEAR_GPIO0_INT_BASE + 8)
+#define SPEAR_GPIO2_INT_BASE	(SPEAR_GPIO1_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END	(SPEAR_GPIO2_INT_BASE + 8)
+#define VIRTUAL_IRQS		(SPEAR_GPIO_INT_END - IRQ_VIC_END)
+#define NR_IRQS			(IRQ_VIC_END + VIRTUAL_IRQS)
+
+#endif	/* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/memory.h b/arch/arm/mach-spear6xx/include/mach/memory.h
new file mode 100644
index 0000000..781f088
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/memory.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/memory.h
+ *
+ * Memory map for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#include <plat/memory.h>
+
+#endif	/* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
new file mode 100644
index 0000000..0390803
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
@@ -0,0 +1,173 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/misc_regs.h
+ *
+ * Miscellaneous registers definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __MACH_MISC_REGS_H
+#define __MACH_MISC_REGS_H
+
+#include <mach/spear.h>
+
+#define MISC_BASE		VA_SPEAR6XX_ICM3_MISC_REG_BASE
+
+#define SOC_CFG_CTR		((unsigned int *)(MISC_BASE + 0x000))
+#define DIAG_CFG_CTR		((unsigned int *)(MISC_BASE + 0x004))
+#define PLL1_CTR		((unsigned int *)(MISC_BASE + 0x008))
+#define PLL1_FRQ		((unsigned int *)(MISC_BASE + 0x00C))
+#define PLL1_MOD		((unsigned int *)(MISC_BASE + 0x010))
+#define PLL2_CTR		((unsigned int *)(MISC_BASE + 0x014))
+/* PLL_CTR register masks */
+#define PLL_ENABLE		2
+#define PLL_MODE_SHIFT		4
+#define PLL_MODE_MASK		0x3
+#define PLL_MODE_NORMAL		0
+#define PLL_MODE_FRACTION	1
+#define PLL_MODE_DITH_DSB	2
+#define PLL_MODE_DITH_SSB	3
+
+#define PLL2_FRQ		((unsigned int *)(MISC_BASE + 0x018))
+/* PLL FRQ register masks */
+#define PLL_DIV_N_SHIFT		0
+#define PLL_DIV_N_MASK		0xFF
+#define PLL_DIV_P_SHIFT		8
+#define PLL_DIV_P_MASK		0x7
+#define PLL_NORM_FDBK_M_SHIFT	24
+#define PLL_NORM_FDBK_M_MASK	0xFF
+#define PLL_DITH_FDBK_M_SHIFT	16
+#define PLL_DITH_FDBK_M_MASK	0xFFFF
+
+#define PLL2_MOD		((unsigned int *)(MISC_BASE + 0x01C))
+#define PLL_CLK_CFG		((unsigned int *)(MISC_BASE + 0x020))
+#define CORE_CLK_CFG		((unsigned int *)(MISC_BASE + 0x024))
+/* CORE CLK CFG register masks */
+#define PLL_HCLK_RATIO_SHIFT	10
+#define PLL_HCLK_RATIO_MASK	0x3
+#define HCLK_PCLK_RATIO_SHIFT	8
+#define HCLK_PCLK_RATIO_MASK	0x3
+
+#define PERIP_CLK_CFG		((unsigned int *)(MISC_BASE + 0x028))
+/* PERIP_CLK_CFG register masks */
+#define CLCD_CLK_SHIFT		2
+#define CLCD_CLK_MASK		0x3
+#define UART_CLK_SHIFT		4
+#define UART_CLK_MASK		0x1
+#define FIRDA_CLK_SHIFT		5
+#define FIRDA_CLK_MASK		0x3
+#define GPT0_CLK_SHIFT		8
+#define GPT1_CLK_SHIFT		10
+#define GPT2_CLK_SHIFT		11
+#define GPT3_CLK_SHIFT		12
+#define GPT_CLK_MASK		0x1
+#define AUX_CLK_PLL3_MASK	0
+#define AUX_CLK_PLL1_MASK	1
+
+#define PERIP1_CLK_ENB		((unsigned int *)(MISC_BASE + 0x02C))
+/* PERIP1_CLK_ENB register masks */
+#define UART0_CLK_ENB		3
+#define UART1_CLK_ENB		4
+#define SSP0_CLK_ENB		5
+#define SSP1_CLK_ENB		6
+#define I2C_CLK_ENB		7
+#define JPEG_CLK_ENB		8
+#define FSMC_CLK_ENB		9
+#define FIRDA_CLK_ENB		10
+#define GPT2_CLK_ENB		11
+#define GPT3_CLK_ENB		12
+#define GPIO2_CLK_ENB		13
+#define SSP2_CLK_ENB		14
+#define ADC_CLK_ENB		15
+#define GPT1_CLK_ENB		11
+#define RTC_CLK_ENB		17
+#define GPIO1_CLK_ENB		18
+#define DMA_CLK_ENB		19
+#define SMI_CLK_ENB		21
+#define CLCD_CLK_ENB		22
+#define GMAC_CLK_ENB		23
+#define USBD_CLK_ENB		24
+#define USBH0_CLK_ENB		25
+#define USBH1_CLK_ENB		26
+
+#define SOC_CORE_ID		((unsigned int *)(MISC_BASE + 0x030))
+#define RAS_CLK_ENB		((unsigned int *)(MISC_BASE + 0x034))
+#define PERIP1_SOF_RST		((unsigned int *)(MISC_BASE + 0x038))
+/* PERIP1_SOF_RST register masks */
+#define JPEG_SOF_RST		8
+
+#define SOC_USER_ID		((unsigned int *)(MISC_BASE + 0x03C))
+#define RAS_SOF_RST		((unsigned int *)(MISC_BASE + 0x040))
+#define PRSC1_CLK_CFG		((unsigned int *)(MISC_BASE + 0x044))
+#define PRSC2_CLK_CFG		((unsigned int *)(MISC_BASE + 0x048))
+#define PRSC3_CLK_CFG		((unsigned int *)(MISC_BASE + 0x04C))
+/* gpt synthesizer register masks */
+#define GPT_MSCALE_SHIFT	0
+#define GPT_MSCALE_MASK		0xFFF
+#define GPT_NSCALE_SHIFT	12
+#define GPT_NSCALE_MASK		0xF
+
+#define AMEM_CLK_CFG		((unsigned int *)(MISC_BASE + 0x050))
+#define EXPI_CLK_CFG		((unsigned int *)(MISC_BASE + 0x054))
+#define CLCD_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x05C))
+#define FIRDA_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x060))
+#define UART_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x064))
+#define GMAC_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x068))
+#define RAS1_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x06C))
+#define RAS2_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x070))
+#define RAS3_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x074))
+#define RAS4_CLK_SYNT		((unsigned int *)(MISC_BASE + 0x078))
+/* aux clk synthesiser register masks for irda to ras4 */
+#define AUX_EQ_SEL_SHIFT	30
+#define AUX_EQ_SEL_MASK		1
+#define AUX_EQ1_SEL		0
+#define AUX_EQ2_SEL		1
+#define AUX_XSCALE_SHIFT	16
+#define AUX_XSCALE_MASK		0xFFF
+#define AUX_YSCALE_SHIFT	0
+#define AUX_YSCALE_MASK		0xFFF
+
+#define ICM1_ARB_CFG		((unsigned int *)(MISC_BASE + 0x07C))
+#define ICM2_ARB_CFG		((unsigned int *)(MISC_BASE + 0x080))
+#define ICM3_ARB_CFG		((unsigned int *)(MISC_BASE + 0x084))
+#define ICM4_ARB_CFG		((unsigned int *)(MISC_BASE + 0x088))
+#define ICM5_ARB_CFG		((unsigned int *)(MISC_BASE + 0x08C))
+#define ICM6_ARB_CFG		((unsigned int *)(MISC_BASE + 0x090))
+#define ICM7_ARB_CFG		((unsigned int *)(MISC_BASE + 0x094))
+#define ICM8_ARB_CFG		((unsigned int *)(MISC_BASE + 0x098))
+#define ICM9_ARB_CFG		((unsigned int *)(MISC_BASE + 0x09C))
+#define DMA_CHN_CFG		((unsigned int *)(MISC_BASE + 0x0A0))
+#define USB2_PHY_CFG		((unsigned int *)(MISC_BASE + 0x0A4))
+#define GMAC_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0A8))
+#define EXPI_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0AC))
+#define PRC1_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x0C0))
+#define PRC2_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x0C4))
+#define PRC3_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x0C8))
+#define PRC4_LOCK_CTR		((unsigned int *)(MISC_BASE + 0x0CC))
+#define PRC1_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x0D0))
+#define PRC2_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x0D4))
+#define PRC3_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x0D8))
+#define PRC4_IRQ_CTR		((unsigned int *)(MISC_BASE + 0x0DC))
+#define PWRDOWN_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0E0))
+#define COMPSSTL_1V8_CFG	((unsigned int *)(MISC_BASE + 0x0E4))
+#define COMPSSTL_2V5_CFG	((unsigned int *)(MISC_BASE + 0x0E8))
+#define COMPCOR_3V3_CFG		((unsigned int *)(MISC_BASE + 0x0EC))
+#define SSTLPAD_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0F0))
+#define BIST1_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0F4))
+#define BIST2_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0F8))
+#define BIST3_CFG_CTR		((unsigned int *)(MISC_BASE + 0x0FC))
+#define BIST4_CFG_CTR		((unsigned int *)(MISC_BASE + 0x100))
+#define BIST5_CFG_CTR		((unsigned int *)(MISC_BASE + 0x104))
+#define BIST1_STS_RES		((unsigned int *)(MISC_BASE + 0x108))
+#define BIST2_STS_RES		((unsigned int *)(MISC_BASE + 0x10C))
+#define BIST3_STS_RES		((unsigned int *)(MISC_BASE + 0x110))
+#define BIST4_STS_RES		((unsigned int *)(MISC_BASE + 0x114))
+#define BIST5_STS_RES		((unsigned int *)(MISC_BASE + 0x118))
+#define SYSERR_CFG_CTR		((unsigned int *)(MISC_BASE + 0x11C))
+
+#endif /* __MACH_MISC_REGS_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/spear.h b/arch/arm/mach-spear6xx/include/mach/spear.h
new file mode 100644
index 0000000..a835f5b
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/spear.h
@@ -0,0 +1,173 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/spear.h
+ *
+ * SPEAr6xx Machine family specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_SPEAR6XX_H
+#define __MACH_SPEAR6XX_H
+
+#include <mach/hardware.h>
+#include <mach/spear600.h>
+
+#define SPEAR6XX_ML_SDRAM_BASE		0x00000000
+#define SPEAR6XX_ML_SDRAM_SIZE		0x40000000
+
+/* ICM1 - Low speed connection */
+#define SPEAR6XX_ICM1_BASE		0xD0000000
+#define SPEAR6XX_ICM1_SIZE		0x08000000
+
+#define SPEAR6XX_ICM1_UART0_BASE	0xD0000000
+#define VA_SPEAR6XX_ICM1_UART0_BASE	IO_ADDRESS(SPEAR6XX_ICM1_UART0_BASE)
+#define SPEAR6XX_ICM1_UART0_SIZE	0x00080000
+
+#define SPEAR6XX_ICM1_UART1_BASE	0xD0080000
+#define SPEAR6XX_ICM1_UART1_SIZE	0x00080000
+
+#define SPEAR6XX_ICM1_SSP0_BASE		0xD0100000
+#define SPEAR6XX_ICM1_SSP0_SIZE		0x00080000
+
+#define SPEAR6XX_ICM1_SSP1_BASE		0xD0180000
+#define SPEAR6XX_ICM1_SSP1_SIZE		0x00080000
+
+#define SPEAR6XX_ICM1_I2C_BASE		0xD0200000
+#define SPEAR6XX_ICM1_I2C_SIZE		0x00080000
+
+#define SPEAR6XX_ICM1_JPEG_BASE		0xD0800000
+#define SPEAR6XX_ICM1_JPEG_SIZE		0x00800000
+
+#define SPEAR6XX_ICM1_IRDA_BASE		0xD1000000
+#define SPEAR6XX_ICM1_IRDA_SIZE		0x00800000
+
+#define SPEAR6XX_ICM1_FSMC_BASE		0xD1800000
+#define SPEAR6XX_ICM1_FSMC_SIZE		0x00800000
+
+#define SPEAR6XX_ICM1_NAND_BASE		0xD2000000
+#define SPEAR6XX_ICM1_NAND_SIZE		0x00800000
+
+#define SPEAR6XX_ICM1_SRAM_BASE		0xD2800000
+#define SPEAR6XX_ICM1_SRAM_SIZE		0x00800000
+
+/* ICM2 - Application Subsystem */
+#define SPEAR6XX_ICM2_BASE		0xD8000000
+#define SPEAR6XX_ICM2_SIZE		0x08000000
+
+#define SPEAR6XX_ICM2_TMR0_BASE		0xD8000000
+#define SPEAR6XX_ICM2_TMR0_SIZE		0x00080000
+
+#define SPEAR6XX_ICM2_TMR1_BASE		0xD8080000
+#define SPEAR6XX_ICM2_TMR1_SIZE		0x00080000
+
+#define SPEAR6XX_ICM2_GPIO_BASE		0xD8100000
+#define SPEAR6XX_ICM2_GPIO_SIZE		0x00080000
+
+#define SPEAR6XX_ICM2_SPI2_BASE		0xD8180000
+#define SPEAR6XX_ICM2_SPI2_SIZE		0x00080000
+
+#define SPEAR6XX_ICM2_ADC_BASE		0xD8200000
+#define SPEAR6XX_ICM2_ADC_SIZE		0x00080000
+
+/* ML-1, 2 - Multi Layer CPU Subsystem */
+#define SPEAR6XX_ML_CPU_BASE		0xF0000000
+#define SPEAR6XX_ML_CPU_SIZE		0x08000000
+
+#define SPEAR6XX_CPU_TMR_BASE		0xF0000000
+#define SPEAR6XX_CPU_TMR_SIZE		0x00100000
+
+#define SPEAR6XX_CPU_GPIO_BASE		0xF0100000
+#define SPEAR6XX_CPU_GPIO_SIZE		0x00100000
+
+#define SPEAR6XX_CPU_VIC_SEC_BASE	0xF1000000
+#define VA_SPEAR6XX_CPU_VIC_SEC_BASE	IO_ADDRESS(SPEAR6XX_CPU_VIC_SEC_BASE)
+#define SPEAR6XX_CPU_VIC_SEC_SIZE	0x00100000
+
+#define SPEAR6XX_CPU_VIC_PRI_BASE	0xF1100000
+#define VA_SPEAR6XX_CPU_VIC_PRI_BASE	IO_ADDRESS(SPEAR6XX_CPU_VIC_PRI_BASE)
+#define SPEAR6XX_CPU_VIC_PRI_SIZE	0x00100000
+
+/* ICM3 - Basic Subsystem */
+#define SPEAR6XX_ICM3_BASE		0xF8000000
+#define SPEAR6XX_ICM3_SIZE		0x08000000
+
+#define SPEAR6XX_ICM3_SMEM_BASE		0xF8000000
+#define SPEAR6XX_ICM3_SMEM_SIZE		0x04000000
+
+#define SPEAR6XX_ICM3_SMI_CTRL_BASE	0xFC000000
+#define SPEAR6XX_ICM3_SMI_CTRL_SIZE	0x00200000
+
+#define SPEAR6XX_ICM3_CLCD_BASE		0xFC200000
+#define SPEAR6XX_ICM3_CLCD_SIZE		0x00200000
+
+#define SPEAR6XX_ICM3_DMA_BASE		0xFC400000
+#define SPEAR6XX_ICM3_DMA_SIZE		0x00200000
+
+#define SPEAR6XX_ICM3_SDRAM_CTRL_BASE	0xFC600000
+#define SPEAR6XX_ICM3_SDRAM_CTRL_SIZE	0x00200000
+
+#define SPEAR6XX_ICM3_TMR_BASE		0xFC800000
+#define SPEAR6XX_ICM3_TMR_SIZE		0x00080000
+
+#define SPEAR6XX_ICM3_WDT_BASE		0xFC880000
+#define SPEAR6XX_ICM3_WDT_SIZE		0x00080000
+
+#define SPEAR6XX_ICM3_RTC_BASE		0xFC900000
+#define SPEAR6XX_ICM3_RTC_SIZE		0x00080000
+
+#define SPEAR6XX_ICM3_GPIO_BASE		0xFC980000
+#define SPEAR6XX_ICM3_GPIO_SIZE		0x00080000
+
+#define SPEAR6XX_ICM3_SYS_CTRL_BASE	0xFCA00000
+#define VA_SPEAR6XX_ICM3_SYS_CTRL_BASE	IO_ADDRESS(SPEAR6XX_ICM3_SYS_CTRL_BASE)
+#define SPEAR6XX_ICM3_SYS_CTRL_SIZE	0x00080000
+
+#define SPEAR6XX_ICM3_MISC_REG_BASE	0xFCA80000
+#define VA_SPEAR6XX_ICM3_MISC_REG_BASE	IO_ADDRESS(SPEAR6XX_ICM3_MISC_REG_BASE)
+#define SPEAR6XX_ICM3_MISC_REG_SIZE	0x00080000
+
+/* ICM4 - High Speed Connection */
+#define SPEAR6XX_ICM4_BASE		0xE0000000
+#define SPEAR6XX_ICM4_SIZE		0x08000000
+
+#define SPEAR6XX_ICM4_GMAC_BASE		0xE0800000
+#define SPEAR6XX_ICM4_GMAC_SIZE		0x00800000
+
+#define SPEAR6XX_ICM4_USBD_FIFO_BASE	0xE1000000
+#define SPEAR6XX_ICM4_USBD_FIFO_SIZE	0x00100000
+
+#define SPEAR6XX_ICM4_USBD_CSR_BASE	0xE1100000
+#define SPEAR6XX_ICM4_USBD_CSR_SIZE	0x00100000
+
+#define SPEAR6XX_ICM4_USBD_PLDT_BASE	0xE1200000
+#define SPEAR6XX_ICM4_USBD_PLDT_SIZE	0x00100000
+
+#define SPEAR6XX_ICM4_USB_EHCI0_BASE	0xE1800000
+#define SPEAR6XX_ICM4_USB_EHCI0_SIZE	0x00100000
+
+#define SPEAR6XX_ICM4_USB_OHCI0_BASE	0xE1900000
+#define SPEAR6XX_ICM4_USB_OHCI0_SIZE	0x00100000
+
+#define SPEAR6XX_ICM4_USB_EHCI1_BASE	0xE2000000
+#define SPEAR6XX_ICM4_USB_EHCI1_SIZE	0x00100000
+
+#define SPEAR6XX_ICM4_USB_OHCI1_BASE	0xE2100000
+#define SPEAR6XX_ICM4_USB_OHCI1_SIZE	0x00100000
+
+#define SPEAR6XX_ICM4_USB_ARB_BASE	0xE2800000
+#define SPEAR6XX_ICM4_USB_ARB_SIZE	0x00010000
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE		SPEAR6XX_ICM1_UART0_BASE
+#define VA_SPEAR_DBG_UART_BASE		VA_SPEAR6XX_ICM1_UART0_BASE
+
+/* Sysctl base for spear platform */
+#define SPEAR_SYS_CTRL_BASE		SPEAR6XX_ICM3_SYS_CTRL_BASE
+#define VA_SPEAR_SYS_CTRL_BASE		VA_SPEAR6XX_ICM3_SYS_CTRL_BASE
+
+#endif /* __MACH_SPEAR6XX_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/spear600.h b/arch/arm/mach-spear6xx/include/mach/spear600.h
new file mode 100644
index 0000000..c068cc5
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/spear600.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-spear66xx/include/mach/spear600.h
+ *
+ * SPEAr600 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifdef	CONFIG_MACH_SPEAR600
+
+#ifndef __MACH_SPEAR600_H
+#define __MACH_SPEAR600_H
+
+#endif /* __MACH_SPEAR600_H */
+
+#endif /* CONFIG_MACH_SPEAR600 */
diff --git a/arch/arm/mach-spear6xx/include/mach/system.h b/arch/arm/mach-spear6xx/include/mach/system.h
new file mode 100644
index 0000000..0b1d2be
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/system.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/system.h
+ *
+ * SPEAr6xx Machine family specific architecture functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <plat/system.h>
+
+#endif	/* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/timex.h b/arch/arm/mach-spear6xx/include/mach/timex.h
new file mode 100644
index 0000000..ac1c5b0
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/timex.h
+ *
+ * SPEAr6XX machine family specific timex definitions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+#include <plat/timex.h>
+
+#endif	/* __MACH_TIMEX_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/uncompress.h b/arch/arm/mach-spear6xx/include/mach/uncompress.h
new file mode 100644
index 0000000..77f0765
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/uncompress.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <plat/uncompress.h>
+
+#endif	/* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/vmalloc.h b/arch/arm/mach-spear6xx/include/mach/vmalloc.h
new file mode 100644
index 0000000..4a0b56c
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/vmalloc.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/vmalloc.h
+ *
+ * Defining Vmalloc area for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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.
+ */
+
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#include <plat/vmalloc.h>
+
+#endif	/* __MACH_VMALLOC_H */
diff --git a/arch/arm/mach-spear6xx/spear600.c b/arch/arm/mach-spear6xx/spear600.c
new file mode 100644
index 0000000..5c484c4
--- /dev/null
+++ b/arch/arm/mach-spear6xx/spear600.c
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-spear6xx/spear600.c
+ *
+ * SPEAr600 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* Add spear600 specific devices here */
+
+void __init spear600_init(void)
+{
+	/* call spear6xx family common init function */
+	spear6xx_init();
+}
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
new file mode 100644
index 0000000..daff8d0
--- /dev/null
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/mach-spear6xx/spear600_evb.c
+ *
+ * SPEAr600 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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 <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+static struct amba_device *amba_devs[] __initdata = {
+	&gpio_device[0],
+	&gpio_device[1],
+	&gpio_device[2],
+	&uart_device[0],
+	&uart_device[1],
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+};
+
+static void __init spear600_evb_init(void)
+{
+	unsigned int i;
+
+	/* call spear600 machine init function */
+	spear600_init();
+
+	/* Add Platform Devices */
+	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+	/* Add Amba Devices */
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+		amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR600, "ST-SPEAR600-EVB")
+	.boot_params	=	0x00000100,
+	.map_io		=	spear6xx_map_io,
+	.init_irq	=	spear6xx_init_irq,
+	.timer		=	&spear_sys_timer,
+	.init_machine	=	spear600_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
new file mode 100644
index 0000000..b67e571
--- /dev/null
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -0,0 +1,158 @@
+/*
+ * arch/arm/mach-spear6xx/spear6xx.c
+ *
+ * SPEAr6XX machines common source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@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/types.h>
+#include <linux/amba/pl061.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/io.h>
+#include <asm/hardware/vic.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <mach/irqs.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* Add spear6xx machines common devices here */
+/* uart device registeration */
+struct amba_device uart_device[] = {
+	{
+		.dev = {
+			.init_name = "uart0",
+		},
+		.res = {
+			.start = SPEAR6XX_ICM1_UART0_BASE,
+			.end = SPEAR6XX_ICM1_UART0_BASE +
+				SPEAR6XX_ICM1_UART0_SIZE - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_UART_0, NO_IRQ},
+	}, {
+		.dev = {
+			.init_name = "uart1",
+		},
+		.res = {
+			.start = SPEAR6XX_ICM1_UART1_BASE,
+			.end = SPEAR6XX_ICM1_UART1_BASE +
+				SPEAR6XX_ICM1_UART1_SIZE - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_UART_1, NO_IRQ},
+	}
+};
+
+/* gpio device registeration */
+static struct pl061_platform_data gpio_plat_data[] = {
+	{
+		.gpio_base	= 0,
+		.irq_base	= SPEAR_GPIO0_INT_BASE,
+	}, {
+		.gpio_base	= 8,
+		.irq_base	= SPEAR_GPIO1_INT_BASE,
+	}, {
+		.gpio_base	= 16,
+		.irq_base	= SPEAR_GPIO2_INT_BASE,
+	},
+};
+
+struct amba_device gpio_device[] = {
+	{
+		.dev = {
+			.init_name = "gpio0",
+			.platform_data = &gpio_plat_data[0],
+		},
+		.res = {
+			.start = SPEAR6XX_CPU_GPIO_BASE,
+			.end = SPEAR6XX_CPU_GPIO_BASE +
+				SPEAR6XX_CPU_GPIO_SIZE - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_LOCAL_GPIO, NO_IRQ},
+	}, {
+		.dev = {
+			.init_name = "gpio1",
+			.platform_data = &gpio_plat_data[1],
+		},
+		.res = {
+			.start = SPEAR6XX_ICM3_GPIO_BASE,
+			.end = SPEAR6XX_ICM3_GPIO_BASE +
+				SPEAR6XX_ICM3_GPIO_SIZE - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_BASIC_GPIO, NO_IRQ},
+	}, {
+		.dev = {
+			.init_name = "gpio2",
+			.platform_data = &gpio_plat_data[2],
+		},
+		.res = {
+			.start = SPEAR6XX_ICM2_GPIO_BASE,
+			.end = SPEAR6XX_ICM2_GPIO_BASE +
+				SPEAR6XX_ICM2_GPIO_SIZE - 1,
+			.flags = IORESOURCE_MEM,
+		},
+		.irq = {IRQ_APPL_GPIO, NO_IRQ},
+	}
+};
+
+/* This will add devices, and do machine specific tasks */
+void __init spear6xx_init(void)
+{
+	/* nothing to do for now */
+}
+
+/* This will initialize vic */
+void __init spear6xx_init_irq(void)
+{
+	vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_PRI_BASE, 0, ~0, 0);
+	vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_SEC_BASE, 32, ~0, 0);
+}
+
+/* Following will create static virtual/physical mappings */
+static struct map_desc spear6xx_io_desc[] __initdata = {
+	{
+		.virtual	= VA_SPEAR6XX_ICM1_UART0_BASE,
+		.pfn		= __phys_to_pfn(SPEAR6XX_ICM1_UART0_BASE),
+		.length		= SPEAR6XX_ICM1_UART0_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= VA_SPEAR6XX_CPU_VIC_PRI_BASE,
+		.pfn		= __phys_to_pfn(SPEAR6XX_CPU_VIC_PRI_BASE),
+		.length		= SPEAR6XX_CPU_VIC_PRI_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= VA_SPEAR6XX_CPU_VIC_SEC_BASE,
+		.pfn		= __phys_to_pfn(SPEAR6XX_CPU_VIC_SEC_BASE),
+		.length		= SPEAR6XX_CPU_VIC_SEC_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= VA_SPEAR6XX_ICM3_SYS_CTRL_BASE,
+		.pfn		= __phys_to_pfn(SPEAR6XX_ICM3_SYS_CTRL_BASE),
+		.length		= SPEAR6XX_ICM3_MISC_REG_BASE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= VA_SPEAR6XX_ICM3_MISC_REG_BASE,
+		.pfn		= __phys_to_pfn(SPEAR6XX_ICM3_MISC_REG_BASE),
+		.length		= SPEAR6XX_ICM3_MISC_REG_SIZE,
+		.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));
+
+	/* This will initialize clock framework */
+	clk_init();
+}
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c
index 77fbb1e..88506d0 100644
--- a/arch/arm/mach-u300/mmc.c
+++ b/arch/arm/mach-u300/mmc.c
@@ -102,11 +102,12 @@
 	 * we have a regulator we can control instead.
 	 */
 	/* Nominally 2.85V on our platform */
+	mmci_card->mmc0_plat_data.f_max = 24000000;
 	mmci_card->mmc0_plat_data.status = mmc_status;
 	mmci_card->mmc0_plat_data.gpio_wp = -1;
 	mmci_card->mmc0_plat_data.gpio_cd = -1;
 	mmci_card->mmc0_plat_data.capabilities = MMC_CAP_MMC_HIGHSPEED |
-		MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA;
+		MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
 
 	mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data;
 
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 03625d7..6625e5b 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -1,15 +1,42 @@
-menu "ST-Ericsson platform type"
-	depends on ARCH_U8500
+if ARCH_U8500
 
-comment "ST-Ericsson Multicore Mobile Platforms"
-
-config MACH_U8500_MOP
-	bool "U8500 Early Development platform"
+config UX500_SOC_COMMON
+	bool
 	default y
 	select ARM_GIC
 	select HAS_MTU
+	select NOMADIK_GPIO
+
+config UX500_SOC_DB8500
+	bool
+
+config UX500_SOC_DB5500
+	bool
+
+choice
+	prompt "Ux500 target platform"
+	default MACH_U8500_MOP
+
+config MACH_U8500_MOP
+	bool "U8500 Development platform"
+	select UX500_SOC_DB8500
 	help
 	  Include support for mop500 development platform
 	  based on U8500 architecture. The platform is based
 	  on early drop silicon version of 8500.
-endmenu
+
+config MACH_U5500
+	bool "U5500 Development platform"
+	select UX500_SOC_DB5500
+	help
+	  Include support for the U5500 development platform.
+endchoice
+
+config UX500_DEBUG_UART
+	int "Ux500 UART to use for low-level debug"
+	default 2
+	help
+	  Choose the UART on which kernel low-level debug messages should be
+	  output.
+
+endif
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 95e6e24c..c7bc419 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -2,7 +2,9 @@
 # Makefile for the linux kernel, U8500 machine.
 #
 
-obj-y				:= clock.o
-obj-$(CONFIG_ARCH_U8500)	+= cpu-u8500.o
+obj-y				:= clock.o cpu.o devices.o
+obj-$(CONFIG_UX500_SOC_DB5500)	+= cpu-db5500.o devices-db5500.o
+obj-$(CONFIG_UX500_SOC_DB8500)	+= cpu-db8500.o devices-db8500.o
 obj-$(CONFIG_MACH_U8500_MOP)	+= board-mop500.o
+obj-$(CONFIG_MACH_U5500)	+= board-u5500.o
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o localtimer.o
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 803aec1..072196c 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -17,37 +17,14 @@
 #include <linux/amba/pl022.h>
 #include <linux/spi/spi.h>
 
-#include <asm/localtimer.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <plat/mtu.h>
 #include <plat/i2c.h>
 
 #include <mach/hardware.h>
 #include <mach/setup.h>
-
-#define __MEM_4K_RESOURCE(x) \
-	.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
-
-/* These are active devices on this board */
-static struct amba_device uart0_device = {
-	.dev = { .init_name = "uart0" },
-	__MEM_4K_RESOURCE(U8500_UART0_BASE),
-	.irq = {IRQ_UART0, NO_IRQ},
-};
-
-static struct amba_device uart1_device = {
-	.dev = { .init_name = "uart1" },
-	__MEM_4K_RESOURCE(U8500_UART1_BASE),
-	.irq = {IRQ_UART1, NO_IRQ},
-};
-
-static struct amba_device uart2_device = {
-	.dev = { .init_name = "uart2" },
-	__MEM_4K_RESOURCE(U8500_UART2_BASE),
-	.irq = {IRQ_UART2, NO_IRQ},
-};
+#include <mach/devices.h>
 
 static void ab4500_spi_cs_control(u32 command)
 {
@@ -93,55 +70,8 @@
 	.num_chipselect = 5,
 };
 
-static struct amba_device pl022_device = {
-	.dev = {
-		.coherent_dma_mask = ~0,
-		.init_name = "pl022",
-		.platform_data = &ssp0_platform_data,
-	},
-	.res = {
-		.start = U8500_SSP0_BASE,
-		.end   = U8500_SSP0_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_SSP0, NO_IRQ },
-	/* ST-Ericsson modified id */
-	.periphid = SSP_PER_ID,
-};
-
-static struct amba_device pl031_device = {
-	.dev = {
-		.init_name = "pl031",
-	},
-	.res = {
-		.start = U8500_RTC_BASE,
-		.end = U8500_RTC_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_RTC_RTT, NO_IRQ},
-};
-
-#define U8500_I2C_RESOURCES(id, size)		\
-static struct resource u8500_i2c_resources_##id[] = {	\
-	[0] = {					\
-		.start	= U8500_I2C##id##_BASE,	\
-		.end	= U8500_I2C##id##_BASE + size - 1, \
-		.flags	= IORESOURCE_MEM,	\
-	},					\
-	[1] = {					\
-		.start	= IRQ_I2C##id,		\
-		.end	= IRQ_I2C##id,		\
-		.flags	= IORESOURCE_IRQ	\
-	}					\
-}
-
-U8500_I2C_RESOURCES(0, SZ_4K);
-U8500_I2C_RESOURCES(1, SZ_4K);
-U8500_I2C_RESOURCES(2, SZ_4K);
-U8500_I2C_RESOURCES(3, SZ_4K);
-
 #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \
-static struct nmk_i2c_controller u8500_i2c_##id = { \
+static struct nmk_i2c_controller u8500_i2c##id##_data = { \
 	/*				\
 	 * slave data setup time, which is	\
 	 * 250 ns,100ns,10ns which is 14,6,2	\
@@ -169,58 +99,32 @@
 U8500_I2C_CONTROLLER(2,	0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
 U8500_I2C_CONTROLLER(3,	0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
 
-#define U8500_I2C_PDEVICE(cid)		\
-static struct platform_device i2c_controller##cid = { \
-	.name = "nmk-i2c",		\
-	.id	 = cid,			\
-	.num_resources = 2,		\
-	.resource = u8500_i2c_resources_##cid,	\
-	.dev = {			\
-		.platform_data = &u8500_i2c_##cid \
-	}				\
-}
-
-U8500_I2C_PDEVICE(0);
-U8500_I2C_PDEVICE(1);
-U8500_I2C_PDEVICE(2);
-U8500_I2C_PDEVICE(3);
-
 static struct amba_device *amba_devs[] __initdata = {
-	&uart0_device,
-	&uart1_device,
-	&uart2_device,
-	&pl022_device,
-	&pl031_device,
+	&ux500_uart0_device,
+	&ux500_uart1_device,
+	&ux500_uart2_device,
+	&u8500_ssp0_device,
 };
 
 /* add any platform devices here - TODO */
 static struct platform_device *platform_devs[] __initdata = {
-	&i2c_controller0,
-	&i2c_controller1,
-	&i2c_controller2,
-	&i2c_controller3,
-};
-
-static void __init u8500_timer_init(void)
-{
-#ifdef CONFIG_LOCAL_TIMERS
-	/* Setup the local timer base */
-	twd_base = __io_address(U8500_TWD_BASE);
-#endif
-	/* Setup the MTU base */
-	mtu_base = __io_address(U8500_MTU0_BASE);
-
-	nmdk_timer_init();
-}
-
-static struct sys_timer u8500_timer = {
-	.init	= u8500_timer_init,
+	&u8500_i2c0_device,
+	&ux500_i2c1_device,
+	&ux500_i2c2_device,
+	&ux500_i2c3_device,
 };
 
 static void __init u8500_init_machine(void)
 {
 	int i;
 
+	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;
+	ux500_i2c3_device.dev.platform_data = &u8500_i2c3_data;
+
+	u8500_ssp0_device.dev.platform_data = &ssp0_platform_data;
+
 	/* Register the active AMBA devices on this board */
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
 		amba_device_register(amba_devs[i], &iomem_resource);
@@ -239,8 +143,8 @@
 	.io_pg_offst	= (IO_ADDRESS(U8500_UART2_BASE) >> 18) & 0xfffc,
 	.boot_params	= 0x100,
 	.map_io		= u8500_map_io,
-	.init_irq	= u8500_init_irq,
+	.init_irq	= ux500_init_irq,
 	/* we re-use nomadik timer here */
-	.timer		= &u8500_timer,
+	.timer		= &ux500_timer,
 	.init_machine	= u8500_init_machine,
 MACHINE_END
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c
new file mode 100644
index 0000000..4430e69
--- /dev/null
+++ b/arch/arm/mach-ux500/board-u5500.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/devices.h>
+#include <mach/setup.h>
+
+static struct amba_device *amba_board_devs[] __initdata = {
+	&ux500_uart0_device,
+	&ux500_uart1_device,
+	&ux500_uart2_device,
+};
+
+static void __init u5500_init_machine(void)
+{
+	u5500_init_devices();
+
+	amba_add_devices(amba_board_devs, ARRAY_SIZE(amba_board_devs));
+}
+
+MACHINE_START(U8500, "ST-Ericsson U5500 Platform")
+	.phys_io	= UX500_UART0_BASE,
+	.io_pg_offst	= (IO_ADDRESS(UX500_UART0_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= u5500_map_io,
+	.init_irq	= ux500_init_irq,
+	.timer		= &ux500_timer,
+	.init_machine	= u5500_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 8359a73..1b2c989 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2009 ST-Ericsson
- * 	heavily based on realview platform
+ *  Copyright (C) 2009 STMicroelectronics
  *
  * 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
@@ -12,33 +12,130 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/clk.h>
-#include <linux/mutex.h>
+#include <linux/io.h>
 
 #include <asm/clkdev.h>
 
-/* currently the clk structure
- * just supports rate. This would
- * be extended as and when new devices are
- * added - TODO
- */
-struct clk {
-	unsigned long		rate;
-};
+#include <mach/hardware.h>
+#include "clock.h"
+
+#define PRCC_PCKEN		0x00
+#define PRCC_PCKDIS		0x04
+#define PRCC_KCKEN		0x08
+#define PRCC_KCKDIS		0x0C
+
+#define PRCM_YYCLKEN0_MGT_SET	0x510
+#define PRCM_YYCLKEN1_MGT_SET	0x514
+#define PRCM_YYCLKEN0_MGT_CLR	0x518
+#define PRCM_YYCLKEN1_MGT_CLR	0x51C
+#define PRCM_YYCLKEN0_MGT_VAL	0x520
+#define PRCM_YYCLKEN1_MGT_VAL	0x524
+
+#define PRCM_SVAMMDSPCLK_MGT	0x008
+#define PRCM_SIAMMDSPCLK_MGT	0x00C
+#define PRCM_SGACLK_MGT		0x014
+#define PRCM_UARTCLK_MGT	0x018
+#define PRCM_MSP02CLK_MGT	0x01C
+#define PRCM_MSP1CLK_MGT	0x288
+#define PRCM_I2CCLK_MGT		0x020
+#define PRCM_SDMMCCLK_MGT	0x024
+#define PRCM_SLIMCLK_MGT	0x028
+#define PRCM_PER1CLK_MGT	0x02C
+#define PRCM_PER2CLK_MGT	0x030
+#define PRCM_PER3CLK_MGT	0x034
+#define PRCM_PER5CLK_MGT	0x038
+#define PRCM_PER6CLK_MGT	0x03C
+#define PRCM_PER7CLK_MGT	0x040
+#define PRCM_LCDCLK_MGT		0x044
+#define PRCM_BMLCLK_MGT		0x04C
+#define PRCM_HSITXCLK_MGT	0x050
+#define PRCM_HSIRXCLK_MGT	0x054
+#define PRCM_HDMICLK_MGT	0x058
+#define PRCM_APEATCLK_MGT	0x05C
+#define PRCM_APETRACECLK_MGT	0x060
+#define PRCM_MCDECLK_MGT	0x064
+#define PRCM_IPI2CCLK_MGT	0x068
+#define PRCM_DSIALTCLK_MGT	0x06C
+#define PRCM_DMACLK_MGT		0x074
+#define PRCM_B2R2CLK_MGT	0x078
+#define PRCM_TVCLK_MGT		0x07C
+#define PRCM_UNIPROCLK_MGT	0x278
+#define PRCM_SSPCLK_MGT		0x280
+#define PRCM_RNGCLK_MGT		0x284
+#define PRCM_UICCCLK_MGT	0x27C
+
+#define PRCM_MGT_ENABLE		(1 << 8)
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static void __clk_enable(struct clk *clk)
+{
+	if (clk->enabled++ == 0) {
+		if (clk->parent_cluster)
+			__clk_enable(clk->parent_cluster);
+
+		if (clk->parent_periph)
+			__clk_enable(clk->parent_periph);
+
+		if (clk->ops && clk->ops->enable)
+			clk->ops->enable(clk);
+	}
+}
 
 int clk_enable(struct clk *clk)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	__clk_enable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
 	return 0;
 }
 EXPORT_SYMBOL(clk_enable);
 
+static void __clk_disable(struct clk *clk)
+{
+	if (--clk->enabled == 0) {
+		if (clk->ops && clk->ops->disable)
+			clk->ops->disable(clk);
+
+		if (clk->parent_periph)
+			__clk_disable(clk->parent_periph);
+
+		if (clk->parent_cluster)
+			__clk_disable(clk->parent_cluster);
+	}
+}
+
 void clk_disable(struct clk *clk)
 {
+	unsigned long flags;
+
+	WARN_ON(!clk->enabled);
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	__clk_disable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
 
 unsigned long clk_get_rate(struct clk *clk)
 {
-	return clk->rate;
+	unsigned long rate;
+
+	if (clk->ops && clk->ops->get_rate)
+		return clk->ops->get_rate(clk);
+
+	rate = clk->rate;
+	if (!rate) {
+		if (clk->parent_periph)
+			rate = clk_get_rate(clk->parent_periph);
+		else if (clk->parent_cluster)
+			rate = clk_get_rate(clk->parent_cluster);
+	}
+
+	return rate;
 }
 EXPORT_SYMBOL(clk_get_rate);
 
@@ -56,37 +153,373 @@
 }
 EXPORT_SYMBOL(clk_set_rate);
 
-/* ssp clock */
-static struct clk ssp_clk = {
-	.rate = 48000000,
+static void clk_prcmu_enable(struct clk *clk)
+{
+	void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE)
+				   + PRCM_YYCLKEN0_MGT_SET + clk->prcmu_cg_off;
+
+	writel(1 << clk->prcmu_cg_bit, cg_set_reg);
+}
+
+static void clk_prcmu_disable(struct clk *clk)
+{
+	void __iomem *cg_clr_reg = __io_address(U8500_PRCMU_BASE)
+				   + PRCM_YYCLKEN0_MGT_CLR + clk->prcmu_cg_off;
+
+	writel(1 << clk->prcmu_cg_bit, cg_clr_reg);
+}
+
+/* ED doesn't have the combined set/clr registers */
+static void clk_prcmu_ed_enable(struct clk *clk)
+{
+	void __iomem *addr = __io_address(U8500_PRCMU_BASE)
+			     + clk->prcmu_cg_mgt;
+
+	writel(readl(addr) | PRCM_MGT_ENABLE, addr);
+}
+
+static void clk_prcmu_ed_disable(struct clk *clk)
+{
+	void __iomem *addr = __io_address(U8500_PRCMU_BASE)
+			     + clk->prcmu_cg_mgt;
+
+	writel(readl(addr) & ~PRCM_MGT_ENABLE, addr);
+}
+
+static struct clkops clk_prcmu_ops = {
+	.enable = clk_prcmu_enable,
+	.disable = clk_prcmu_disable,
 };
 
-/* fixed clock */
-static struct clk f38_clk = {
-	.rate = 38400000,
+static unsigned int clkrst_base[] = {
+	[1] = U8500_CLKRST1_BASE,
+	[2] = U8500_CLKRST2_BASE,
+	[3] = U8500_CLKRST3_BASE,
+	[5] = U8500_CLKRST5_BASE,
+	[6] = U8500_CLKRST6_BASE,
+	[7] = U8500_CLKRST7_BASE_ED,
 };
 
-static struct clk_lookup lookups[] = {
-	{
-		/* UART0 */
-		.dev_id		= "uart0",
-		.clk		= &f38_clk,
-	}, {	/* UART1 */
-		.dev_id		= "uart1",
-		.clk		= &f38_clk,
-	}, {	/* UART2 */
-		.dev_id		= "uart2",
-		.clk		= &f38_clk,
-	}, {	/* SSP */
-		.dev_id		= "pl022",
-		.clk		= &ssp_clk,
-	}
+static void clk_prcc_enable(struct clk *clk)
+{
+	void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
+
+	if (clk->prcc_kernel != -1)
+		writel(1 << clk->prcc_kernel, addr + PRCC_KCKEN);
+
+	if (clk->prcc_bus != -1)
+		writel(1 << clk->prcc_bus, addr + PRCC_PCKEN);
+}
+
+static void clk_prcc_disable(struct clk *clk)
+{
+	void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
+
+	if (clk->prcc_bus != -1)
+		writel(1 << clk->prcc_bus, addr + PRCC_PCKDIS);
+
+	if (clk->prcc_kernel != -1)
+		writel(1 << clk->prcc_kernel, addr + PRCC_KCKDIS);
+}
+
+static struct clkops clk_prcc_ops = {
+	.enable = clk_prcc_enable,
+	.disable = clk_prcc_disable,
+};
+
+static struct clk clk_32khz = {
+	.rate = 32000,
+};
+
+/*
+ * PRCMU level clock gating
+ */
+
+/* Bank 0 */
+static DEFINE_PRCMU_CLK(svaclk,		0x0, 2, SVAMMDSPCLK);
+static DEFINE_PRCMU_CLK(siaclk,		0x0, 3, SIAMMDSPCLK);
+static DEFINE_PRCMU_CLK(sgaclk,		0x0, 4, SGACLK);
+static DEFINE_PRCMU_CLK_RATE(uartclk,	0x0, 5, UARTCLK, 38400000);
+static DEFINE_PRCMU_CLK(msp02clk,	0x0, 6, MSP02CLK);
+static DEFINE_PRCMU_CLK(msp1clk,	0x0, 7, MSP1CLK); /* v1 */
+static DEFINE_PRCMU_CLK_RATE(i2cclk,	0x0, 8, I2CCLK, 48000000);
+static DEFINE_PRCMU_CLK_RATE(sdmmcclk,	0x0, 9, SDMMCCLK, 50000000);
+static DEFINE_PRCMU_CLK(slimclk,	0x0, 10, SLIMCLK);
+static DEFINE_PRCMU_CLK(per1clk,	0x0, 11, PER1CLK);
+static DEFINE_PRCMU_CLK(per2clk,	0x0, 12, PER2CLK);
+static DEFINE_PRCMU_CLK(per3clk,	0x0, 13, PER3CLK);
+static DEFINE_PRCMU_CLK(per5clk,	0x0, 14, PER5CLK);
+static DEFINE_PRCMU_CLK_RATE(per6clk,	0x0, 15, PER6CLK, 133330000);
+static DEFINE_PRCMU_CLK_RATE(per7clk,	0x0, 16, PER7CLK, 100000000);
+static DEFINE_PRCMU_CLK(lcdclk,		0x0, 17, LCDCLK);
+static DEFINE_PRCMU_CLK(bmlclk,		0x0, 18, BMLCLK);
+static DEFINE_PRCMU_CLK(hsitxclk,	0x0, 19, HSITXCLK);
+static DEFINE_PRCMU_CLK(hsirxclk,	0x0, 20, HSIRXCLK);
+static DEFINE_PRCMU_CLK(hdmiclk,	0x0, 21, HDMICLK);
+static DEFINE_PRCMU_CLK(apeatclk,	0x0, 22, APEATCLK);
+static DEFINE_PRCMU_CLK(apetraceclk,	0x0, 23, APETRACECLK);
+static DEFINE_PRCMU_CLK(mcdeclk,	0x0, 24, MCDECLK);
+static DEFINE_PRCMU_CLK(ipi2clk,	0x0, 25, IPI2CCLK);
+static DEFINE_PRCMU_CLK(dsialtclk,	0x0, 26, DSIALTCLK); /* v1 */
+static DEFINE_PRCMU_CLK(dmaclk,		0x0, 27, DMACLK);
+static DEFINE_PRCMU_CLK(b2r2clk,	0x0, 28, B2R2CLK);
+static DEFINE_PRCMU_CLK(tvclk,		0x0, 29, TVCLK);
+static DEFINE_PRCMU_CLK(uniproclk,	0x0, 30, UNIPROCLK); /* v1 */
+static DEFINE_PRCMU_CLK_RATE(sspclk,	0x0, 31, SSPCLK, 48000000); /* v1 */
+
+/* Bank 1 */
+static DEFINE_PRCMU_CLK(rngclk,		0x4, 0, RNGCLK); /* v1 */
+static DEFINE_PRCMU_CLK(uiccclk,	0x4, 1, UICCCLK); /* v1 */
+
+/*
+ * PRCC level clock gating
+ * Format: per#, clk, PCKEN bit, KCKEN bit, parent
+ */
+
+/* Peripheral Cluster #1 */
+static DEFINE_PRCC_CLK(1, i2c4, 	10, 9, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, gpio0,	9, -1, NULL);
+static DEFINE_PRCC_CLK(1, slimbus0, 	8,  8, &clk_slimclk);
+static DEFINE_PRCC_CLK(1, spi3_ed, 	7,  7, NULL);
+static DEFINE_PRCC_CLK(1, spi3_v1, 	7, -1, NULL);
+static DEFINE_PRCC_CLK(1, i2c2, 	6,  6, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, sdi0,		5,  5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(1, msp1_ed, 	4,  4, &clk_msp02clk);
+static DEFINE_PRCC_CLK(1, msp1_v1, 	4,  4, &clk_msp1clk);
+static DEFINE_PRCC_CLK(1, msp0, 	3,  3, &clk_msp02clk);
+static DEFINE_PRCC_CLK(1, i2c1, 	2,  2, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, uart1, 	1,  1, &clk_uartclk);
+static DEFINE_PRCC_CLK(1, uart0, 	0,  0, &clk_uartclk);
+
+/* Peripheral Cluster #2 */
+
+static DEFINE_PRCC_CLK(2, gpio1_ed,	12, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssitx_ed, 	11, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssirx_ed, 	10, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi0_ed, 	 9, -1, NULL);
+static DEFINE_PRCC_CLK(2, sdi3_ed, 	 8,  6, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, sdi1_ed, 	 7,  5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, msp2_ed, 	 6,  4, &clk_msp02clk);
+static DEFINE_PRCC_CLK(2, sdi4_ed, 	 4,  2, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, pwl_ed,	 3,  1, NULL);
+static DEFINE_PRCC_CLK(2, spi1_ed, 	 2, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi2_ed, 	 1, -1, NULL);
+static DEFINE_PRCC_CLK(2, i2c3_ed, 	 0,  0, &clk_i2cclk);
+
+static DEFINE_PRCC_CLK(2, gpio1_v1,	11, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssitx_v1, 	10,  7, NULL);
+static DEFINE_PRCC_CLK(2, ssirx_v1, 	 9,  6, NULL);
+static DEFINE_PRCC_CLK(2, spi0_v1, 	 8, -1, NULL);
+static DEFINE_PRCC_CLK(2, sdi3_v1, 	 7,  5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, sdi1_v1, 	 6,  4, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, msp2_v1, 	 5,  3, &clk_msp02clk);
+static DEFINE_PRCC_CLK(2, sdi4_v1, 	 4,  2, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, pwl_v1,	 3,  1, NULL);
+static DEFINE_PRCC_CLK(2, spi1_v1, 	 2, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi2_v1, 	 1, -1, NULL);
+static DEFINE_PRCC_CLK(2, i2c3_v1, 	 0,  0, &clk_i2cclk);
+
+/* Peripheral Cluster #3 */
+static DEFINE_PRCC_CLK(3, gpio2, 	8, -1, NULL);
+static DEFINE_PRCC_CLK(3, sdi5, 	7,  7, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(3, uart2, 	6,  6, &clk_uartclk);
+static DEFINE_PRCC_CLK(3, ske, 		5,  5, &clk_32khz);
+static DEFINE_PRCC_CLK(3, sdi2, 	4,  4, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(3, i2c0, 	3,  3, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp1_ed, 	2,  2, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp0_ed, 	1,  1, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp1_v1, 	2,  2, &clk_sspclk);
+static DEFINE_PRCC_CLK(3, ssp0_v1, 	1,  1, &clk_sspclk);
+static DEFINE_PRCC_CLK(3, fsmc, 	0, -1, NULL);
+
+/* Peripheral Cluster #4 is in the always on domain */
+
+/* Peripheral Cluster #5 */
+static DEFINE_PRCC_CLK(5, gpio3, 	1, -1, NULL);
+static DEFINE_PRCC_CLK(5, usb_ed, 	0,  0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(5, usb_v1, 	0,  0, NULL);
+
+/* Peripheral Cluster #6 */
+
+static DEFINE_PRCC_CLK(6, mtu1_v1, 	8, -1, NULL);
+static DEFINE_PRCC_CLK(6, mtu0_v1, 	7, -1, NULL);
+static DEFINE_PRCC_CLK(6, cfgreg_v1, 	6,  6, NULL);
+static DEFINE_PRCC_CLK(6, dmc_ed, 	6,  6, NULL);
+static DEFINE_PRCC_CLK(6, hash1, 	5, -1, NULL);
+static DEFINE_PRCC_CLK(6, unipro_v1, 	4,  1, &clk_uniproclk);
+static DEFINE_PRCC_CLK(6, cryp1_ed, 	4, -1, NULL);
+static DEFINE_PRCC_CLK(6, pka, 		3, -1, NULL);
+static DEFINE_PRCC_CLK(6, hash0, 	2, -1, NULL);
+static DEFINE_PRCC_CLK(6, cryp0, 	1, -1, NULL);
+static DEFINE_PRCC_CLK(6, rng_ed, 	0,  0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(6, rng_v1, 	0,  0, &clk_rngclk);
+
+/* Peripheral Cluster #7 */
+
+static DEFINE_PRCC_CLK(7, tzpc0_ed, 	4, -1, NULL);
+static DEFINE_PRCC_CLK(7, mtu1_ed, 	3, -1, NULL);
+static DEFINE_PRCC_CLK(7, mtu0_ed, 	2, -1, NULL);
+static DEFINE_PRCC_CLK(7, wdg_ed, 	1, -1, NULL);
+static DEFINE_PRCC_CLK(7, cfgreg_ed, 	0, -1, NULL);
+
+static struct clk_lookup u8500_common_clks[] = {
+	/* Peripheral Cluster #1 */
+	CLK(gpio0,	"gpio.0",	NULL),
+	CLK(gpio0,	"gpio.1",	NULL),
+	CLK(slimbus0,	"slimbus0",	NULL),
+	CLK(i2c2,	"nmk-i2c.2",	NULL),
+	CLK(sdi0,	"sdi0",		NULL),
+	CLK(msp0,	"msp0",		NULL),
+	CLK(i2c1,	"nmk-i2c.1",	NULL),
+	CLK(uart1,	"uart1",	NULL),
+	CLK(uart0,	"uart0",	NULL),
+
+	/* Peripheral Cluster #3 */
+	CLK(gpio2,	"gpio.2",	NULL),
+	CLK(gpio2,	"gpio.3",	NULL),
+	CLK(gpio2,	"gpio.4",	NULL),
+	CLK(gpio2,	"gpio.5",	NULL),
+	CLK(sdi5,	"sdi5",		NULL),
+	CLK(uart2,	"uart2",	NULL),
+	CLK(ske,	"ske",		NULL),
+	CLK(sdi2,	"sdi2",		NULL),
+	CLK(i2c0,	"nmk-i2c.0",	NULL),
+	CLK(fsmc,	"fsmc",		NULL),
+
+	/* Peripheral Cluster #5 */
+	CLK(gpio3,	"gpio.8",	NULL),
+
+	/* Peripheral Cluster #6 */
+	CLK(hash1,	"hash1",	NULL),
+	CLK(pka,	"pka",		NULL),
+	CLK(hash0,	"hash0",	NULL),
+	CLK(cryp0,	"cryp0",	NULL),
+
+	/* PRCMU level clock gating */
+
+	/* Bank 0 */
+	CLK(svaclk,	"sva",		NULL),
+	CLK(siaclk,	"sia",		NULL),
+	CLK(sgaclk,	"sga",		NULL),
+	CLK(slimclk,	"slim",		NULL),
+	CLK(lcdclk,	"lcd",		NULL),
+	CLK(bmlclk,	"bml",		NULL),
+	CLK(hsitxclk,	"stm-hsi.0",	NULL),
+	CLK(hsirxclk,	"stm-hsi.1",	NULL),
+	CLK(hdmiclk,	"hdmi",		NULL),
+	CLK(apeatclk,	"apeat",	NULL),
+	CLK(apetraceclk,	"apetrace",	NULL),
+	CLK(mcdeclk,	"mcde",		NULL),
+	CLK(ipi2clk,	"ipi2",		NULL),
+	CLK(dmaclk,	"dma40",	NULL),
+	CLK(b2r2clk,	"b2r2",		NULL),
+	CLK(tvclk,	"tv",		NULL),
+};
+
+static struct clk_lookup u8500_ed_clks[] = {
+	/* Peripheral Cluster #1 */
+	CLK(spi3_ed,	"spi3",		NULL),
+	CLK(msp1_ed,	"msp1",		NULL),
+
+	/* Peripheral Cluster #2 */
+	CLK(gpio1_ed,	"gpio.6",	NULL),
+	CLK(gpio1_ed,	"gpio.7",	NULL),
+	CLK(ssitx_ed,	"ssitx",	NULL),
+	CLK(ssirx_ed,	"ssirx",	NULL),
+	CLK(spi0_ed,	"spi0",		NULL),
+	CLK(sdi3_ed,	"sdi3",		NULL),
+	CLK(sdi1_ed,	"sdi1",		NULL),
+	CLK(msp2_ed,	"msp2",		NULL),
+	CLK(sdi4_ed,	"sdi4",		NULL),
+	CLK(pwl_ed,	"pwl",		NULL),
+	CLK(spi1_ed,	"spi1",		NULL),
+	CLK(spi2_ed,	"spi2",		NULL),
+	CLK(i2c3_ed,	"nmk-i2c.3",	NULL),
+
+	/* Peripheral Cluster #3 */
+	CLK(ssp1_ed,	"ssp1",		NULL),
+	CLK(ssp0_ed,	"ssp0",		NULL),
+
+	/* Peripheral Cluster #5 */
+	CLK(usb_ed,	"musb_hdrc.0",	"usb"),
+
+	/* Peripheral Cluster #6 */
+	CLK(dmc_ed,	"dmc",		NULL),
+	CLK(cryp1_ed,	"cryp1",	NULL),
+	CLK(rng_ed,	"rng",		NULL),
+
+	/* Peripheral Cluster #7 */
+	CLK(tzpc0_ed,	"tzpc0",	NULL),
+	CLK(mtu1_ed,	"mtu1",		NULL),
+	CLK(mtu0_ed,	"mtu0",		NULL),
+	CLK(wdg_ed,	"wdg",		NULL),
+	CLK(cfgreg_ed,	"cfgreg",	NULL),
+};
+
+static struct clk_lookup u8500_v1_clks[] = {
+	/* Peripheral Cluster #1 */
+	CLK(i2c4,	"nmk-i2c.4", 	NULL),
+	CLK(spi3_v1,	"spi3",		NULL),
+	CLK(msp1_v1,	"msp1",		NULL),
+
+	/* Peripheral Cluster #2 */
+	CLK(gpio1_v1,	"gpio.6",	NULL),
+	CLK(gpio1_v1,	"gpio.7",	NULL),
+	CLK(ssitx_v1,	"ssitx",	NULL),
+	CLK(ssirx_v1,	"ssirx",	NULL),
+	CLK(spi0_v1,	"spi0",		NULL),
+	CLK(sdi3_v1,	"sdi3",		NULL),
+	CLK(sdi1_v1,	"sdi1",		NULL),
+	CLK(msp2_v1,	"msp2",		NULL),
+	CLK(sdi4_v1,	"sdi4",		NULL),
+	CLK(pwl_v1,	"pwl",		NULL),
+	CLK(spi1_v1,	"spi1",		NULL),
+	CLK(spi2_v1,	"spi2",		NULL),
+	CLK(i2c3_v1,	"nmk-i2c.3",	NULL),
+
+	/* Peripheral Cluster #3 */
+	CLK(ssp1_v1,	"ssp1",		NULL),
+	CLK(ssp0_v1,	"ssp0",		NULL),
+
+	/* Peripheral Cluster #5 */
+	CLK(usb_v1,	"musb_hdrc.0",	"usb"),
+
+	/* Peripheral Cluster #6 */
+	CLK(mtu1_v1,	"mtu1",		NULL),
+	CLK(mtu0_v1,	"mtu0",		NULL),
+	CLK(cfgreg_v1,	"cfgreg",	NULL),
+	CLK(hash1,	"hash1",	NULL),
+	CLK(unipro_v1,	"unipro",	NULL),
+	CLK(rng_v1,	"rng",		NULL),
+
+	/* PRCMU level clock gating */
+
+	/* Bank 0 */
+	CLK(uniproclk,	"uniproclk",	NULL),
+	CLK(dsialtclk,	"dsialt",	NULL),
+
+	/* Bank 1 */
+	CLK(rngclk,	"rng",		NULL),
+	CLK(uiccclk,	"uicc",		NULL),
 };
 
 static int __init clk_init(void)
 {
-	/* register the clock lookups */
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+	if (cpu_is_u8500ed()) {
+		clk_prcmu_ops.enable = clk_prcmu_ed_enable;
+		clk_prcmu_ops.disable = clk_prcmu_ed_disable;
+	} else if (cpu_is_u5500()) {
+		/* Clock tree for U5500 not implemented yet */
+		clk_prcc_ops.enable = clk_prcc_ops.disable = NULL;
+		clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL;
+	}
+
+	clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks));
+	if (cpu_is_u8500ed())
+		clkdev_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks));
+	else
+		clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks));
+
 	return 0;
 }
 arch_initcall(clk_init);
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h
new file mode 100644
index 0000000..e4f99b6
--- /dev/null
+++ b/arch/arm/mach-ux500/clock.h
@@ -0,0 +1,125 @@
+/*
+ *  Copyright (C) 2010 ST-Ericsson
+ *  Copyright (C) 2009 STMicroelectronics
+ *
+ * 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.
+ */
+
+/**
+ * struct clkops - ux500 clock operations
+ * @enable:	function to enable the clock
+ * @disable:	function to disable the clock
+ * @get_rate:	function to get the current clock rate
+ *
+ * This structure contains function pointers to functions that will be used to
+ * control the clock.  All of these functions are optional.  If get_rate is
+ * NULL, the rate in the struct clk will be used.
+ */
+struct clkops {
+	void (*enable) (struct clk *);
+	void (*disable) (struct clk *);
+	unsigned long (*get_rate) (struct clk *);
+};
+
+/**
+ * struct clk - ux500 clock structure
+ * @ops:		pointer to clkops struct used to control this clock
+ * @name:		name, for debugging
+ * @enabled:		refcount. positive if enabled, zero if disabled
+ * @rate:		fixed rate for clocks which don't implement
+ * 			ops->getrate
+ * @prcmu_cg_off:	address offset of the combined enable/disable register
+ * 			(used on u8500v1)
+ * @prcmu_cg_bit:	bit in the combined enable/disable register (used on
+ * 			u8500v1)
+ * @prcmu_cg_mgt:	address of the enable/disable register (used on
+ * 			u8500ed)
+ * @cluster:		peripheral cluster number
+ * @prcc_bus:		bit for the bus clock in the peripheral's CLKRST
+ * @prcc_kernel:	bit for the kernel clock in the peripheral's CLKRST.
+ * 			-1 if no kernel clock exists.
+ * @parent_cluster:	pointer to parent's cluster clk struct
+ * @parent_periph:	pointer to parent's peripheral clk struct
+ *
+ * Peripherals are organised into clusters, and each cluster has an associated
+ * bus clock.  Some peripherals also have a parent peripheral clock.
+ *
+ * In order to enable a clock for a peripheral, we need to enable:
+ * 	(1) the parent cluster (bus) clock at the PRCMU level
+ * 	(2) the parent peripheral clock (if any) at the PRCMU level
+ * 	(3) the peripheral's bus & kernel clock at the PRCC level
+ *
+ * (1) and (2) are handled by defining clk structs (DEFINE_PRCMU_CLK) for each
+ * of the cluster and peripheral clocks, and hooking these as the parents of
+ * the individual peripheral clocks.
+ *
+ * (3) is handled by specifying the bits in the PRCC control registers required
+ * to enable these clocks and modifying them in the ->enable and
+ * ->disable callbacks of the peripheral clocks (DEFINE_PRCC_CLK).
+ *
+ * This structure describes both the PRCMU-level clocks and PRCC-level clocks.
+ * The prcmu_* fields are only used for the PRCMU clocks, and the cluster,
+ * prcc, and parent pointers are only used for the PRCC-level clocks.
+ */
+struct clk {
+	const struct clkops	*ops;
+	const char 		*name;
+	unsigned int		enabled;
+
+	unsigned long		rate;
+	struct list_head	list;
+
+	/* These three are only for PRCMU clks */
+
+	unsigned int		prcmu_cg_off;
+	unsigned int		prcmu_cg_bit;
+	unsigned int		prcmu_cg_mgt;
+
+	/* The rest are only for PRCC clks */
+
+	int			cluster;
+	unsigned int		prcc_bus;
+	unsigned int		prcc_kernel;
+
+	struct clk		*parent_cluster;
+	struct clk		*parent_periph;
+};
+
+#define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg)		\
+struct clk clk_##_name = {					\
+		.name		= #_name,			\
+		.ops    	= &clk_prcmu_ops, 		\
+		.prcmu_cg_off	= _cg_off, 			\
+		.prcmu_cg_bit	= _cg_bit,			\
+		.prcmu_cg_mgt	= PRCM_##_reg##_MGT		\
+	}
+
+#define DEFINE_PRCMU_CLK_RATE(_name, _cg_off, _cg_bit, _reg, _rate)	\
+struct clk clk_##_name = {						\
+		.name		= #_name,				\
+		.ops    	= &clk_prcmu_ops, 			\
+		.prcmu_cg_off	= _cg_off, 				\
+		.prcmu_cg_bit	= _cg_bit,				\
+		.rate		= _rate,				\
+		.prcmu_cg_mgt	= PRCM_##_reg##_MGT			\
+	}
+
+#define DEFINE_PRCC_CLK(_pclust, _name, _bus_en, _kernel_en, _kernclk)	\
+struct clk clk_##_name = {						\
+		.name		= #_name,				\
+		.ops    	= &clk_prcc_ops, 			\
+		.cluster 	= _pclust,				\
+		.prcc_bus 	= _bus_en, 				\
+		.prcc_kernel 	= _kernel_en, 				\
+		.parent_cluster = &clk_per##_pclust##clk,		\
+		.parent_periph 	= _kernclk				\
+	}
+
+#define CLK(_clk, _devname, _conname)			\
+	{						\
+		.clk	= &clk_##_clk,			\
+		.dev_id	= _devname,			\
+		.con_id = _conname,			\
+	}
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c
new file mode 100644
index 0000000..6a3ac45
--- /dev/null
+++ b/arch/arm/mach-ux500/cpu-db5500.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/devices.h>
+#include <mach/setup.h>
+
+static struct map_desc u5500_io_desc[] __initdata = {
+	__IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_GPIO3_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_GPIO4_BASE, SZ_4K),
+};
+
+static struct platform_device *u5500_platform_devs[] __initdata = {
+	&u5500_gpio_devs[0],
+	&u5500_gpio_devs[1],
+	&u5500_gpio_devs[2],
+	&u5500_gpio_devs[3],
+	&u5500_gpio_devs[4],
+	&u5500_gpio_devs[5],
+	&u5500_gpio_devs[6],
+	&u5500_gpio_devs[7],
+};
+
+void __init u5500_map_io(void)
+{
+	ux500_map_io();
+
+	iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc));
+}
+
+void __init u5500_init_devices(void)
+{
+	ux500_init_devices();
+
+	platform_add_devices(u5500_platform_devs,
+			     ARRAY_SIZE(u5500_platform_devs));
+}
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
new file mode 100644
index 0000000..d04299f
--- /dev/null
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ *
+ * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.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/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/setup.h>
+#include <mach/devices.h>
+
+static struct platform_device *platform_devs[] __initdata = {
+	&u8500_gpio_devs[0],
+	&u8500_gpio_devs[1],
+	&u8500_gpio_devs[2],
+	&u8500_gpio_devs[3],
+	&u8500_gpio_devs[4],
+	&u8500_gpio_devs[5],
+	&u8500_gpio_devs[6],
+	&u8500_gpio_devs[7],
+	&u8500_gpio_devs[8],
+};
+
+/* minimum static i/o mapping required to boot U8500 platforms */
+static struct map_desc u8500_io_desc[] __initdata = {
+	__IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
+};
+
+static struct map_desc u8500ed_io_desc[] __initdata = {
+	__IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K),
+	__IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K),
+};
+
+static struct map_desc u8500v1_io_desc[] __initdata = {
+	__IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
+};
+
+void __init u8500_map_io(void)
+{
+	ux500_map_io();
+
+	iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
+
+	if (cpu_is_u8500ed())
+		iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc));
+	else
+		iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc));
+}
+
+/*
+ * This function is called from the board init
+ */
+void __init u8500_init_devices(void)
+{
+	ux500_init_devices();
+
+	/* Register the platform devices */
+	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
+	return ;
+}
diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c
deleted file mode 100644
index 397bc1f..0000000
--- a/arch/arm/mach-ux500/cpu-u8500.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008-2009 ST-Ericsson
- *
- * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.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/types.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/amba/bus.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-
-#include <asm/hardware/gic.h>
-#include <asm/mach/map.h>
-#include <mach/hardware.h>
-
-/* add any platform devices here - TODO */
-static struct platform_device *platform_devs[] __initdata = {
-	/* yet to be added, add i2c0, gpio.. */
-};
-
-#define __IO_DEV_DESC(x, sz)	{		\
-	.virtual	= IO_ADDRESS(x),	\
-	.pfn		= __phys_to_pfn(x),	\
-	.length		= sz,			\
-	.type		= MT_DEVICE,		\
-}
-
-/* minimum static i/o mapping required to boot U8500 platforms */
-static struct map_desc u8500_io_desc[] __initdata = {
-	__IO_DEV_DESC(U8500_UART2_BASE, SZ_4K),
-	__IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K),
-	__IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
-	__IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
-	__IO_DEV_DESC(U8500_TWD_BASE, SZ_4K),
-	__IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
-	__IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K),
-};
-
-void __init u8500_map_io(void)
-{
-	iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
-}
-
-void __init u8500_init_irq(void)
-{
-	gic_dist_init(0, __io_address(U8500_GIC_DIST_BASE), 29);
-	gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE));
-}
-
-/*
- * This function is called from the board init
- */
-void __init u8500_init_devices(void)
-{
-	/* Register the platform devices */
-	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
-
-	return ;
-}
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
new file mode 100644
index 0000000..d81ad02
--- /dev/null
+++ b/arch/arm/mach-ux500/cpu.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+#include <asm/localtimer.h>
+
+#include <plat/mtu.h>
+#include <mach/hardware.h>
+#include <mach/setup.h>
+#include <mach/devices.h>
+
+#include "clock.h"
+
+static struct map_desc ux500_io_desc[] __initdata = {
+	__IO_DEV_DESC(UX500_UART0_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_UART2_BASE, SZ_4K),
+
+	__IO_DEV_DESC(UX500_GIC_CPU_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_GIC_DIST_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_L2CC_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_TWD_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_SCU_BASE, SZ_4K),
+
+	__IO_DEV_DESC(UX500_CLKRST1_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_CLKRST2_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_CLKRST3_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_CLKRST5_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_CLKRST6_BASE, SZ_4K),
+
+	__IO_DEV_DESC(UX500_MTU0_BASE, SZ_4K),
+	__IO_DEV_DESC(UX500_MTU1_BASE, SZ_4K),
+
+	__IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K),
+};
+
+static struct amba_device *ux500_amba_devs[] __initdata = {
+	&ux500_pl031_device,
+};
+
+void __init ux500_map_io(void)
+{
+	iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc));
+}
+
+void __init ux500_init_devices(void)
+{
+	amba_add_devices(ux500_amba_devs, ARRAY_SIZE(ux500_amba_devs));
+}
+
+void __init ux500_init_irq(void)
+{
+	gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29);
+	gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
+}
+
+#ifdef CONFIG_CACHE_L2X0
+static int ux500_l2x0_init(void)
+{
+	void __iomem *l2x0_base;
+
+	l2x0_base = __io_address(UX500_L2CC_BASE);
+
+	/* 64KB way size, 8 way associativity, force WA */
+	l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
+
+	return 0;
+}
+early_initcall(ux500_l2x0_init);
+#endif
+
+static void __init ux500_timer_init(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+	/* Setup the local timer base */
+	twd_base = __io_address(UX500_TWD_BASE);
+#endif
+	/* Setup the MTU base */
+	if (cpu_is_u8500ed())
+		mtu_base = __io_address(U8500_MTU0_BASE_ED);
+	else
+		mtu_base = __io_address(UX500_MTU0_BASE);
+
+	nmdk_timer_init();
+}
+
+struct sys_timer ux500_timer = {
+	.init	= ux500_timer_init,
+};
diff --git a/arch/arm/mach-ux500/devices-db5500.c b/arch/arm/mach-ux500/devices-db5500.c
new file mode 100644
index 0000000..33e5b56
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-db5500.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/devices.h>
+
+static struct nmk_gpio_platform_data u5500_gpio_data[] = {
+	GPIO_DATA("GPIO-0-31", 0),
+	GPIO_DATA("GPIO-32-63", 32), /* 36..63 not routed to pin */
+	GPIO_DATA("GPIO-64-95", 64), /* 83..95 not routed to pin */
+	GPIO_DATA("GPIO-96-127", 96), /* 102..127 not routed to pin */
+	GPIO_DATA("GPIO-128-159", 128), /* 149..159 not routed to pin */
+	GPIO_DATA("GPIO-160-191", 160),
+	GPIO_DATA("GPIO-192-223", 192),
+	GPIO_DATA("GPIO-224-255", 224), /* 228..255 not routed to pin */
+};
+
+static struct resource u5500_gpio_resources[] = {
+	GPIO_RESOURCE(0),
+	GPIO_RESOURCE(1),
+	GPIO_RESOURCE(2),
+	GPIO_RESOURCE(3),
+	GPIO_RESOURCE(4),
+	GPIO_RESOURCE(5),
+	GPIO_RESOURCE(6),
+	GPIO_RESOURCE(7),
+};
+
+struct platform_device u5500_gpio_devs[] = {
+	GPIO_DEVICE(0),
+	GPIO_DEVICE(1),
+	GPIO_DEVICE(2),
+	GPIO_DEVICE(3),
+	GPIO_DEVICE(4),
+	GPIO_DEVICE(5),
+	GPIO_DEVICE(6),
+	GPIO_DEVICE(7),
+};
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
new file mode 100644
index 0000000..2033423
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/amba/bus.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+static struct nmk_gpio_platform_data u8500_gpio_data[] = {
+	GPIO_DATA("GPIO-0-31", 0),
+	GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */
+	GPIO_DATA("GPIO-64-95", 64),
+	GPIO_DATA("GPIO-96-127", 96), /* 98..127 not routed to pin */
+	GPIO_DATA("GPIO-128-159", 128),
+	GPIO_DATA("GPIO-160-191", 160), /* 172..191 not routed to pin */
+	GPIO_DATA("GPIO-192-223", 192),
+	GPIO_DATA("GPIO-224-255", 224), /* 231..255 not routed to pin */
+	GPIO_DATA("GPIO-256-288", 256), /* 268..288 not routed to pin */
+};
+
+static struct resource u8500_gpio_resources[] = {
+	GPIO_RESOURCE(0),
+	GPIO_RESOURCE(1),
+	GPIO_RESOURCE(2),
+	GPIO_RESOURCE(3),
+	GPIO_RESOURCE(4),
+	GPIO_RESOURCE(5),
+	GPIO_RESOURCE(6),
+	GPIO_RESOURCE(7),
+	GPIO_RESOURCE(8),
+};
+
+struct platform_device u8500_gpio_devs[] = {
+	GPIO_DEVICE(0),
+	GPIO_DEVICE(1),
+	GPIO_DEVICE(2),
+	GPIO_DEVICE(3),
+	GPIO_DEVICE(4),
+	GPIO_DEVICE(5),
+	GPIO_DEVICE(6),
+	GPIO_DEVICE(7),
+	GPIO_DEVICE(8),
+};
+
+struct amba_device u8500_ssp0_device = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.init_name = "ssp0",
+	},
+	.res = {
+		.start = U8500_SSP0_BASE,
+		.end   = U8500_SSP0_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	.irq = {IRQ_SSP0, NO_IRQ },
+	/* ST-Ericsson modified id */
+	.periphid = SSP_PER_ID,
+};
+
+static struct resource u8500_i2c0_resources[] = {
+	[0] = {
+		.start	= U8500_I2C0_BASE,
+		.end	= U8500_I2C0_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_I2C0,
+		.end	= IRQ_I2C0,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device u8500_i2c0_device = {
+	.name		= "nmk-i2c",
+	.id		= 0,
+	.resource	= u8500_i2c0_resources,
+	.num_resources	= ARRAY_SIZE(u8500_i2c0_resources),
+};
+
+static struct resource u8500_i2c4_resources[] = {
+	[0] = {
+		.start	= U8500_I2C4_BASE,
+		.end	= U8500_I2C4_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_I2C4,
+		.end	= IRQ_I2C4,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device u8500_i2c4_device = {
+	.name		= "nmk-i2c",
+	.id		= 4,
+	.resource	= u8500_i2c4_resources,
+	.num_resources	= ARRAY_SIZE(u8500_i2c4_resources),
+};
diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c
new file mode 100644
index 0000000..8a26889
--- /dev/null
+++ b/arch/arm/mach-ux500/devices.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/amba/bus.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+#define __MEM_4K_RESOURCE(x) \
+	.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
+struct amba_device ux500_pl031_device = {
+	.dev = {
+		.init_name = "pl031",
+	},
+	.res = {
+		.start	= UX500_RTC_BASE,
+		.end	= UX500_RTC_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq = {IRQ_RTC_RTT, NO_IRQ},
+};
+
+struct amba_device ux500_uart0_device = {
+	.dev = { .init_name = "uart0" },
+	__MEM_4K_RESOURCE(UX500_UART0_BASE),
+	.irq = {IRQ_UART0, NO_IRQ},
+};
+
+struct amba_device ux500_uart1_device = {
+	.dev = { .init_name = "uart1" },
+	__MEM_4K_RESOURCE(UX500_UART1_BASE),
+	.irq = {IRQ_UART1, NO_IRQ},
+};
+
+struct amba_device ux500_uart2_device = {
+	.dev = { .init_name = "uart2" },
+	__MEM_4K_RESOURCE(UX500_UART2_BASE),
+	.irq = {IRQ_UART2, NO_IRQ},
+};
+
+#define UX500_I2C_RESOURCES(id, size)				\
+static struct resource ux500_i2c##id##_resources[] = {		\
+	[0] = {							\
+		.start	= UX500_I2C##id##_BASE,			\
+		.end	= UX500_I2C##id##_BASE + size - 1,	\
+		.flags	= IORESOURCE_MEM,			\
+	},							\
+	[1] = {							\
+		.start	= IRQ_I2C##id,				\
+		.end	= IRQ_I2C##id,				\
+		.flags	= IORESOURCE_IRQ			\
+	}							\
+}
+
+UX500_I2C_RESOURCES(1, SZ_4K);
+UX500_I2C_RESOURCES(2, SZ_4K);
+UX500_I2C_RESOURCES(3, SZ_4K);
+
+#define UX500_I2C_PDEVICE(cid)					\
+struct platform_device ux500_i2c##cid##_device = {		\
+	.name		= "nmk-i2c",				\
+	.id		= cid,					\
+	.num_resources	= 2,					\
+	.resource	= ux500_i2c##cid##_resources,		\
+}
+
+UX500_I2C_PDEVICE(1);
+UX500_I2C_PDEVICE(2);
+UX500_I2C_PDEVICE(3);
+
+void __init amba_add_devices(struct amba_device *devs[], int num)
+{
+	int i;
+
+	for (i = 0; i < num; i++) {
+		struct amba_device *d = devs[i];
+		amba_device_register(d, &iomem_resource);
+	}
+}
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h
new file mode 100644
index 0000000..545c80f
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_DB5500_REGS_H
+#define __MACH_DB5500_REGS_H
+
+#define U5500_PER1_BASE		0xA0020000
+#define U5500_PER2_BASE		0xA0010000
+#define U5500_PER3_BASE		0x80140000
+#define U5500_PER4_BASE		0x80150000
+#define U5500_PER5_BASE		0x80100000
+#define U5500_PER6_BASE		0x80120000
+
+#define U5500_GIC_DIST_BASE	0xA0411000
+#define U5500_GIC_CPU_BASE	0xA0410100
+#define U5500_DMA_BASE		0x90030000
+#define U5500_MCDE_BASE		0xA0400000
+#define U5500_MODEM_BASE	0xB0000000
+#define U5500_L2CC_BASE		0xA0412000
+#define U5500_SCU_BASE		0xA0410000
+#define U5500_DSI1_BASE		0xA0401000
+#define U5500_DSI2_BASE		0xA0402000
+#define U5500_SIA_BASE		0xA0100000
+#define U5500_SVA_BASE		0x80200000
+#define U5500_HSEM_BASE		0xA0000000
+#define U5500_NAND0_BASE	0x60000000
+#define U5500_NAND1_BASE	0x70000000
+#define U5500_TWD_BASE		0xa0410600
+#define U5500_B2R2_BASE		0xa0200000
+
+#define U5500_FSMC_BASE		(U5500_PER1_BASE + 0x0000)
+#define U5500_SDI0_BASE		(U5500_PER1_BASE + 0x1000)
+#define U5500_SDI2_BASE		(U5500_PER1_BASE + 0x2000)
+#define U5500_UART0_BASE	(U5500_PER1_BASE + 0x3000)
+#define U5500_I2C1_BASE		(U5500_PER1_BASE + 0x4000)
+#define U5500_MSP0_BASE		(U5500_PER1_BASE + 0x5000)
+#define U5500_GPIO0_BASE	(U5500_PER1_BASE + 0xE000)
+#define U5500_CLKRST1_BASE	(U5500_PER1_BASE + 0xF000)
+
+#define U5500_USBOTG_BASE	(U5500_PER2_BASE + 0x0000)
+#define U5500_GPIO1_BASE	(U5500_PER2_BASE + 0xE000)
+#define U5500_CLKRST2_BASE	(U5500_PER2_BASE + 0xF000)
+
+#define U5500_KEYPAD_BASE	(U5500_PER3_BASE + 0x0000)
+#define U5500_PWM_BASE		(U5500_PER3_BASE + 0x1000)
+#define U5500_GPIO3_BASE	(U5500_PER3_BASE + 0xE000)
+#define U5500_CLKRST3_BASE	(U5500_PER3_BASE + 0xF000)
+
+#define U5500_BACKUPRAM0_BASE	(U5500_PER4_BASE + 0x0000)
+#define U5500_BACKUPRAM1_BASE	(U5500_PER4_BASE + 0x1000)
+#define U5500_RTT0_BASE		(U5500_PER4_BASE + 0x2000)
+#define U5500_RTT1_BASE		(U5500_PER4_BASE + 0x3000)
+#define U5500_RTC_BASE		(U5500_PER4_BASE + 0x4000)
+#define U5500_SCR_BASE		(U5500_PER4_BASE + 0x5000)
+#define U5500_DMC_BASE		(U5500_PER4_BASE + 0x6000)
+#define U5500_PRCMU_BASE	(U5500_PER4_BASE + 0x7000)
+#define U5500_MSP1_BASE		(U5500_PER4_BASE + 0x9000)
+#define U5500_GPIO2_BASE	(U5500_PER4_BASE + 0xA000)
+#define U5500_CDETECT_BASE	(U5500_PER4_BASE + 0xF000)
+
+#define U5500_SPI0_BASE		(U5500_PER5_BASE + 0x0000)
+#define U5500_SPI1_BASE		(U5500_PER5_BASE + 0x1000)
+#define U5500_SPI2_BASE		(U5500_PER5_BASE + 0x2000)
+#define U5500_SPI3_BASE		(U5500_PER5_BASE + 0x3000)
+#define U5500_UART1_BASE	(U5500_PER5_BASE + 0x4000)
+#define U5500_UART2_BASE	(U5500_PER5_BASE + 0x5000)
+#define U5500_UART3_BASE	(U5500_PER5_BASE + 0x6000)
+#define U5500_SDI1_BASE		(U5500_PER5_BASE + 0x7000)
+#define U5500_SDI3_BASE		(U5500_PER5_BASE + 0x8000)
+#define U5500_SDI4_BASE		(U5500_PER5_BASE + 0x9000)
+#define U5500_I2C2_BASE		(U5500_PER5_BASE + 0xA000)
+#define U5500_I2C3_BASE		(U5500_PER5_BASE + 0xB000)
+#define U5500_MSP2_BASE		(U5500_PER5_BASE + 0xC000)
+#define U5500_IRDA_BASE		(U5500_PER5_BASE + 0xD000)
+#define U5500_IRRC_BASE		(U5500_PER5_BASE + 0x10000)
+#define U5500_GPIO4_BASE	(U5500_PER5_BASE + 0x1E000)
+#define U5500_CLKRST5_BASE	(U5500_PER5_BASE + 0x1F000)
+
+#define U5500_RNG_BASE		(U5500_PER6_BASE + 0x0000)
+#define U5500_HASH0_BASE	(U5500_PER6_BASE + 0x1000)
+#define U5500_HASH1_BASE	(U5500_PER6_BASE + 0x2000)
+#define U5500_PKA_BASE		(U5500_PER6_BASE + 0x4000)
+#define U5500_PKAM_BASE		(U5500_PER6_BASE + 0x5000)
+#define U5500_MTU0_BASE		(U5500_PER6_BASE + 0x6000)
+#define U5500_MTU1_BASE		(U5500_PER6_BASE + 0x7000)
+#define U5500_CR_BASE		(U5500_PER6_BASE + 0x8000)
+#define U5500_CRYP0_BASE	(U5500_PER6_BASE + 0xA000)
+#define U5500_CRYP1_BASE	(U5500_PER6_BASE + 0xB000)
+#define U5500_CLKRST6_BASE	(U5500_PER6_BASE + 0xF000)
+
+#define U5500_GPIOBANK0_BASE	U5500_GPIO0_BASE
+#define U5500_GPIOBANK1_BASE	(U5500_GPIO0_BASE + 0x80)
+#define U5500_GPIOBANK2_BASE	U5500_GPIO1_BASE
+#define U5500_GPIOBANK3_BASE	U5500_GPIO2_BASE
+#define U5500_GPIOBANK4_BASE	U5500_GPIO3_BASE
+#define U5500_GPIOBANK5_BASE	U5500_GPIO4_BASE
+#define U5500_GPIOBANK6_BASE	(U5500_GPIO4_BASE + 0x80)
+#define U5500_GPIOBANK7_BASE	(U5500_GPIO4_BASE + 0x100)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
new file mode 100644
index 0000000..9169e1e
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_DB8500_REGS_H
+#define __MACH_DB8500_REGS_H
+
+#define U8500_PER3_BASE		0x80000000
+#define U8500_STM_BASE		0x80100000
+#define U8500_STM_REG_BASE	(U8500_STM_BASE + 0xF000)
+#define U8500_PER2_BASE		0x80110000
+#define U8500_PER1_BASE		0x80120000
+#define U8500_B2R2_BASE		0x80130000
+#define U8500_HSEM_BASE		0x80140000
+#define U8500_PER4_BASE		0x80150000
+#define U8500_ICN_BASE		0x81000000
+
+#define U8500_BOOT_ROM_BASE	0x90000000
+/* ASIC ID is at 0xff4 offset within this region */
+#define U8500_ASIC_ID_BASE	0x9001F000
+
+#define U8500_PER6_BASE		0xa03c0000
+#define U8500_PER5_BASE		0xa03e0000
+#define U8500_PER7_BASE_ED	0xa03d0000
+
+#define U8500_SVA_BASE		0xa0100000
+#define U8500_SIA_BASE		0xa0200000
+
+#define U8500_SGA_BASE		0xa0300000
+#define U8500_MCDE_BASE		0xa0350000
+#define U8500_DMA_BASE_ED	0xa0362000
+#define U8500_DMA_BASE		0x801C0000	/* v1 */
+
+#define U8500_SBAG_BASE		0xa0390000
+
+#define U8500_SCU_BASE		0xa0410000
+#define U8500_GIC_CPU_BASE	0xa0410100
+#define U8500_TWD_BASE		0xa0410600
+#define U8500_GIC_DIST_BASE	0xa0411000
+#define U8500_L2CC_BASE		0xa0412000
+
+#define U8500_MODEM_I2C		0xb7e02000
+
+#define U8500_GPIO0_BASE	(U8500_PER1_BASE + 0xE000)
+#define U8500_GPIO1_BASE	(U8500_PER3_BASE + 0xE000)
+#define U8500_GPIO2_BASE	(U8500_PER2_BASE + 0xE000)
+#define U8500_GPIO3_BASE	(U8500_PER5_BASE + 0x1E000)
+
+/* per7 base addressess */
+#define U8500_CR_BASE_ED	(U8500_PER7_BASE_ED + 0x8000)
+#define U8500_MTU0_BASE_ED	(U8500_PER7_BASE_ED + 0xa000)
+#define U8500_MTU1_BASE_ED	(U8500_PER7_BASE_ED + 0xb000)
+#define U8500_TZPC0_BASE_ED	(U8500_PER7_BASE_ED + 0xc000)
+#define U8500_CLKRST7_BASE_ED	(U8500_PER7_BASE_ED + 0xf000)
+
+#define U8500_UART0_BASE	(U8500_PER1_BASE + 0x0000)
+#define U8500_UART1_BASE	(U8500_PER1_BASE + 0x1000)
+
+/* per6 base addressess */
+#define U8500_RNG_BASE		(U8500_PER6_BASE + 0x0000)
+#define U8500_PKA_BASE		(U8500_PER6_BASE + 0x1000)
+#define U8500_PKAM_BASE		(U8500_PER6_BASE + 0x2000)
+#define U8500_MTU0_BASE		(U8500_PER6_BASE + 0x6000) /* v1 */
+#define U8500_MTU1_BASE		(U8500_PER6_BASE + 0x7000) /* v1 */
+#define U8500_CR_BASE		(U8500_PER6_BASE + 0x8000) /* v1 */
+#define U8500_CRYPTO0_BASE	(U8500_PER6_BASE + 0xa000)
+#define U8500_CRYPTO1_BASE	(U8500_PER6_BASE + 0xb000)
+#define U8500_CLKRST6_BASE	(U8500_PER6_BASE + 0xf000)
+
+/* per5 base addressess */
+#define U8500_USBOTG_BASE	(U8500_PER5_BASE + 0x00000)
+#define U8500_CLKRST5_BASE	(U8500_PER5_BASE + 0x1f000)
+
+/* per4 base addressess */
+#define U8500_BACKUPRAM0_BASE	(U8500_PER4_BASE + 0x00000)
+#define U8500_BACKUPRAM1_BASE	(U8500_PER4_BASE + 0x01000)
+#define U8500_RTT0_BASE		(U8500_PER4_BASE + 0x02000)
+#define U8500_RTT1_BASE		(U8500_PER4_BASE + 0x03000)
+#define U8500_RTC_BASE		(U8500_PER4_BASE + 0x04000)
+#define U8500_SCR_BASE		(U8500_PER4_BASE + 0x05000)
+#define U8500_DMC_BASE		(U8500_PER4_BASE + 0x06000)
+#define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x07000)
+#define U8500_PRCMU_TCDM_BASE	(U8500_PER4_BASE + 0x0f000)
+
+/* per3 base addresses */
+#define U8500_FSMC_BASE		(U8500_PER3_BASE + 0x0000)
+#define U8500_SSP0_BASE		(U8500_PER3_BASE + 0x2000)
+#define U8500_SSP1_BASE		(U8500_PER3_BASE + 0x3000)
+#define U8500_I2C0_BASE		(U8500_PER3_BASE + 0x4000)
+#define U8500_SDI2_BASE		(U8500_PER3_BASE + 0x5000)
+#define U8500_SKE_BASE		(U8500_PER3_BASE + 0x6000)
+#define U8500_UART2_BASE	(U8500_PER3_BASE + 0x7000)
+#define U8500_SDI5_BASE		(U8500_PER3_BASE + 0x8000)
+#define U8500_CLKRST3_BASE	(U8500_PER3_BASE + 0xf000)
+
+/* per2 base addressess */
+#define U8500_I2C3_BASE		(U8500_PER2_BASE + 0x0000)
+#define U8500_SPI2_BASE		(U8500_PER2_BASE + 0x1000)
+#define U8500_SPI1_BASE		(U8500_PER2_BASE + 0x2000)
+#define U8500_PWL_BASE		(U8500_PER2_BASE + 0x3000)
+#define U8500_SDI4_BASE		(U8500_PER2_BASE + 0x4000)
+#define U8500_MSP2_BASE		(U8500_PER2_BASE + 0x7000)
+#define U8500_SDI1_BASE		(U8500_PER2_BASE + 0x8000)
+#define U8500_SDI3_BASE		(U8500_PER2_BASE + 0x9000)
+#define U8500_SPI0_BASE		(U8500_PER2_BASE + 0xa000)
+#define U8500_HSIR_BASE		(U8500_PER2_BASE + 0xb000)
+#define U8500_HSIT_BASE		(U8500_PER2_BASE + 0xc000)
+#define U8500_CLKRST2_BASE	(U8500_PER2_BASE + 0xf000)
+
+/* per1 base addresses */
+#define U8500_I2C1_BASE		(U8500_PER1_BASE + 0x2000)
+#define U8500_MSP0_BASE		(U8500_PER1_BASE + 0x3000)
+#define U8500_MSP1_BASE		(U8500_PER1_BASE + 0x4000)
+#define U8500_SDI0_BASE		(U8500_PER1_BASE + 0x6000)
+#define U8500_I2C2_BASE		(U8500_PER1_BASE + 0x8000)
+#define U8500_SPI3_BASE		(U8500_PER1_BASE + 0x9000)
+#define U8500_I2C4_BASE		(U8500_PER1_BASE + 0xa000)
+#define U8500_SLIM0_BASE	(U8500_PER1_BASE + 0xb000)
+#define U8500_CLKRST1_BASE	(U8500_PER1_BASE + 0xf000)
+
+#define U8500_SHRM_GOP_INTERRUPT_BASE	0xB7C00040
+
+#define U8500_GPIOBANK0_BASE	U8500_GPIO0_BASE
+#define U8500_GPIOBANK1_BASE	(U8500_GPIO0_BASE + 0x80)
+#define U8500_GPIOBANK2_BASE	U8500_GPIO1_BASE
+#define U8500_GPIOBANK3_BASE	(U8500_GPIO1_BASE + 0x80)
+#define U8500_GPIOBANK4_BASE	(U8500_GPIO1_BASE + 0x100)
+#define U8500_GPIOBANK5_BASE	(U8500_GPIO1_BASE + 0x180)
+#define U8500_GPIOBANK6_BASE	U8500_GPIO2_BASE
+#define U8500_GPIOBANK7_BASE	(U8500_GPIO2_BASE + 0x80)
+#define U8500_GPIOBANK8_BASE	U8500_GPIO3_BASE
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/debug-macro.S b/arch/arm/mach-ux500/include/mach/debug-macro.S
index 09cbfda..c5203b7 100644
--- a/arch/arm/mach-ux500/include/mach/debug-macro.S
+++ b/arch/arm/mach-ux500/include/mach/debug-macro.S
@@ -10,11 +10,19 @@
  */
 #include <mach/hardware.h>
 
+#if CONFIG_UX500_DEBUG_UART > 2
+#error Invalid Ux500 debug UART
+#endif
+
+#define __UX500_UART(n)	UX500_UART##n##_BASE
+#define UX500_UART(n)	__UX500_UART(n)
+#define UART_BASE	UX500_UART(CONFIG_UX500_DEBUG_UART)
+
 	.macro	addruart, rx, tmp
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1					@ MMU enabled?
-	ldreq	\rx, =U8500_UART2_BASE			@ no, physical address
-	ldrne	\rx, =IO_ADDRESS(U8500_UART2_BASE)	@ yes, virtual address
+	ldreq	\rx, =UART_BASE				@ no, physical address
+	ldrne	\rx, =IO_ADDRESS(UART_BASE)		@ yes, virtual address
 	.endm
 
 #include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h
new file mode 100644
index 0000000..0422af0
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/devices.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __ASM_ARCH_DEVICES_H__
+#define __ASM_ARCH_DEVICES_H__
+
+struct platform_device;
+struct amba_device;
+
+extern struct platform_device u5500_gpio_devs[];
+extern struct platform_device u8500_gpio_devs[];
+
+extern struct amba_device ux500_pl031_device;
+extern struct amba_device u8500_ssp0_device;
+extern struct amba_device ux500_uart0_device;
+extern struct amba_device ux500_uart1_device;
+extern struct amba_device ux500_uart2_device;
+
+extern struct platform_device ux500_i2c1_device;
+extern struct platform_device ux500_i2c2_device;
+extern struct platform_device ux500_i2c3_device;
+
+extern struct platform_device u8500_i2c0_device;
+extern struct platform_device u8500_i2c4_device;
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S
index eece330..60ea88d 100644
--- a/arch/arm/mach-ux500/include/mach/entry-macro.S
+++ b/arch/arm/mach-ux500/include/mach/entry-macro.S
@@ -17,7 +17,7 @@
 		.endm
 
 		.macro  get_irqnr_preamble, base, tmp
-		ldr     \base, =IO_ADDRESS(U8500_GIC_CPU_BASE)
+		ldr     \base, =IO_ADDRESS(UX500_GIC_CPU_BASE)
 		.endm
 
 		.macro  arch_ret_to_user, tmp1, tmp2
diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h
new file mode 100644
index 0000000..d548a62
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/gpio.h
@@ -0,0 +1,50 @@
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+/*
+ * 288 (#267 is the highest one actually hooked up) onchip GPIOs, plus enough
+ * room for a couple of GPIO expanders.
+ */
+#define ARCH_NR_GPIOS	350
+
+#include <plat/gpio.h>
+
+#define __GPIO_RESOURCE(soc, block)					\
+	{								\
+		.start	= soc##_GPIOBANK##block##_BASE,			\
+		.end	= soc##_GPIOBANK##block##_BASE + 127,		\
+		.flags	= IORESOURCE_MEM,				\
+	},								\
+	{								\
+		.start	= IRQ_GPIO##block,				\
+		.end	= IRQ_GPIO##block,				\
+		.flags	= IORESOURCE_IRQ,				\
+	}
+
+#define __GPIO_DEVICE(soc, block)					\
+	{								\
+		.name		= "gpio",				\
+		.id		= block,				\
+		.num_resources	= 2,					\
+		.resource	= &soc##_gpio_resources[block * 2],	\
+		.dev = {						\
+			.platform_data = &soc##_gpio_data[block],	\
+		},							\
+	}
+
+#define GPIO_DATA(_name, first)						\
+	{								\
+		.name		= _name,				\
+		.first_gpio	= first,				\
+		.first_irq	= NOMADIK_GPIO_TO_IRQ(first),		\
+	}
+
+#ifdef CONFIG_UX500_SOC_DB8500
+#define GPIO_RESOURCE(block)	__GPIO_RESOURCE(U8500, block)
+#define GPIO_DEVICE(block)	__GPIO_DEVICE(u8500, block)
+#elif defined(CONFIG_UX500_SOC_DB5500)
+#define GPIO_RESOURCE(block)	__GPIO_RESOURCE(U5500, block)
+#define GPIO_DEVICE(block)	__GPIO_DEVICE(u5500, block)
+#endif
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
index 04ea836..8656379 100644
--- a/arch/arm/mach-ux500/include/mach/hardware.h
+++ b/arch/arm/mach-ux500/include/mach/hardware.h
@@ -23,109 +23,106 @@
 
 /* typesafe io address */
 #define __io_address(n)		__io(IO_ADDRESS(n))
+/* used by some plat-nomadik code */
+#define io_p2v(n)		__io_address(n)
 
-/*
- * Base address definitions for U8500 Onchip IPs. All the
- * peripherals are contained in a single 1 Mbyte region, with
- * AHB peripherals at the bottom and APB peripherals at the
- * top of the region. PER stands for PERIPHERAL region which
- * itself divided into sub regions.
- */
-#define U8500_PER3_BASE		0x80000000
-#define U8500_PER2_BASE		0x80110000
-#define U8500_PER1_BASE		0x80120000
-#define U8500_PER4_BASE		0x80150000
+#include <mach/db8500-regs.h>
+#include <mach/db5500-regs.h>
 
-#define U8500_PER6_BASE		0xa03c0000
-#define U8500_PER5_BASE		0xa03e0000
-#define U8500_PER7_BASE		0xa03d0000
+#ifdef CONFIG_UX500_SOC_DB8500
+#define UX500(periph)		U8500_##periph##_BASE
+#elif defined(CONFIG_UX500_SOC_DB5500)
+#define UX500(periph)		U5500_##periph##_BASE
+#endif
 
-#define U8500_SVA_BASE		0xa0100000
-#define U8500_SIA_BASE		0xa0200000
+#define UX500_BACKUPRAM0_BASE	UX500(BACKUPRAM0)
+#define UX500_BACKUPRAM1_BASE	UX500(BACKUPRAM1)
+#define UX500_B2R2_BASE		UX500(B2R2)
 
-#define U8500_SGA_BASE		0xa0300000
-#define U8500_MCDE_BASE		0xa0350000
-#define U8500_DMA_BASE		0xa0362000
+#define UX500_CLKRST1_BASE	UX500(CLKRST1)
+#define UX500_CLKRST2_BASE	UX500(CLKRST2)
+#define UX500_CLKRST3_BASE	UX500(CLKRST3)
+#define UX500_CLKRST5_BASE	UX500(CLKRST5)
+#define UX500_CLKRST6_BASE	UX500(CLKRST6)
 
-#define U8500_SCU_BASE		0xa0410000
-#define U8500_GIC_CPU_BASE	0xa0410100
-#define U8500_TWD_BASE		0xa0410600
-#define U8500_GIC_DIST_BASE	0xa0411000
-#define U8500_L2CC_BASE		0xa0412000
+#define UX500_DMA_BASE		UX500(DMA)
+#define UX500_FSMC_BASE		UX500(FSMC)
 
-#define U8500_TWD_SIZE		0x100
+#define UX500_GIC_CPU_BASE	UX500(GIC_CPU)
+#define UX500_GIC_DIST_BASE	UX500(GIC_DIST)
 
-/* per7 base addressess */
-#define U8500_CR_BASE		(U8500_PER7_BASE + 0x8000)
-#define U8500_MTU0_BASE		(U8500_PER7_BASE + 0xa000)
-#define U8500_MTU1_BASE		(U8500_PER7_BASE + 0xb000)
-#define U8500_TZPC0_BASE	(U8500_PER7_BASE + 0xc000)
-#define U8500_CLKRST7_BASE	(U8500_PER7_BASE + 0xf000)
+#define UX500_I2C1_BASE		UX500(I2C1)
+#define UX500_I2C2_BASE		UX500(I2C2)
+#define UX500_I2C3_BASE		UX500(I2C3)
 
-/* per6 base addressess */
-#define U8500_RNG_BASE		(U8500_PER6_BASE + 0x0000)
-#define U8500_PKA_BASE		(U8500_PER6_BASE + 0x1000)
-#define U8500_PKAM_BASE		(U8500_PER6_BASE + 0x2000)
-#define U8500_CRYPTO0_BASE	(U8500_PER6_BASE + 0xa000)
-#define U8500_CRYPTO1_BASE	(U8500_PER6_BASE + 0xb000)
-#define U8500_CLKRST6_BASE	(U8500_PER6_BASE + 0xf000)
+#define UX500_L2CC_BASE		UX500(L2CC)
+#define UX500_MCDE_BASE		UX500(MCDE)
+#define UX500_MTU0_BASE		UX500(MTU0)
+#define UX500_MTU1_BASE		UX500(MTU1)
+#define UX500_PRCMU_BASE	UX500(PRCMU)
 
-/* per5 base addressess */
-#define U8500_USBOTG_BASE	(U8500_PER5_BASE + 0x00000)
-#define U8500_GPIO5_BASE	(U8500_PER5_BASE + 0x1e000)
-#define U8500_CLKRST5_BASE	(U8500_PER5_BASE + 0x1f000)
+#define UX500_RNG_BASE		UX500(RNG)
+#define UX500_RTC_BASE		UX500(RTC)
 
-/* per4 base addressess */
-#define U8500_BACKUPRAM0_BASE	(U8500_PER4_BASE + 0x0000)
-#define U8500_BACKUPRAM1_BASE	(U8500_PER4_BASE + 0x1000)
-#define U8500_RTT0_BASE		(U8500_PER4_BASE + 0x2000)
-#define U8500_RTT1_BASE		(U8500_PER4_BASE + 0x3000)
-#define U8500_RTC_BASE		(U8500_PER4_BASE + 0x4000)
-#define U8500_SCR_BASE		(U8500_PER4_BASE + 0x5000)
-#define U8500_DMC_BASE		(U8500_PER4_BASE + 0x6000)
-#define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x7000)
+#define UX500_SCU_BASE		UX500(SCU)
 
-/* per3 base addressess */
-#define U8500_FSMC_BASE		(U8500_PER3_BASE + 0x0000)
-#define U8500_SSP0_BASE		(U8500_PER3_BASE + 0x2000)
-#define U8500_SSP1_BASE		(U8500_PER3_BASE + 0x3000)
-#define U8500_I2C0_BASE		(U8500_PER3_BASE + 0x4000)
-#define U8500_SDI2_BASE		(U8500_PER3_BASE + 0x5000)
-#define U8500_SKE_BASE		(U8500_PER3_BASE + 0x6000)
-#define U8500_UART2_BASE	(U8500_PER3_BASE + 0x7000)
-#define U8500_SDI5_BASE		(U8500_PER3_BASE + 0x8000)
-#define U8500_GPIO3_BASE	(U8500_PER3_BASE + 0xe000)
-#define U8500_CLKRST3_BASE	(U8500_PER3_BASE + 0xf000)
+#define UX500_SDI0_BASE		UX500(SDI0)
+#define UX500_SDI1_BASE		UX500(SDI1)
+#define UX500_SDI2_BASE		UX500(SDI2)
+#define UX500_SDI3_BASE		UX500(SDI3)
+#define UX500_SDI4_BASE		UX500(SDI4)
 
-/* per2 base addressess */
-#define U8500_I2C3_BASE		(U8500_PER2_BASE + 0x0000)
-#define U8500_SPI2_BASE		(U8500_PER2_BASE + 0x1000)
-#define U8500_SPI1_BASE		(U8500_PER2_BASE + 0x2000)
-#define U8500_PWL_BASE		(U8500_PER2_BASE + 0x3000)
-#define U8500_SDI4_BASE		(U8500_PER2_BASE + 0x4000)
-#define U8500_MSP2_BASE		(U8500_PER2_BASE + 0x7000)
-#define U8500_SDI1_BASE		(U8500_PER2_BASE + 0x8000)
-#define U8500_SDI3_BASE		(U8500_PER2_BASE + 0x9000)
-#define U8500_SPI0_BASE		(U8500_PER2_BASE + 0xa000)
-#define U8500_HSIR_BASE		(U8500_PER2_BASE + 0xb000)
-#define U8500_HSIT_BASE		(U8500_PER2_BASE + 0xc000)
-#define U8500_GPIO2_BASE	(U8500_PER2_BASE + 0xe000)
-#define U8500_CLKRST2_BASE	(U8500_PER2_BASE + 0xf000)
+#define UX500_SPI0_BASE		UX500(SPI0)
+#define UX500_SPI1_BASE		UX500(SPI1)
+#define UX500_SPI2_BASE		UX500(SPI2)
+#define UX500_SPI3_BASE		UX500(SPI3)
 
-/* per1 base addresses */
-#define U8500_UART0_BASE	(U8500_PER1_BASE + 0x0000)
-#define U8500_UART1_BASE	(U8500_PER1_BASE + 0x1000)
-#define U8500_I2C1_BASE		(U8500_PER1_BASE + 0x2000)
-#define U8500_MSP0_BASE		(U8500_PER1_BASE + 0x3000)
-#define U8500_MSP1_BASE		(U8500_PER1_BASE + 0x4000)
-#define U8500_SDI0_BASE		(U8500_PER1_BASE + 0x6000)
-#define U8500_I2C2_BASE		(U8500_PER1_BASE + 0x8000)
-#define U8500_SPI3_BASE		(U8500_PER1_BASE + 0x9000)
-#define U8500_SLIM0_BASE	(U8500_PER1_BASE + 0xa000)
-#define U8500_GPIO1_BASE	(U8500_PER1_BASE + 0xe000)
-#define U8500_CLKRST1_BASE	(U8500_PER1_BASE + 0xf000)
+#define UX500_SIA_BASE		UX500(SIA)
+#define UX500_SVA_BASE		UX500(SVA)
+
+#define UX500_TWD_BASE		UX500(TWD)
+
+#define UX500_UART0_BASE	UX500(UART0)
+#define UX500_UART1_BASE	UX500(UART1)
+#define UX500_UART2_BASE	UX500(UART2)
+
+#define UX500_USBOTG_BASE	UX500(USBOTG)
 
 /* ST-Ericsson modified pl022 id */
 #define SSP_PER_ID		0x01080022
 
+#ifndef __ASSEMBLY__
+
+#include <asm/cputype.h>
+
+static inline bool cpu_is_u8500(void)
+{
+#ifdef CONFIG_UX500_SOC_DB8500
+	return 1;
+#else
+	return 0;
+#endif
+}
+
+static inline bool cpu_is_u8500ed(void)
+{
+	return cpu_is_u8500() && (read_cpuid_id() & 15) == 0;
+}
+
+static inline bool cpu_is_u8500v1(void)
+{
+	return cpu_is_u8500() && (read_cpuid_id() & 15) == 1;
+}
+
+static inline bool cpu_is_u5500(void)
+{
+#ifdef CONFIG_UX500_SOC_DB5500
+	return 1;
+#else
+	return 0;
+#endif
+}
+
+#endif
+
 #endif				/* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h
index 394b5dd..7970684 100644
--- a/arch/arm/mach-ux500/include/mach/irqs.h
+++ b/arch/arm/mach-ux500/include/mach/irqs.h
@@ -42,6 +42,7 @@
 #define IRQ_AB4500		(IRQ_SHPI_START + 40)
 #define IRQ_DISP		(IRQ_SHPI_START + 48)
 #define IRQ_SiPI3		(IRQ_SHPI_START + 49)
+#define IRQ_I2C4		(IRQ_SHPI_START + 51)
 #define IRQ_SSP1		(IRQ_SHPI_START + 52)
 #define IRQ_I2C2		(IRQ_SHPI_START + 55)
 #define IRQ_SDMMC0		(IRQ_SHPI_START + 60)
@@ -66,6 +67,12 @@
 /* There are 128 shared peripheral interrupts assigned to
  * INTID[160:32]. The first 32 interrupts are reserved.
  */
-#define NR_IRQS			161
+#define U8500_SOC_NR_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)
 
 #endif /*ASM_ARCH_IRQS_H*/
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index cf0ce16..e978dbd 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -14,10 +14,28 @@
 #include <asm/mach/time.h>
 #include <linux/init.h>
 
-extern void u8500_map_io(void);
-extern void u8500_init_devices(void);
-extern void u8500_init_irq(void);
+extern void __init ux500_map_io(void);
+extern void __init u5500_map_io(void);
+extern void __init u8500_map_io(void);
+
+extern void __init ux500_init_devices(void);
+extern void __init u5500_init_devices(void);
+extern void __init u8500_init_devices(void);
+
+extern void __init ux500_init_irq(void);
 /* We re-use nomadik_timer for this platform */
 extern void nmdk_timer_init(void);
 
+extern void __init amba_add_devices(struct amba_device *devs[], int num);
+
+struct sys_timer;
+extern struct sys_timer ux500_timer;
+
+#define __IO_DEV_DESC(x, sz)	{		\
+	.virtual	= IO_ADDRESS(x),	\
+	.pfn		= __phys_to_pfn(x),	\
+	.length		= sz,			\
+	.type		= MT_DEVICE,		\
+}
+
 #endif /*  __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 8dfe7ca..438ef16 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -30,7 +30,7 @@
 
 static unsigned int __init get_core_count(void)
 {
-	return scu_get_core_count(__io_address(U8500_SCU_BASE));
+	return scu_get_core_count(__io_address(UX500_SCU_BASE));
 }
 
 static DEFINE_SPINLOCK(boot_lock);
@@ -44,7 +44,7 @@
 	 * core (e.g. timer irq), then they will not have been enabled
 	 * for us: do so
 	 */
-	gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE));
+	gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
 
 	/*
 	 * let the primary processor know we're out of the
@@ -75,7 +75,8 @@
 	 * that it has been released by resetting pen_release.
 	 */
 	pen_release = cpu;
-	flush_cache_all();
+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+	outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1);
 
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
@@ -105,12 +106,12 @@
 	 */
 #define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4
 	__raw_writel(virt_to_phys(u8500_secondary_startup),
-		(void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) +
+		__io_address(UX500_BACKUPRAM0_BASE) +
 		U8500_CPU1_JUMPADDR_OFFSET);
 
 #define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
 	__raw_writel(0xA1FEED01,
-		(void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) +
+		__io_address(UX500_BACKUPRAM0_BASE) +
 		U8500_CPU1_WAKEMAGIC_OFFSET);
 
 	/* make sure write buffer is drained */
@@ -171,7 +172,7 @@
 		 * boot CPU, but only if we have more than one CPU.
 		 */
 		percpu_timer_setup();
-		scu_enable(__io_address(U8500_SCU_BASE));
+		scu_enable(__io_address(UX500_SCU_BASE));
 		wakeup_secondary();
 	}
 }
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
index ba81e70..97cf4d8 100644
--- a/arch/arm/mach-versatile/Makefile
+++ b/arch/arm/mach-versatile/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-y					:= core.o clock.o
+obj-y					:= core.o
 obj-$(CONFIG_ARCH_VERSATILE_PB)		+= versatile_pb.o
 obj-$(CONFIG_MACH_VERSATILE_AB)		+= versatile_ab.o
 obj-$(CONFIG_PCI)			+= pci.o
diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c
deleted file mode 100644
index c50a44e..0000000
--- a/arch/arm/mach-versatile/clock.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  linux/arch/arm/mach-versatile/clock.c
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-
-#include <asm/clkdev.h>
-#include <asm/hardware/icst307.h>
-
-#include "clock.h"
-
-int clk_enable(struct clk *clk)
-{
-	return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	struct icst307_vco vco;
-	vco = icst307_khz_to_vco(clk->params, rate / 1000);
-	return icst307_khz(clk->params, vco) * 1000;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -EIO;
-
-	if (clk->setvco) {
-		struct icst307_vco vco;
-
-		vco = icst307_khz_to_vco(clk->params, rate / 1000);
-		clk->rate = icst307_khz(clk->params, vco) * 1000;
-		clk->setvco(clk, vco);
-		ret = 0;
-	}
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h
deleted file mode 100644
index 03468fdc..0000000
--- a/arch/arm/mach-versatile/clock.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *  linux/arch/arm/mach-versatile/clock.h
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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.
- */
-struct module;
-struct icst307_params;
-
-struct clk {
-	unsigned long		rate;
-	const struct icst307_params *params;
-	u32			oscoff;
-	void			*data;
-	void			(*setvco)(struct clk *, struct icst307_vco vco);
-};
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 3b1a4ee..3dff864 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -28,19 +28,15 @@
 #include <linux/amba/clcd.h>
 #include <linux/amba/pl061.h>
 #include <linux/amba/mmci.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/cnt32_to_63.h>
 #include <linux/io.h>
 #include <linux/gfp.h>
 
 #include <asm/clkdev.h>
 #include <asm/system.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/hardware/arm_timer.h>
-#include <asm/hardware/icst307.h>
+#include <asm/hardware/icst.h>
 #include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 
@@ -49,9 +45,12 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
+#include <mach/clkdev.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <plat/timer-sp.h>
 
 #include "core.h"
-#include "clock.h"
 
 /*
  * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
@@ -59,7 +58,6 @@
  *
  * Setup a VA for the Versatile Vectored Interrupt Controller.
  */
-#define __io_address(n)		__io(IO_ADDRESS(n))
 #define VA_VIC_BASE		__io_address(VERSATILE_VIC_BASE)
 #define VA_SIC_BASE		__io_address(VERSATILE_SIC_BASE)
 
@@ -229,27 +227,6 @@
 	iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
 }
 
-#define VERSATILE_REFCOUNTER	(__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
-
-/*
- * This is the Versatile sched_clock implementation.  This has
- * a resolution of 41.7ns, and a maximum value of about 35583 days.
- *
- * The return value is guaranteed to be monotonic in that range as
- * long as there is always less than 89 seconds between successive
- * calls to this function.
- */
-unsigned long long sched_clock(void)
-{
-	unsigned long long v = cnt32_to_63(readl(VERSATILE_REFCOUNTER));
-
-	/* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
-	v *= 125<<1;
-	do_div(v, 3<<1);
-
-	return v;
-}
-
 
 #define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
 
@@ -380,35 +357,42 @@
 /*
  * Clock handling
  */
-static const struct icst307_params versatile_oscvco_params = {
-	.ref		= 24000,
-	.vco_max	= 200000,
+static const struct icst_params versatile_oscvco_params = {
+	.ref		= 24000000,
+	.vco_max	= ICST307_VCO_MAX,
+	.vco_min	= ICST307_VCO_MIN,
 	.vd_min		= 4 + 8,
 	.vd_max		= 511 + 8,
 	.rd_min		= 1 + 2,
 	.rd_max		= 127 + 2,
+	.s2div		= icst307_s2div,
+	.idx2s		= icst307_idx2s,
 };
 
-static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco)
+static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco)
 {
-	void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
-	void __iomem *sys_lock = sys + VERSATILE_SYS_LOCK_OFFSET;
+	void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
 	u32 val;
 
-	val = readl(sys + clk->oscoff) & ~0x7ffff;
+	val = readl(clk->vcoreg) & ~0x7ffff;
 	val |= vco.v | (vco.r << 9) | (vco.s << 16);
 
 	writel(0xa05f, sys_lock);
-	writel(val, sys + clk->oscoff);
+	writel(val, clk->vcoreg);
 	writel(0, sys_lock);
 }
 
-static struct clk osc4_clk = {
-	.params	= &versatile_oscvco_params,
-	.oscoff	= VERSATILE_SYS_OSCCLCD_OFFSET,
+static const struct clk_ops osc4_clk_ops = {
+	.round	= icst_clk_round,
+	.set	= icst_clk_set,
 	.setvco	= versatile_oscvco_set,
 };
 
+static struct clk osc4_clk = {
+	.ops	= &osc4_clk_ops,
+	.params	= &versatile_oscvco_params,
+};
+
 /*
  * These are fixed clocks.
  */
@@ -852,6 +836,8 @@
 {
 	int i;
 
+	osc4_clk.vcoreg	= __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET;
+
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	platform_device_register(&versatile_flash_device);
@@ -875,120 +861,6 @@
 #define TIMER1_VA_BASE		(__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
 #define TIMER2_VA_BASE		 __io_address(VERSATILE_TIMER2_3_BASE)
 #define TIMER3_VA_BASE		(__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
-#define VA_IC_BASE		 __io_address(VERSATILE_VIC_BASE) 
-
-/*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD	(TIMER_INTERVAL >> 8)
-#define TIMER_DIVISOR	(TIMER_CTRL_DIV256)
-#define TICKS2USECS(x)	(256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TIMER_RELOAD	(TIMER_INTERVAL >> 4)		/* Divide by 16 */
-#define TIMER_DIVISOR	(TIMER_CTRL_DIV16)
-#define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)
-#else
-#define TIMER_RELOAD	(TIMER_INTERVAL)
-#define TIMER_DIVISOR	(TIMER_CTRL_DIV1)
-#define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
-#endif
-
-static void timer_set_mode(enum clock_event_mode mode,
-			   struct clock_event_device *clk)
-{
-	unsigned long ctrl;
-
-	switch(mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
-
-		ctrl = TIMER_CTRL_PERIODIC;
-		ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* period set, and timer enabled in 'next_event' hook */
-		ctrl = TIMER_CTRL_ONESHOT;
-		ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	default:
-		ctrl = 0;
-	}
-
-	writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
-}
-
-static int timer_set_next_event(unsigned long evt,
-				struct clock_event_device *unused)
-{
-	unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
-
-	writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
-	writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
-
-	return 0;
-}
-
-static struct clock_event_device timer0_clockevent =	 {
-	.name		= "timer0",
-	.shift		= 32,
-	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode	= timer_set_mode,
-	.set_next_event	= timer_set_next_event,
-};
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = &timer0_clockevent;
-
-	writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction versatile_timer_irq = {
-	.name		= "Versatile Timer Tick",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= versatile_timer_interrupt,
-};
-
-static cycle_t versatile_get_cycles(struct clocksource *cs)
-{
-	return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
-}
-
-static struct clocksource clocksource_versatile = {
-	.name 		= "timer3",
- 	.rating		= 200,
- 	.read		= versatile_get_cycles,
-	.mask		= CLOCKSOURCE_MASK(32),
- 	.shift 		= 20,
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static int __init versatile_clocksource_init(void)
-{
-	/* setup timer3 as free-running clocksource */
-	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
-	writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
-	writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
-	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
-	       TIMER3_VA_BASE + TIMER_CTRL);
-
- 	clocksource_versatile.mult =
- 		clocksource_khz2mult(1000, clocksource_versatile.shift);
- 	clocksource_register(&clocksource_versatile);
-
- 	return 0;
-}
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
@@ -1017,22 +889,8 @@
 	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
 	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
 
-	/* 
-	 * Make irqs happen for the system timer
-	 */
-	setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
-
-	versatile_clocksource_init();
-
-	timer0_clockevent.mult =
-		div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
-	timer0_clockevent.max_delta_ns =
-		clockevent_delta2ns(0xffffffff, &timer0_clockevent);
-	timer0_clockevent.min_delta_ns =
-		clockevent_delta2ns(0xf, &timer0_clockevent);
-
-	timer0_clockevent.cpumask = cpumask_of(0);
-	clockevents_register_device(&timer0_clockevent);
+	sp804_clocksource_init(TIMER3_VA_BASE);
+	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1);
 }
 
 struct sys_timer versatile_timer = {
diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
index 04b37a8..e58d077 100644
--- a/arch/arm/mach-versatile/include/mach/clkdev.h
+++ b/arch/arm/mach-versatile/include/mach/clkdev.h
@@ -1,6 +1,15 @@
 #ifndef __ASM_MACH_CLKDEV_H
 #define __ASM_MACH_CLKDEV_H
 
+#include <plat/clock.h>
+
+struct clk {
+	unsigned long		rate;
+	const struct clk_ops	*ops;
+	const struct icst_params *params;
+	void __iomem		*vcoreg;
+};
+
 #define __clk_get(clk) ({ 1; })
 #define __clk_put(clk) do { } while (0)
 
diff --git a/arch/arm/mach-versatile/include/mach/entry-macro.S b/arch/arm/mach-versatile/include/mach/entry-macro.S
index 8c80209..e6f7c16 100644
--- a/arch/arm/mach-versatile/include/mach/entry-macro.S
+++ b/arch/arm/mach-versatile/include/mach/entry-macro.S
@@ -8,6 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/hardware/vic.h>
 
 		.macro	disable_fiq
diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h
index 7aa906c..4f8f99a 100644
--- a/arch/arm/mach-versatile/include/mach/hardware.h
+++ b/arch/arm/mach-versatile/include/mach/hardware.h
@@ -23,7 +23,6 @@
 #define __ASM_ARCH_HARDWARE_H
 
 #include <asm/sizes.h>
-#include <mach/platform.h>
 
 /*
  * PCI space virtual addresses
@@ -49,4 +48,6 @@
 /* macro to get at IO space when running virtually */
 #define IO_ADDRESS(x)		(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
 
+#define __io_address(n)		__io(IO_ADDRESS(n))
+
 #endif
diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
index 8320739..ec08740 100644
--- a/arch/arm/mach-versatile/include/mach/platform.h
+++ b/arch/arm/mach-versatile/include/mach/platform.h
@@ -205,7 +205,7 @@
 #define VERSATILE_CLCD_BASE            0x10120000	/* CLCD */
 #define VERSATILE_DMAC_BASE            0x10130000	/* DMA controller */
 #define VERSATILE_VIC_BASE             0x10140000	/* Vectored interrupt controller */
-#define VERSATILE_PERIPH_BASE          0x10150000    /* off-chip peripherals alias from */
+#define VERSATILE_PERIPH_BASE          0x10150000	/* off-chip peripherals alias from */
                                                 /* 0x10000000 - 0x100FFFFF */
 #define VERSATILE_AHBM_BASE            0x101D0000	/* AHB monitor */
 #define VERSATILE_SCTL_BASE            0x101E0000	/* System controller */
@@ -213,7 +213,7 @@
 #define VERSATILE_TIMER0_1_BASE        0x101E2000	/* Timer 0 and 1 */
 #define VERSATILE_TIMER2_3_BASE        0x101E3000	/* Timer 2 and 3 */
 #define VERSATILE_GPIO0_BASE           0x101E4000	/* GPIO port 0 */
-#define VERSATILE_GPIO1_BASE           0x101E5000    /* GPIO port 1 */
+#define VERSATILE_GPIO1_BASE           0x101E5000	/* GPIO port 1 */
 #define VERSATILE_GPIO2_BASE           0x101E6000	/* GPIO port 2 */
 #define VERSATILE_GPIO3_BASE           0x101E7000	/* GPIO port 3 */
 #define VERSATILE_RTC_BASE             0x101E8000	/* Real Time Clock */
@@ -379,12 +379,6 @@
 #define SIC_INT_PCI3                    30
 
 
-/* 
- *  Clean base - dummy
- * 
- */
-#define CLEAN_BASE                      VERSATILE_BOOT_ROM_HI
-
 /*
  * System controller bit assignment
  */
@@ -397,20 +391,6 @@
 #define VERSATILE_TIMER4_EnSel	21
 
 
-#define MAX_TIMER                       2
-#define MAX_PERIOD                      699050
-#define TICKS_PER_uSEC                  1
-
-/* 
- *  These are useconds NOT ticks.  
- * 
- */
-#define mSEC_1                          1000
-#define mSEC_5                          (mSEC_1 * 5)
-#define mSEC_10                         (mSEC_1 * 10)
-#define mSEC_25                         (mSEC_1 * 25)
-#define SEC_1                           (mSEC_1 * 1000)
-
 #define VERSATILE_CSR_BASE             0x10000000
 #define VERSATILE_CSR_SIZE             0x10000000
 
@@ -432,5 +412,3 @@
 #endif
 
 #endif
-
-/* 	END */
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
new file mode 100644
index 0000000..3f19b66
--- /dev/null
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -0,0 +1,9 @@
+menu "Versatile Express platform type"
+	depends on ARCH_VEXPRESS
+
+config ARCH_VEXPRESS_CA9X4
+	bool "Versatile Express Cortex-A9x4 tile"
+	select CPU_V7
+	select ARM_GIC
+
+endmenu
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
new file mode 100644
index 0000000..1b71b77
--- /dev/null
+++ b/arch/arm/mach-vexpress/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y					:= v2m.o
+obj-$(CONFIG_ARCH_VEXPRESS_CA9X4)	+= ct-ca9x4.o
+obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
+obj-$(CONFIG_LOCAL_TIMERS)		+= localtimer.o
diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot
new file mode 100644
index 0000000..07c2d9c
--- /dev/null
+++ b/arch/arm/mach-vexpress/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x60008000
+params_phys-y	:= 0x60000100
+initrd_phys-y	:= 0x60800000
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
new file mode 100644
index 0000000..57dd95c
--- /dev/null
+++ b/arch/arm/mach-vexpress/core.h
@@ -0,0 +1,26 @@
+#define __MMIO_P2V(x)	(((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000)
+#define MMIO_P2V(x)	((void __iomem *)__MMIO_P2V(x))
+
+#define AMBA_DEVICE(name,busid,base,plat)	\
+struct amba_device name##_device = {		\
+	.dev		= {			\
+		.coherent_dma_mask = ~0UL,	\
+		.init_name = busid,		\
+		.platform_data = plat,		\
+	},					\
+	.res		= {			\
+		.start	= base,			\
+		.end	= base + SZ_4K - 1,	\
+		.flags	= IORESOURCE_MEM,	\
+	},					\
+	.dma_mask	= ~0UL,			\
+	.irq		= IRQ_##base,		\
+	/* .dma		= DMA_##base,*/		\
+}
+
+struct map_desc;
+
+void v2m_map_io(struct map_desc *tile, size_t num);
+extern struct sys_timer v2m_timer;
+
+extern void __iomem *gic_cpu_base_addr;
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
new file mode 100644
index 0000000..e6f7303
--- /dev/null
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -0,0 +1,249 @@
+/*
+ * Versatile Express Core Tile Cortex A9x4 Support
+ */
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <asm/clkdev.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/pmu.h>
+
+#include <mach/clkdev.h>
+#include <mach/ct-ca9x4.h>
+
+#include <plat/timer-sp.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include "core.h"
+
+#include <mach/motherboard.h>
+
+#define V2M_PA_CS7	0x10000000
+
+static struct map_desc ct_ca9x4_io_desc[] __initdata = {
+	{
+		.virtual	= __MMIO_P2V(CT_CA9X4_MPIC),
+		.pfn		= __phys_to_pfn(CT_CA9X4_MPIC),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= __MMIO_P2V(CT_CA9X4_SP804_TIMER),
+		.pfn		= __phys_to_pfn(CT_CA9X4_SP804_TIMER),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= __MMIO_P2V(CT_CA9X4_L2CC),
+		.pfn		= __phys_to_pfn(CT_CA9X4_L2CC),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+static void __init ct_ca9x4_map_io(void)
+{
+	v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
+}
+
+void __iomem *gic_cpu_base_addr;
+
+static void __init ct_ca9x4_init_irq(void)
+{
+	gic_cpu_base_addr = MMIO_P2V(A9_MPCORE_GIC_CPU);
+	gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST), 29);
+	gic_cpu_init(0, gic_cpu_base_addr);
+}
+
+#if 0
+static void ct_ca9x4_timer_init(void)
+{
+	writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL);
+	writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL);
+
+	sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1));
+	sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0);
+}
+
+static struct sys_timer ct_ca9x4_timer = {
+	.init	= ct_ca9x4_timer_init,
+};
+#endif
+
+static struct clcd_panel xvga_panel = {
+	.mode		= {
+		.name		= "XVGA",
+		.refresh	= 60,
+		.xres		= 1024,
+		.yres		= 768,
+		.pixclock	= 15384,
+		.left_margin	= 168,
+		.right_margin	= 8,
+		.upper_margin	= 29,
+		.lower_margin	= 3,
+		.hsync_len	= 144,
+		.vsync_len	= 6,
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+	.width		= -1,
+	.height		= -1,
+	.tim2		= TIM2_BCD | TIM2_IPC,
+	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+	.bpp		= 16,
+};
+
+static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
+{
+	v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
+	v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2);
+}
+
+static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
+{
+	unsigned long framesize = 1024 * 768 * 2;
+	dma_addr_t dma;
+
+	fb->panel = &xvga_panel;
+
+	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
+				&dma, GFP_KERNEL);
+	if (!fb->fb.screen_base) {
+		printk(KERN_ERR "CLCD: unable to map frame buffer\n");
+		return -ENOMEM;
+	}
+	fb->fb.fix.smem_start = dma;
+	fb->fb.fix.smem_len = framesize;
+
+	return 0;
+}
+
+static int ct_ca9x4_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
+		fb->fb.fix.smem_start, fb->fb.fix.smem_len);
+}
+
+static void ct_ca9x4_clcd_remove(struct clcd_fb *fb)
+{
+	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+		fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board ct_ca9x4_clcd_data = {
+	.name		= "CT-CA9X4",
+	.check		= clcdfb_check,
+	.decode		= clcdfb_decode,
+	.enable		= ct_ca9x4_clcd_enable,
+	.setup		= ct_ca9x4_clcd_setup,
+	.mmap		= ct_ca9x4_clcd_mmap,
+	.remove		= ct_ca9x4_clcd_remove,
+};
+
+static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
+static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL);
+static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL);
+static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL);
+
+static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
+	&clcd_device,
+	&dmc_device,
+	&smc_device,
+	&gpio_device,
+};
+
+
+static long ct_round(struct clk *clk, unsigned long rate)
+{
+	return rate;
+}
+
+static int ct_set(struct clk *clk, unsigned long rate)
+{
+	return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate);
+}
+
+static const struct clk_ops osc1_clk_ops = {
+	.round	= ct_round,
+	.set	= ct_set,
+};
+
+static struct clk osc1_clk = {
+	.ops	= &osc1_clk_ops,
+	.rate	= 24000000,
+};
+
+static struct clk_lookup lookups[] = {
+	{	/* CLCD */
+		.dev_id		= "ct:clcd",
+		.clk		= &osc1_clk,
+	},
+};
+
+static struct resource pmu_resources[] = {
+	[0] = {
+		.start	= IRQ_CT_CA9X4_PMU_CPU0,
+		.end	= IRQ_CT_CA9X4_PMU_CPU0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[1] = {
+		.start	= IRQ_CT_CA9X4_PMU_CPU1,
+		.end	= IRQ_CT_CA9X4_PMU_CPU1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_CT_CA9X4_PMU_CPU2,
+		.end	= IRQ_CT_CA9X4_PMU_CPU2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= IRQ_CT_CA9X4_PMU_CPU3,
+		.end	= IRQ_CT_CA9X4_PMU_CPU3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device pmu_device = {
+	.name		= "arm-pmu",
+	.id		= ARM_PMU_DEVICE_CPU,
+	.num_resources	= ARRAY_SIZE(pmu_resources),
+	.resource	= pmu_resources,
+};
+
+static void ct_ca9x4_init(void)
+{
+	int i;
+
+#ifdef CONFIG_CACHE_L2X0
+	l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff);
+#endif
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
+		amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
+
+	platform_device_register(&pmu_device);
+}
+
+MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
+	.phys_io	= V2M_UART0,
+	.io_pg_offst	= (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc,
+	.boot_params	= PHYS_OFFSET + 0x00000100,
+	.map_io		= ct_ca9x4_map_io,
+	.init_irq	= ct_ca9x4_init_irq,
+#if 0
+	.timer		= &ct_ca9x4_timer,
+#else
+	.timer		= &v2m_timer,
+#endif
+	.init_machine	= ct_ca9x4_init,
+MACHINE_END
diff --git a/arch/arm/mach-vexpress/headsmp.S b/arch/arm/mach-vexpress/headsmp.S
new file mode 100644
index 0000000..8a78ff6
--- /dev/null
+++ b/arch/arm/mach-vexpress/headsmp.S
@@ -0,0 +1,39 @@
+/*
+ *  linux/arch/arm/mach-vexpress/headsmp.S
+ *
+ *  Copyright (c) 2003 ARM Limited
+ *  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/linkage.h>
+#include <linux/init.h>
+
+	__INIT
+
+/*
+ * Versatile Express 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(vexpress_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
+
+	/*
+	 * we've been released from the holding pen: secondary_stack
+	 * should now contain the SVC stack for this core
+	 */
+	b	secondary_startup
+
+1:	.long	.
+	.long	pen_release
diff --git a/arch/arm/mach-vexpress/include/mach/clkdev.h b/arch/arm/mach-vexpress/include/mach/clkdev.h
new file mode 100644
index 0000000..3f8307d
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/clkdev.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#include <plat/clock.h>
+
+struct clk {
+	const struct clk_ops	*ops;
+	unsigned long		rate;
+	const struct icst_params *params;
+};
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
new file mode 100644
index 0000000..8650f04
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
@@ -0,0 +1,47 @@
+#ifndef __MACH_CT_CA9X4_H
+#define __MACH_CT_CA9X4_H
+
+/*
+ * Physical base addresses
+ */
+#define CT_CA9X4_CLCDC		(0x10020000)
+#define CT_CA9X4_AXIRAM		(0x10060000)
+#define CT_CA9X4_DMC		(0x100e0000)
+#define CT_CA9X4_SMC		(0x100e1000)
+#define CT_CA9X4_SCC		(0x100e2000)
+#define CT_CA9X4_SP804_TIMER	(0x100e4000)
+#define CT_CA9X4_SP805_WDT	(0x100e5000)
+#define CT_CA9X4_TZPC		(0x100e6000)
+#define CT_CA9X4_GPIO		(0x100e8000)
+#define CT_CA9X4_FASTAXI	(0x100e9000)
+#define CT_CA9X4_SLOWAXI	(0x100ea000)
+#define CT_CA9X4_TZASC		(0x100ec000)
+#define CT_CA9X4_CORESIGHT	(0x10200000)
+#define CT_CA9X4_MPIC		(0x1e000000)
+#define CT_CA9X4_SYSTIMER	(0x1e004000)
+#define CT_CA9X4_SYSWDT		(0x1e007000)
+#define CT_CA9X4_L2CC		(0x1e00a000)
+
+#define CT_CA9X4_TIMER0		(CT_CA9X4_SP804_TIMER + 0x000)
+#define CT_CA9X4_TIMER1		(CT_CA9X4_SP804_TIMER + 0x020)
+
+#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_GIC_DIST	(CT_CA9X4_MPIC + 0x1000)
+
+/*
+ * Interrupts.  Those in {} are for AMBA devices
+ */
+#define IRQ_CT_CA9X4_CLCDC	{ 76 }
+#define IRQ_CT_CA9X4_DMC	{ -1 }
+#define IRQ_CT_CA9X4_SMC	{ 77, 78 }
+#define IRQ_CT_CA9X4_TIMER0	80
+#define IRQ_CT_CA9X4_TIMER1	81
+#define IRQ_CT_CA9X4_GPIO	{ 82 }
+#define IRQ_CT_CA9X4_PMU_CPU0	92
+#define IRQ_CT_CA9X4_PMU_CPU1	93
+#define IRQ_CT_CA9X4_PMU_CPU2	94
+#define IRQ_CT_CA9X4_PMU_CPU3	95
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S
new file mode 100644
index 0000000..5167e2a
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S
@@ -0,0 +1,23 @@
+/* arch/arm/mach-realview/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.
+ */
+
+#define DEBUG_LL_UART_OFFSET	0x00009000
+
+		.macro	addruart,rx,tmp
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx,      #0x10000000
+		movne	\rx,      #0xf8000000	@ virtual base
+		orr	\rx, \rx, #DEBUG_LL_UART_OFFSET
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-vexpress/include/mach/entry-macro.S b/arch/arm/mach-vexpress/include/mach/entry-macro.S
new file mode 100644
index 0000000..20e9fb5
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/entry-macro.S
@@ -0,0 +1,67 @@
+#include <asm/hardware/gic.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_preamble, base, tmp
+	ldr	\base, =gic_cpu_base_addr
+	ldr	\base, [\base]
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	/*
+	 * The interrupt numbering scheme is defined in the
+	 * interrupt controller spec.  To wit:
+	 *
+	 * Interrupts 0-15 are IPI
+	 * 16-28 are reserved
+	 * 29-31 are local.  We allow 30 to be used for the watchdog.
+	 * 32-1020 are global
+	 * 1021-1022 are reserved
+	 * 1023 is "spurious" (no interrupt)
+	 *
+	 * For now, we ignore all local interrupts so only return an interrupt if it's
+	 * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
+	 *
+	 * A simple read from the controller will tell us the number of the highest
+	 * priority enabled interrupt.  We then just need to check whether it is in the
+	 * valid range for an IRQ (30-1020 inclusive).
+	 */
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
+	ldr	\tmp, =1021
+	bic     \irqnr, \irqstat, #0x1c00
+	cmp     \irqnr, #29
+	cmpcc	\irqnr, \irqnr
+	cmpne	\irqnr, \tmp
+	cmpcs	\irqnr, \irqnr
+	.endm
+
+	/* We assume that irqstat (the raw value of the IRQ acknowledge
+	 * register) is preserved from the macro above.
+	 * If there is an IPI, we immediately signal end of interrupt on the
+	 * controller, since this requires the original irqstat value which
+	 * we won't easily be able to recreate later.
+	 */
+
+	.macro test_for_ipi, irqnr, irqstat, base, tmp
+	bic	\irqnr, \irqstat, #0x1c00
+	cmp	\irqnr, #16
+	strcc	\irqstat, [\base, #GIC_CPU_EOI]
+	cmpcs	\irqnr, \irqnr
+	.endm
+
+	/* As above, this assumes that irqstat and base are preserved.. */
+
+	.macro test_for_ltirq, irqnr, irqstat, base, tmp
+	bic	\irqnr, \irqstat, #0x1c00
+	mov 	\tmp, #0
+	cmp	\irqnr, #29
+	moveq	\tmp, #1
+	streq	\irqstat, [\base, #GIC_CPU_EOI]
+	cmp	\tmp, #0
+	.endm
+
diff --git a/arch/arm/mach-vexpress/include/mach/hardware.h b/arch/arm/mach-vexpress/include/mach/hardware.h
new file mode 100644
index 0000000..40a8c178
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/hardware.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h
new file mode 100644
index 0000000..748bb52
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/io.h
@@ -0,0 +1,28 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/io.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/irqs.h b/arch/arm/mach-vexpress/include/mach/irqs.h
new file mode 100644
index 0000000..7054cbf
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/irqs.h
@@ -0,0 +1,4 @@
+#define IRQ_LOCALTIMER		29
+#define IRQ_LOCALWDOG		30
+
+#define NR_IRQS	128
diff --git a/arch/arm/mach-vexpress/include/mach/memory.h b/arch/arm/mach-vexpress/include/mach/memory.h
new file mode 100644
index 0000000..be28232
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/memory.h
@@ -0,0 +1,25 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/memory.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET		UL(0x60000000)
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
new file mode 100644
index 0000000..98a8ded
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -0,0 +1,121 @@
+#ifndef __MACH_MOTHERBOARD_H
+#define __MACH_MOTHERBOARD_H
+
+/*
+ * Physical addresses, offset from V2M_PA_CS0-3
+ */
+#define V2M_NOR0		(V2M_PA_CS0)
+#define V2M_NOR1		(V2M_PA_CS1)
+#define V2M_SRAM		(V2M_PA_CS2)
+#define V2M_VIDEO_SRAM		(V2M_PA_CS3 + 0x00000000)
+#define V2M_LAN9118		(V2M_PA_CS3 + 0x02000000)
+#define V2M_ISP1761		(V2M_PA_CS3 + 0x03000000)
+
+/*
+ * Physical addresses, offset from V2M_PA_CS7
+ */
+#define V2M_SYSREGS		(V2M_PA_CS7 + 0x00000000)
+#define V2M_SYSCTL		(V2M_PA_CS7 + 0x00001000)
+#define V2M_SERIAL_BUS_PCI	(V2M_PA_CS7 + 0x00002000)
+
+#define V2M_AACI		(V2M_PA_CS7 + 0x00004000)
+#define V2M_MMCI		(V2M_PA_CS7 + 0x00005000)
+#define V2M_KMI0		(V2M_PA_CS7 + 0x00006000)
+#define V2M_KMI1		(V2M_PA_CS7 + 0x00007000)
+
+#define V2M_UART0		(V2M_PA_CS7 + 0x00009000)
+#define V2M_UART1		(V2M_PA_CS7 + 0x0000a000)
+#define V2M_UART2		(V2M_PA_CS7 + 0x0000b000)
+#define V2M_UART3		(V2M_PA_CS7 + 0x0000c000)
+
+#define V2M_WDT			(V2M_PA_CS7 + 0x0000f000)
+
+#define V2M_TIMER01		(V2M_PA_CS7 + 0x00011000)
+#define V2M_TIMER23		(V2M_PA_CS7 + 0x00012000)
+
+#define V2M_SERIAL_BUS_DVI	(V2M_PA_CS7 + 0x00016000)
+#define V2M_RTC			(V2M_PA_CS7 + 0x00017000)
+
+#define V2M_CF			(V2M_PA_CS7 + 0x0001a000)
+#define V2M_CLCD		(V2M_PA_CS7 + 0x0001f000)
+
+#define V2M_SYS_ID		(V2M_SYSREGS + 0x000)
+#define V2M_SYS_SW		(V2M_SYSREGS + 0x004)
+#define V2M_SYS_LED		(V2M_SYSREGS + 0x008)
+#define V2M_SYS_100HZ		(V2M_SYSREGS + 0x024)
+#define V2M_SYS_FLAGS		(V2M_SYSREGS + 0x030)
+#define V2M_SYS_FLAGSSET	(V2M_SYSREGS + 0x030)
+#define V2M_SYS_FLAGSCLR	(V2M_SYSREGS + 0x034)
+#define V2M_SYS_NVFLAGS		(V2M_SYSREGS + 0x038)
+#define V2M_SYS_NVFLAGSSET	(V2M_SYSREGS + 0x038)
+#define V2M_SYS_NVFLAGSCLR	(V2M_SYSREGS + 0x03c)
+#define V2M_SYS_MCI		(V2M_SYSREGS + 0x048)
+#define V2M_SYS_FLASH		(V2M_SYSREGS + 0x03c)
+#define V2M_SYS_CFGSW		(V2M_SYSREGS + 0x058)
+#define V2M_SYS_24MHZ		(V2M_SYSREGS + 0x05c)
+#define V2M_SYS_MISC		(V2M_SYSREGS + 0x060)
+#define V2M_SYS_DMA		(V2M_SYSREGS + 0x064)
+#define V2M_SYS_PROCID0		(V2M_SYSREGS + 0x084)
+#define V2M_SYS_PROCID1		(V2M_SYSREGS + 0x088)
+#define V2M_SYS_CFGDATA		(V2M_SYSREGS + 0x0a0)
+#define V2M_SYS_CFGCTRL		(V2M_SYSREGS + 0x0a4)
+#define V2M_SYS_CFGSTAT		(V2M_SYSREGS + 0x0a8)
+
+#define V2M_TIMER0		(V2M_TIMER01 + 0x000)
+#define V2M_TIMER1		(V2M_TIMER01 + 0x020)
+
+#define V2M_TIMER2		(V2M_TIMER23 + 0x000)
+#define V2M_TIMER3		(V2M_TIMER23 + 0x020)
+
+
+/*
+ * Interrupts.  Those in {} are for AMBA devices
+ */
+#define IRQ_V2M_WDT		{ (32 + 0) }
+#define IRQ_V2M_TIMER0		(32 + 2)
+#define IRQ_V2M_TIMER1		(32 + 2)
+#define IRQ_V2M_TIMER2		(32 + 3)
+#define IRQ_V2M_TIMER3		(32 + 3)
+#define IRQ_V2M_RTC		{ (32 + 4) }
+#define IRQ_V2M_UART0		{ (32 + 5) }
+#define IRQ_V2M_UART1		{ (32 + 6) }
+#define IRQ_V2M_UART2		{ (32 + 7) }
+#define IRQ_V2M_UART3		{ (32 + 8) }
+#define IRQ_V2M_MMCI		{ (32 + 9), (32 + 10) }
+#define IRQ_V2M_AACI		{ (32 + 11) }
+#define IRQ_V2M_KMI0		{ (32 + 12) }
+#define IRQ_V2M_KMI1		{ (32 + 13) }
+#define IRQ_V2M_CLCD		{ (32 + 14) }
+#define IRQ_V2M_LAN9118		(32 + 15)
+#define IRQ_V2M_ISP1761		(32 + 16)
+#define IRQ_V2M_PCIE		(32 + 17)
+
+
+/*
+ * Configuration
+ */
+#define SYS_CFG_START		(1 << 31)
+#define SYS_CFG_WRITE		(1 << 30)
+#define SYS_CFG_OSC		(1 << 20)
+#define SYS_CFG_VOLT		(2 << 20)
+#define SYS_CFG_AMP		(3 << 20)
+#define SYS_CFG_TEMP		(4 << 20)
+#define SYS_CFG_RESET		(5 << 20)
+#define SYS_CFG_SCC		(6 << 20)
+#define SYS_CFG_MUXFPGA		(7 << 20)
+#define SYS_CFG_SHUTDOWN	(8 << 20)
+#define SYS_CFG_REBOOT		(9 << 20)
+#define SYS_CFG_DVIMODE		(11 << 20)
+#define SYS_CFG_POWER		(12 << 20)
+#define SYS_CFG_SITE_MB		(0 << 16)
+#define SYS_CFG_SITE_DB1	(1 << 16)
+#define SYS_CFG_SITE_DB2	(2 << 16)
+#define SYS_CFG_STACK(n)	((n) << 12)
+
+#define SYS_CFG_ERR		(1 << 1)
+#define SYS_CFG_COMPLETE	(1 << 0)
+
+int v2m_cfg_write(u32 devfn, u32 data);
+int v2m_cfg_read(u32 devfn, u32 *data);
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h
new file mode 100644
index 0000000..72a9621
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/smp.h
@@ -0,0 +1,21 @@
+#ifndef __MACH_SMP_H
+#define __MACH_SMP_H
+
+#include <asm/hardware/gic.h>
+
+#define hard_smp_processor_id()				\
+	({						\
+		unsigned int cpunum;			\
+		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
+			: "=r" (cpunum));		\
+		cpunum &= 0x0F;				\
+	})
+
+/*
+ * We use IRQ1 as the IPI
+ */
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+	gic_raise_softirq(mask, 1);
+}
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/system.h b/arch/arm/mach-vexpress/include/mach/system.h
new file mode 100644
index 0000000..899a4e6
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/system.h
@@ -0,0 +1,37 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/system.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/timex.h b/arch/arm/mach-vexpress/include/mach/timex.h
new file mode 100644
index 0000000..00029ba
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/timex.h
@@ -0,0 +1,23 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/timex.h
+ *
+ *  RealView architecture timex specifications
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+
+#define CLOCK_TICK_RATE		(50000000 / 16)
diff --git a/arch/arm/mach-vexpress/include/mach/uncompress.h b/arch/arm/mach-vexpress/include/mach/uncompress.h
new file mode 100644
index 0000000..7972c57
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/uncompress.h
@@ -0,0 +1,52 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/uncompress.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+#define AMBA_UART_DR(base)	(*(volatile unsigned char *)((base) + 0x00))
+#define AMBA_UART_LCRH(base)	(*(volatile unsigned char *)((base) + 0x2c))
+#define AMBA_UART_CR(base)	(*(volatile unsigned char *)((base) + 0x30))
+#define AMBA_UART_FR(base)	(*(volatile unsigned char *)((base) + 0x18))
+
+#define get_uart_base()	(0x10000000 + 0x00009000)
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+	unsigned long base = get_uart_base();
+
+	while (AMBA_UART_FR(base) & (1 << 5))
+		barrier();
+
+	AMBA_UART_DR(base) = c;
+}
+
+static inline void flush(void)
+{
+	unsigned long base = get_uart_base();
+
+	while (AMBA_UART_FR(base) & (1 << 3))
+		barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-vexpress/include/mach/vmalloc.h b/arch/arm/mach-vexpress/include/mach/vmalloc.h
new file mode 100644
index 0000000..f43a36e
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/vmalloc.h
@@ -0,0 +1,21 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/vmalloc.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *  Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+#define VMALLOC_END		0xf8000000UL
diff --git a/arch/arm/mach-vexpress/localtimer.c b/arch/arm/mach-vexpress/localtimer.c
new file mode 100644
index 0000000..c0e3a59
--- /dev/null
+++ b/arch/arm/mach-vexpress/localtimer.c
@@ -0,0 +1,26 @@
+/*
+ *  linux/arch/arm/mach-vexpress/localtimer.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  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/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+
+#include <asm/smp_twd.h>
+#include <asm/localtimer.h>
+#include <mach/irqs.h>
+
+/*
+ * Setup the local clock events for a CPU.
+ */
+void __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+	evt->irq = IRQ_LOCALTIMER;
+	twd_timer_setup(evt);
+}
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
new file mode 100644
index 0000000..6709706
--- /dev/null
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -0,0 +1,190 @@
+/*
+ *  linux/arch/arm/mach-vexpress/platsmp.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  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/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/localtimer.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
+
+#include <mach/ct-ca9x4.h>
+#include <mach/motherboard.h>
+#define V2M_PA_CS7 0x10000000
+
+#include "core.h"
+
+extern void vexpress_secondary_startup(void);
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+
+static void __iomem *scu_base_addr(void)
+{
+	return MMIO_P2V(A9_MPCORE_SCU);
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+	trace_hardirqs_off();
+
+	/*
+	 * 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_cpu_init(0, gic_cpu_base_addr);
+
+	/*
+	 * 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);
+}
+
+int __cpuinit 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);
+
+	/*
+	 * This is really belt and braces; we hold unintended secondary
+	 * CPUs in the holding pen until we're ready for them.  However,
+	 * since we haven't sent them a soft interrupt, they shouldn't
+	 * be there.
+	 */
+	pen_release = cpu;
+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+
+	/*
+	 * Send the secondary CPU a soft interrupt, thereby causing
+	 * the boot monitor to read the system wide flags register,
+	 * and branch to the address found there.
+	 */
+	smp_cross_call(cpumask_of(cpu));
+
+	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.
+ */
+void __init smp_init_cpus(void)
+{
+	void __iomem *scu_base = scu_base_addr();
+	unsigned int i, ncores;
+
+	ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+
+	/* sanity check */
+	if (ncores == 0) {
+		printk(KERN_ERR
+		       "vexpress: strange CM count of 0? Default to 1\n");
+
+		ncores = 1;
+	}
+
+	if (ncores > NR_CPUS) {
+		printk(KERN_WARNING
+		       "vexpress: no. of cores (%d) greater than configured "
+		       "maximum of %d - clipping\n",
+		       ncores, NR_CPUS);
+		ncores = NR_CPUS;
+	}
+
+	for (i = 0; i < ncores; i++)
+		set_cpu_possible(i, true);
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+	unsigned int ncores = num_possible_cpus();
+	unsigned int cpu = smp_processor_id();
+	int i;
+
+	smp_store_cpu_info(cpu);
+
+	/*
+	 * are we trying to boot more cores than exist?
+	 */
+	if (max_cpus > ncores)
+		max_cpus = ncores;
+
+	/*
+	 * Initialise the present map, which describes the set of CPUs
+	 * actually populated at the present time.
+	 */
+	for (i = 0; i < max_cpus; i++)
+		set_cpu_present(i, true);
+
+	/*
+	 * Initialise the SCU if there are more than one CPU and let
+	 * them know where to start.
+	 */
+	if (max_cpus > 1) {
+		/*
+		 * Enable the local timer or broadcast device for the
+		 * boot CPU, but only if we have more than one CPU.
+		 */
+		percpu_timer_setup();
+
+		scu_enable(scu_base_addr());
+
+		/*
+		 * Write the address of secondary startup into the
+		 * system-wide flags register. The boot monitor waits
+		 * until it receives a soft interrupt, and then the
+		 * secondary CPU branches to this address.
+		 */
+		writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
+		writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
+			MMIO_P2V(V2M_SYS_FLAGSSET));
+	}
+}
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
new file mode 100644
index 0000000..d250711
--- /dev/null
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -0,0 +1,361 @@
+/*
+ * Versatile Express V2M Motherboard Support
+ */
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/mmci.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/spinlock.h>
+#include <linux/sysdev.h>
+#include <linux/usb/isp1760.h>
+
+#include <asm/clkdev.h>
+#include <asm/sizes.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/arm_timer.h>
+
+#include <mach/clkdev.h>
+#include <mach/motherboard.h>
+
+#include <plat/timer-sp.h>
+
+#include "core.h"
+
+#define V2M_PA_CS0	0x40000000
+#define V2M_PA_CS1	0x44000000
+#define V2M_PA_CS2	0x48000000
+#define V2M_PA_CS3	0x4c000000
+#define V2M_PA_CS7	0x10000000
+
+static struct map_desc v2m_io_desc[] __initdata = {
+	{
+		.virtual	= __MMIO_P2V(V2M_PA_CS7),
+		.pfn		= __phys_to_pfn(V2M_PA_CS7),
+		.length		= SZ_128K,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init v2m_map_io(struct map_desc *tile, size_t num)
+{
+	iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
+	iotable_init(tile, num);
+}
+
+
+static void v2m_timer_init(void)
+{
+	writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
+	writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
+
+	sp804_clocksource_init(MMIO_P2V(V2M_TIMER1));
+	sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0);
+}
+
+struct sys_timer v2m_timer = {
+	.init	= v2m_timer_init,
+};
+
+
+static DEFINE_SPINLOCK(v2m_cfg_lock);
+
+int v2m_cfg_write(u32 devfn, u32 data)
+{
+	/* Configuration interface broken? */
+	u32 val;
+
+	printk("%s: writing %08x to %08x\n", __func__, data, devfn);
+
+	devfn |= SYS_CFG_START | SYS_CFG_WRITE;
+
+	spin_lock(&v2m_cfg_lock);
+	val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+	writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT));
+
+	writel(data, MMIO_P2V(V2M_SYS_CFGDATA));
+	writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
+
+	do {
+		val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+	} while (val == 0);
+	spin_unlock(&v2m_cfg_lock);
+
+	return !!(val & SYS_CFG_ERR);
+}
+
+int v2m_cfg_read(u32 devfn, u32 *data)
+{
+	u32 val;
+
+	devfn |= SYS_CFG_START;
+
+	spin_lock(&v2m_cfg_lock);
+	writel(0, MMIO_P2V(V2M_SYS_CFGSTAT));
+	writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
+
+	mb();
+
+	do {
+		cpu_relax();
+		val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+	} while (val == 0);
+
+	*data = readl(MMIO_P2V(V2M_SYS_CFGDATA));
+	spin_unlock(&v2m_cfg_lock);
+
+	return !!(val & SYS_CFG_ERR);
+}
+
+
+static struct resource v2m_pcie_i2c_resource = {
+	.start	= V2M_SERIAL_BUS_PCI,
+	.end	= V2M_SERIAL_BUS_PCI + SZ_4K - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device v2m_pcie_i2c_device = {
+	.name		= "versatile-i2c",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= &v2m_pcie_i2c_resource,
+};
+
+static struct resource v2m_ddc_i2c_resource = {
+	.start	= V2M_SERIAL_BUS_DVI,
+	.end	= V2M_SERIAL_BUS_DVI + SZ_4K - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device v2m_ddc_i2c_device = {
+	.name		= "versatile-i2c",
+	.id		= 1,
+	.num_resources	= 1,
+	.resource	= &v2m_ddc_i2c_resource,
+};
+
+static struct resource v2m_eth_resources[] = {
+	{
+		.start	= V2M_LAN9118,
+		.end	= V2M_LAN9118 + SZ_64K - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_V2M_LAN9118,
+		.end	= IRQ_V2M_LAN9118,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct smsc911x_platform_config v2m_eth_config = {
+	.flags		= SMSC911X_USE_32BIT,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device v2m_eth_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.resource	= v2m_eth_resources,
+	.num_resources	= ARRAY_SIZE(v2m_eth_resources),
+	.dev.platform_data = &v2m_eth_config,
+};
+
+static struct resource v2m_usb_resources[] = {
+	{
+		.start	= V2M_ISP1761,
+		.end	= V2M_ISP1761 + SZ_128K - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_V2M_ISP1761,
+		.end	= IRQ_V2M_ISP1761,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct isp1760_platform_data v2m_usb_config = {
+	.is_isp1761		= true,
+	.bus_width_16		= false,
+	.port1_otg		= true,
+	.analog_oc		= false,
+	.dack_polarity_high	= false,
+	.dreq_polarity_high	= false,
+};
+
+static struct platform_device v2m_usb_device = {
+	.name		= "isp1760",
+	.id		= -1,
+	.resource	= v2m_usb_resources,
+	.num_resources	= ARRAY_SIZE(v2m_usb_resources),
+	.dev.platform_data = &v2m_usb_config,
+};
+
+static int v2m_flash_init(void)
+{
+	writel(0, MMIO_P2V(V2M_SYS_FLASH));
+	return 0;
+}
+
+static void v2m_flash_exit(void)
+{
+	writel(0, MMIO_P2V(V2M_SYS_FLASH));
+}
+
+static void v2m_flash_set_vpp(int on)
+{
+	writel(on != 0, MMIO_P2V(V2M_SYS_FLASH));
+}
+
+static struct flash_platform_data v2m_flash_data = {
+	.map_name	= "cfi_probe",
+	.width		= 4,
+	.init		= v2m_flash_init,
+	.exit		= v2m_flash_exit,
+	.set_vpp	= v2m_flash_set_vpp,
+};
+
+static struct resource v2m_flash_resources[] = {
+	{
+		.start	= V2M_NOR0,
+		.end	= V2M_NOR0 + SZ_64M - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= V2M_NOR1,
+		.end	= V2M_NOR1 + SZ_64M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device v2m_flash_device = {
+	.name		= "armflash",
+	.id		= -1,
+	.resource	= v2m_flash_resources,
+	.num_resources	= ARRAY_SIZE(v2m_flash_resources),
+	.dev.platform_data = &v2m_flash_data,
+};
+
+
+static unsigned int v2m_mmci_status(struct device *dev)
+{
+	return !(readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0));
+}
+
+static struct mmci_platform_data v2m_mmci_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.status		= v2m_mmci_status,
+};
+
+static AMBA_DEVICE(aaci,  "mb:aaci",  V2M_AACI, NULL);
+static AMBA_DEVICE(mmci,  "mb:mmci",  V2M_MMCI, &v2m_mmci_data);
+static AMBA_DEVICE(kmi0,  "mb:kmi0",  V2M_KMI0, NULL);
+static AMBA_DEVICE(kmi1,  "mb:kmi1",  V2M_KMI1, NULL);
+static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL);
+static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL);
+static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL);
+static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL);
+static AMBA_DEVICE(wdt,   "mb:wdt",   V2M_WDT, NULL);
+static AMBA_DEVICE(rtc,   "mb:rtc",   V2M_RTC, NULL);
+
+static struct amba_device *v2m_amba_devs[] __initdata = {
+	&aaci_device,
+	&mmci_device,
+	&kmi0_device,
+	&kmi1_device,
+	&uart0_device,
+	&uart1_device,
+	&uart2_device,
+	&uart3_device,
+	&wdt_device,
+	&rtc_device,
+};
+
+
+static long v2m_osc_round(struct clk *clk, unsigned long rate)
+{
+	return rate;
+}
+
+static int v2m_osc1_set(struct clk *clk, unsigned long rate)
+{
+	return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate);
+}
+
+static const struct clk_ops osc1_clk_ops = {
+	.round	= v2m_osc_round,
+	.set	= v2m_osc1_set,
+};
+
+static struct clk osc1_clk = {
+	.ops	= &osc1_clk_ops,
+	.rate	= 24000000,
+};
+
+static struct clk osc2_clk = {
+	.rate	= 24000000,
+};
+
+static struct clk_lookup v2m_lookups[] = {
+	{	/* UART0 */
+		.dev_id		= "mb:uart0",
+		.clk		= &osc2_clk,
+	}, {	/* UART1 */
+		.dev_id		= "mb:uart1",
+		.clk		= &osc2_clk,
+	}, {	/* UART2 */
+		.dev_id		= "mb:uart2",
+		.clk		= &osc2_clk,
+	}, {	/* UART3 */
+		.dev_id		= "mb:uart3",
+		.clk		= &osc2_clk,
+	}, {	/* KMI0 */
+		.dev_id		= "mb:kmi0",
+		.clk		= &osc2_clk,
+	}, {	/* KMI1 */
+		.dev_id		= "mb:kmi1",
+		.clk		= &osc2_clk,
+	}, {	/* MMC0 */
+		.dev_id		= "mb:mmci",
+		.clk		= &osc2_clk,
+	}, {	/* CLCD */
+		.dev_id		= "mb:clcd",
+		.clk		= &osc1_clk,
+	},
+};
+
+static void v2m_power_off(void)
+{
+	if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0))
+		printk(KERN_EMERG "Unable to shutdown\n");
+}
+
+static void v2m_restart(char str, const char *cmd)
+{
+	if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
+		printk(KERN_EMERG "Unable to reboot\n");
+}
+
+static int __init v2m_init(void)
+{
+	int i;
+
+	clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
+
+	platform_device_register(&v2m_pcie_i2c_device);
+	platform_device_register(&v2m_ddc_i2c_device);
+	platform_device_register(&v2m_flash_device);
+	platform_device_register(&v2m_eth_device);
+	platform_device_register(&v2m_usb_device);
+
+	for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
+		amba_device_register(v2m_amba_devs[i], &iomem_resource);
+
+	pm_power_off = v2m_power_off;
+	arm_pm_restart = v2m_restart;
+
+	return 0;
+}
+arch_initcall(v2m_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 5bd7c89..346ae14 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -572,6 +572,8 @@
 config CPU_TLB_V7
 	bool
 
+config VERIFY_PERMISSION_FAULT
+	bool
 endif
 
 config CPU_HAS_ASID
@@ -760,7 +762,8 @@
 config CACHE_L2X0
 	bool "Enable the L2x0 outer cache controller"
 	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
-		   REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4
+		   REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \
+		   ARCH_NOMADIK || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
 	default y
 	select OUTER_CACHE
 	select OUTER_CACHE_SYNC
@@ -769,7 +772,7 @@
 
 config CACHE_TAUROS2
 	bool "Enable the Tauros2 L2 cache controller"
-	depends on ARCH_DOVE
+	depends on (ARCH_DOVE || ARCH_MMP)
 	default y
 	select OUTER_CACHE
 	help
@@ -789,6 +792,25 @@
 	default 6 if ARM_L1_CACHE_SHIFT_6
 	default 5
 
+config ARM_DMA_MEM_BUFFERABLE
+	bool "Use non-cacheable memory for DMA" if CPU_V6 && !CPU_V7
+	default y if CPU_V6 || CPU_V7
+	help
+	  Historically, the kernel has used strongly ordered mappings to
+	  provide DMA coherent memory.  With the advent of ARMv7, mapping
+	  memory with differing types results in unpredictable behaviour,
+	  so on these CPUs, this option is forced on.
+
+	  Multiple mappings with differing attributes is also unpredictable
+	  on ARMv6 CPUs, but since they do not have aggressive speculative
+	  prefetch, no harm appears to occur.
+
+	  However, drivers may be missing the necessary barriers for ARMv6,
+	  and therefore turning this on may result in unpredictable driver
+	  behaviour.  Therefore, we offer this as an option.
+
+	  You are recommended say 'Y' here and debug any affected drivers.
+
 config ARCH_HAS_BARRIERS
 	bool
 	help
diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S
index 2e6dc04..ec88b15 100644
--- a/arch/arm/mm/abort-ev7.S
+++ b/arch/arm/mm/abort-ev7.S
@@ -29,5 +29,26 @@
 	 * V6 code adjusts the returned DFSR.
 	 * New designs should not need to patch up faults.
 	 */
+
+#if defined(CONFIG_VERIFY_PERMISSION_FAULT)
+	/*
+	 * Detect erroneous permission failures and fix
+	 */
+	ldr	r3, =0x40d			@ On permission fault
+	and	r3, r1, r3
+	cmp	r3, #0x0d
+	movne	pc, lr
+
+	mcr	p15, 0, r0, c7, c8, 0   	@ Retranslate FAR
+	isb
+	mrc	p15, 0, r2, c7, c4, 0   	@ Read the PAR
+	and	r3, r2, #0x7b   		@ On translation fault
+	cmp	r3, #0x0b
+	movne	pc, lr
+	bic	r1, r1, #0xf			@ Fix up FSR FS[5:0]
+	and	r2, r2, #0x7e
+	orr	r1, r1, r2, LSR #1
+#endif
+
 	mov	pc, lr
 ENDPROC(v7_early_abort)
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index a2ab51f..6f98c35 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/uaccess.h>
@@ -94,36 +95,29 @@
 	"signal+warn"
 };
 
-static int
-proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
-		    void *data)
+static int alignment_proc_show(struct seq_file *m, void *v)
 {
-	char *p = page;
-	int len;
-
-	p += sprintf(p, "User:\t\t%lu\n", ai_user);
-	p += sprintf(p, "System:\t\t%lu\n", ai_sys);
-	p += sprintf(p, "Skipped:\t%lu\n", ai_skipped);
-	p += sprintf(p, "Half:\t\t%lu\n", ai_half);
-	p += sprintf(p, "Word:\t\t%lu\n", ai_word);
+	seq_printf(m, "User:\t\t%lu\n", ai_user);
+	seq_printf(m, "System:\t\t%lu\n", ai_sys);
+	seq_printf(m, "Skipped:\t%lu\n", ai_skipped);
+	seq_printf(m, "Half:\t\t%lu\n", ai_half);
+	seq_printf(m, "Word:\t\t%lu\n", ai_word);
 	if (cpu_architecture() >= CPU_ARCH_ARMv5TE)
-		p += sprintf(p, "DWord:\t\t%lu\n", ai_dword);
-	p += sprintf(p, "Multi:\t\t%lu\n", ai_multi);
-	p += sprintf(p, "User faults:\t%i (%s)\n", ai_usermode,
+		seq_printf(m, "DWord:\t\t%lu\n", ai_dword);
+	seq_printf(m, "Multi:\t\t%lu\n", ai_multi);
+	seq_printf(m, "User faults:\t%i (%s)\n", ai_usermode,
 			usermode_action[ai_usermode]);
 
-	len = (p - page) - off;
-	if (len < 0)
-		len = 0;
-
-	*eof = (len <= count) ? 1 : 0;
-	*start = page + off;
-
-	return len;
+	return 0;
 }
 
-static int proc_alignment_write(struct file *file, const char __user *buffer,
-				unsigned long count, void *data)
+static int alignment_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, alignment_proc_show, NULL);
+}
+
+static ssize_t alignment_proc_write(struct file *file, const char __user *buffer,
+				    size_t count, loff_t *pos)
 {
 	char mode;
 
@@ -136,6 +130,13 @@
 	return count;
 }
 
+static const struct file_operations alignment_proc_fops = {
+	.open		= alignment_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= alignment_proc_write,
+};
 #endif /* CONFIG_PROC_FS */
 
 union offset_union {
@@ -901,12 +902,10 @@
 #ifdef CONFIG_PROC_FS
 	struct proc_dir_entry *res;
 
-	res = create_proc_entry("cpu/alignment", S_IWUSR | S_IRUGO, NULL);
+	res = proc_create("cpu/alignment", S_IWUSR | S_IRUGO, NULL,
+			  &alignment_proc_fops);
 	if (!res)
 		return -ENOMEM;
-
-	res->read_proc = proc_alignment_read;
-	res->write_proc = proc_alignment_write;
 #endif
 
 	/*
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 21ad68b..9819869 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -27,6 +27,7 @@
 
 static void __iomem *l2x0_base;
 static DEFINE_SPINLOCK(l2x0_lock);
+static uint32_t l2x0_way_mask;	/* Bitmask of active ways */
 
 static inline void cache_wait(void __iomem *reg, unsigned long mask)
 {
@@ -108,8 +109,8 @@
 
 	/* invalidate all ways */
 	spin_lock_irqsave(&l2x0_lock, flags);
-	writel(0xff, l2x0_base + L2X0_INV_WAY);
-	cache_wait(l2x0_base + L2X0_INV_WAY, 0xff);
+	writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
+	cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
 	cache_sync();
 	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
@@ -208,9 +209,37 @@
 void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 {
 	__u32 aux;
+	__u32 cache_id;
+	int ways;
+	const char *type;
 
 	l2x0_base = base;
 
+	cache_id = readl(l2x0_base + L2X0_CACHE_ID);
+	aux = readl(l2x0_base + L2X0_AUX_CTRL);
+
+	/* Determine the number of ways */
+	switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
+	case L2X0_CACHE_ID_PART_L310:
+		if (aux & (1 << 16))
+			ways = 16;
+		else
+			ways = 8;
+		type = "L310";
+		break;
+	case L2X0_CACHE_ID_PART_L210:
+		ways = (aux >> 13) & 0xf;
+		type = "L210";
+		break;
+	default:
+		/* Assume unknown chips have 8 ways */
+		ways = 8;
+		type = "L2x0 series";
+		break;
+	}
+
+	l2x0_way_mask = (1 << ways) - 1;
+
 	/*
 	 * Check if l2x0 controller is already enabled.
 	 * If you are booting from non-secure mode
@@ -219,8 +248,6 @@
 	if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
 
 		/* l2x0 controller is disabled */
-
-		aux = readl(l2x0_base + L2X0_AUX_CTRL);
 		aux &= aux_mask;
 		aux |= aux_val;
 		writel(aux, l2x0_base + L2X0_AUX_CTRL);
@@ -236,5 +263,7 @@
 	outer_cache.flush_range = l2x0_flush_range;
 	outer_cache.sync = l2x0_cache_sync;
 
-	printk(KERN_INFO "L2X0 cache controller enabled\n");
+	printk(KERN_INFO "%s cache controller enabled\n", type);
+	printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
+			 ways, cache_id, aux);
 }
diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c
index b2a6008..d2852e1 100644
--- a/arch/arm/mm/copypage-fa.c
+++ b/arch/arm/mm/copypage-fa.c
@@ -40,7 +40,7 @@
 }
 
 void fa_copy_user_highpage(struct page *to, struct page *from,
-	unsigned long vaddr)
+	unsigned long vaddr, struct vm_area_struct *vma)
 {
 	void *kto, *kfrom;
 
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 0d414c2..9b906de 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -134,8 +134,6 @@
 	flush_dcache_mmap_unlock(mapping);
 	if (aliases)
 		do_adjust_pte(vma, addr, pfn, ptep);
-	else
-		flush_cache_page(vma, addr, pfn);
 }
 
 /*
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 9d40c34..92f5801 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -463,7 +463,12 @@
 	{ do_bad,		SIGILL,	 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,	 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"	   },
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 0ed29bf..1ba6cf5 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -15,7 +15,6 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
-#include <linux/sort.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 
@@ -224,20 +223,6 @@
 	return initrd_node;
 }
 
-static inline void map_memory_bank(struct membank *bank)
-{
-#ifdef CONFIG_MMU
-	struct map_desc map;
-
-	map.pfn = bank_pfn_start(bank);
-	map.virtual = __phys_to_virt(bank_phys_start(bank));
-	map.length = bank_phys_size(bank);
-	map.type = MT_MEMORY;
-
-	create_mapping(&map);
-#endif
-}
-
 static void __init bootmem_init_node(int node, struct meminfo *mi,
 	unsigned long start_pfn, unsigned long end_pfn)
 {
@@ -247,16 +232,6 @@
 	int i;
 
 	/*
-	 * Map the memory banks for this node.
-	 */
-	for_each_nodebank(i, mi, node) {
-		struct membank *bank = &mi->bank[i];
-
-		if (!bank->highmem)
-			map_memory_bank(bank);
-	}
-
-	/*
 	 * Allocate the bootmem bitmap page.
 	 */
 	boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
@@ -385,21 +360,12 @@
 }
 #endif
 
-static int __init meminfo_cmp(const void *_a, const void *_b)
-{
-	const struct membank *a = _a, *b = _b;
-	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
-	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
-}
-
 void __init bootmem_init(void)
 {
 	struct meminfo *mi = &meminfo;
 	unsigned long min, max_low, max_high;
 	int node, initrd_node;
 
-	sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
-
 	/*
 	 * Locate which node contains the ramdisk image, if any.
 	 */
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index a888363..815d08e 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -28,10 +28,7 @@
 
 #endif
 
-struct map_desc;
-struct meminfo;
 struct pglist_data;
 
-void __init create_mapping(struct map_desc *md);
 void __init bootmem_init(void);
 void reserve_node_zero(struct pglist_data *pgdat);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 241c24a..e7113d0 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -14,6 +14,7 @@
 #include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
+#include <linux/sort.h>
 
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
@@ -603,7 +604,7 @@
  * offsets, and we take full advantage of sections and
  * supersections.
  */
-void __init create_mapping(struct map_desc *md)
+static void __init create_mapping(struct map_desc *md)
 {
 	unsigned long phys, addr, length, end;
 	const struct mem_type *type;
@@ -1017,6 +1018,39 @@
 #endif
 }
 
+static inline void map_memory_bank(struct membank *bank)
+{
+	struct map_desc map;
+
+	map.pfn = bank_pfn_start(bank);
+	map.virtual = __phys_to_virt(bank_phys_start(bank));
+	map.length = bank_phys_size(bank);
+	map.type = MT_MEMORY;
+
+	create_mapping(&map);
+}
+
+static void __init map_lowmem(void)
+{
+	struct meminfo *mi = &meminfo;
+	int i;
+
+	/* Map all the lowmem memory banks. */
+	for (i = 0; i < mi->nr_banks; i++) {
+		struct membank *bank = &mi->bank[i];
+
+		if (!bank->highmem)
+			map_memory_bank(bank);
+	}
+}
+
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+	const struct membank *a = _a, *b = _b;
+	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
@@ -1025,9 +1059,12 @@
 {
 	void *zero_page;
 
+	sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+
 	build_mem_type_table();
 	sanity_check_meminfo();
 	prepare_page_table();
+	map_lowmem();
 	bootmem_init();
 	devicemaps_init(mdesc);
 	kmap_init();
diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c
index 4c0ab50..cb7658e 100644
--- a/arch/arm/nwfpe/fpmodule.c
+++ b/arch/arm/nwfpe/fpmodule.c
@@ -24,6 +24,7 @@
 #include "fpa11.h"
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 
 /* XXX */
 #include <linux/errno.h>
@@ -134,13 +135,17 @@
 cumulative exceptions flag byte are set and we return.
 */
 
+#ifdef CONFIG_DEBUG_USER
+/* By default, ignore inexact errors as there are far too many of them to log */
+static int debug = ~BIT_IXC;
+#endif
+
 void float_raise(signed char flags)
 {
 	register unsigned int fpsr, cumulativeTraps;
 
 #ifdef CONFIG_DEBUG_USER
- 	/* Ignore inexact errors as there are far too many of them to log */
- 	if (flags & ~BIT_IXC)
+	if (flags & debug)
  		printk(KERN_DEBUG
 		       "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
 		       current->comm, current->pid, flags,
@@ -179,3 +184,7 @@
 MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
 MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)");
 MODULE_LICENSE("GPL");
+
+#ifdef CONFIG_DEBUG_USER
+module_param(debug, int, 0644);
+#endif
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index 88e31f5..e666eaf 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -6,9 +6,4 @@
 		oprofilefs.o oprofile_stats.o \
 		timer_int.o )
 
-oprofile-y				:= $(DRIVER_OBJS) common.o backtrace.o
-oprofile-$(CONFIG_CPU_XSCALE)		+= op_model_xscale.o
-oprofile-$(CONFIG_OPROFILE_ARM11_CORE)	+= op_model_arm11_core.o
-oprofile-$(CONFIG_OPROFILE_ARMV6)	+= op_model_v6.o
-oprofile-$(CONFIG_OPROFILE_MPCORE)	+= op_model_mpcore.o
-oprofile-$(CONFIG_OPROFILE_ARMV7)	+= op_model_v7.o
+oprofile-y				:= $(DRIVER_OBJS) common.o
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
deleted file mode 100644
index d805a52..0000000
--- a/arch/arm/oprofile/backtrace.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Arm specific backtracing code for oprofile
- *
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <rpurdie@openedhand.com>
- *
- * Based on i386 oprofile backtrace code by John Levon, David Smith
- *
- * 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/oprofile.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/uaccess.h>
-#include <asm/ptrace.h>
-#include <asm/stacktrace.h>
-
-static int report_trace(struct stackframe *frame, void *d)
-{
-	unsigned int *depth = d;
-
-	if (*depth) {
-		oprofile_add_trace(frame->pc);
-		(*depth)--;
-	}
-
-	return *depth == 0;
-}
-
-/*
- * The registers we're interested in are at the end of the variable
- * length saved register structure. The fp points at the end of this
- * structure so the address of this struct is:
- * (struct frame_tail *)(xxx->fp)-1
- */
-struct frame_tail {
-	struct frame_tail *fp;
-	unsigned long sp;
-	unsigned long lr;
-} __attribute__((packed));
-
-static struct frame_tail* user_backtrace(struct frame_tail *tail)
-{
-	struct frame_tail buftail[2];
-
-	/* Also check accessibility of one struct frame_tail beyond */
-	if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
-		return NULL;
-	if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail)))
-		return NULL;
-
-	oprofile_add_trace(buftail[0].lr);
-
-	/* frame pointers should strictly progress back up the stack
-	 * (towards higher addresses) */
-	if (tail >= buftail[0].fp)
-		return NULL;
-
-	return buftail[0].fp-1;
-}
-
-void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
-{
-	struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
-
-	if (!user_mode(regs)) {
-		struct stackframe frame;
-		frame.fp = regs->ARM_fp;
-		frame.sp = regs->ARM_sp;
-		frame.lr = regs->ARM_lr;
-		frame.pc = regs->ARM_pc;
-		walk_stackframe(&frame, report_trace, &depth);
-		return;
-	}
-
-	while (depth-- && tail && !((unsigned long) tail & 3))
-		tail = user_backtrace(tail);
-}
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index 3fcd752..0691176 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -2,32 +2,184 @@
  * @file common.c
  *
  * @remark Copyright 2004 Oprofile Authors
+ * @remark Copyright 2010 ARM Ltd.
  * @remark Read the file COPYING
  *
  * @author Zwane Mwaikambo
+ * @author Will Deacon [move to perf]
  */
 
-#include <linux/init.h>
-#include <linux/oprofile.h>
+#include <linux/cpumask.h>
+#include <linux/err.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/sysdev.h>
+#include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/oprofile.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <asm/stacktrace.h>
+#include <linux/uaccess.h>
 
-#include "op_counter.h"
-#include "op_arm_model.h"
+#include <asm/perf_event.h>
+#include <asm/ptrace.h>
 
-static struct op_arm_model_spec *op_arm_model;
+#ifdef CONFIG_HW_PERF_EVENTS
+/*
+ * Per performance monitor configuration as set via oprofilefs.
+ */
+struct op_counter_config {
+	unsigned long count;
+	unsigned long enabled;
+	unsigned long event;
+	unsigned long unit_mask;
+	unsigned long kernel;
+	unsigned long user;
+	struct perf_event_attr attr;
+};
+
 static int op_arm_enabled;
 static DEFINE_MUTEX(op_arm_mutex);
 
-struct op_counter_config *counter_config;
+static struct op_counter_config *counter_config;
+static struct perf_event **perf_events[nr_cpumask_bits];
+static int perf_num_counters;
+
+/*
+ * Overflow callback for oprofile.
+ */
+static void op_overflow_handler(struct perf_event *event, int unused,
+			struct perf_sample_data *data, struct pt_regs *regs)
+{
+	int id;
+	u32 cpu = smp_processor_id();
+
+	for (id = 0; id < perf_num_counters; ++id)
+		if (perf_events[cpu][id] == event)
+			break;
+
+	if (id != perf_num_counters)
+		oprofile_add_sample(regs, id);
+	else
+		pr_warning("oprofile: ignoring spurious overflow "
+				"on cpu %u\n", cpu);
+}
+
+/*
+ * Called by op_arm_setup to create perf attributes to mirror the oprofile
+ * settings in counter_config. Attributes are created as `pinned' events and
+ * so are permanently scheduled on the PMU.
+ */
+static void op_perf_setup(void)
+{
+	int i;
+	u32 size = sizeof(struct perf_event_attr);
+	struct perf_event_attr *attr;
+
+	for (i = 0; i < perf_num_counters; ++i) {
+		attr = &counter_config[i].attr;
+		memset(attr, 0, size);
+		attr->type		= PERF_TYPE_RAW;
+		attr->size		= size;
+		attr->config		= counter_config[i].event;
+		attr->sample_period	= counter_config[i].count;
+		attr->pinned		= 1;
+	}
+}
+
+static int op_create_counter(int cpu, int event)
+{
+	int ret = 0;
+	struct perf_event *pevent;
+
+	if (!counter_config[event].enabled || (perf_events[cpu][event] != NULL))
+		return ret;
+
+	pevent = perf_event_create_kernel_counter(&counter_config[event].attr,
+						  cpu, -1,
+						  op_overflow_handler);
+
+	if (IS_ERR(pevent)) {
+		ret = PTR_ERR(pevent);
+	} else if (pevent->state != PERF_EVENT_STATE_ACTIVE) {
+		pr_warning("oprofile: failed to enable event %d "
+				"on CPU %d\n", event, cpu);
+		ret = -EBUSY;
+	} else {
+		perf_events[cpu][event] = pevent;
+	}
+
+	return ret;
+}
+
+static void op_destroy_counter(int cpu, int event)
+{
+	struct perf_event *pevent = perf_events[cpu][event];
+
+	if (pevent) {
+		perf_event_release_kernel(pevent);
+		perf_events[cpu][event] = NULL;
+	}
+}
+
+/*
+ * Called by op_arm_start to create active perf events based on the
+ * perviously configured attributes.
+ */
+static int op_perf_start(void)
+{
+	int cpu, event, ret = 0;
+
+	for_each_online_cpu(cpu) {
+		for (event = 0; event < perf_num_counters; ++event) {
+			ret = op_create_counter(cpu, event);
+			if (ret)
+				goto out;
+		}
+	}
+
+out:
+	return ret;
+}
+
+/*
+ * Called by op_arm_stop at the end of a profiling run.
+ */
+static void op_perf_stop(void)
+{
+	int cpu, event;
+
+	for_each_online_cpu(cpu)
+		for (event = 0; event < perf_num_counters; ++event)
+			op_destroy_counter(cpu, event);
+}
+
+
+static char *op_name_from_perf_id(enum arm_perf_pmu_ids id)
+{
+	switch (id) {
+	case ARM_PERF_PMU_ID_XSCALE1:
+		return "arm/xscale1";
+	case ARM_PERF_PMU_ID_XSCALE2:
+		return "arm/xscale2";
+	case ARM_PERF_PMU_ID_V6:
+		return "arm/armv6";
+	case ARM_PERF_PMU_ID_V6MP:
+		return "arm/mpcore";
+	case ARM_PERF_PMU_ID_CA8:
+		return "arm/armv7";
+	case ARM_PERF_PMU_ID_CA9:
+		return "arm/armv7-ca9";
+	default:
+		return NULL;
+	}
+}
 
 static int op_arm_create_files(struct super_block *sb, struct dentry *root)
 {
 	unsigned int i;
 
-	for (i = 0; i < op_arm_model->num_counters; i++) {
+	for (i = 0; i < perf_num_counters; i++) {
 		struct dentry *dir;
 		char buf[4];
 
@@ -46,12 +198,10 @@
 
 static int op_arm_setup(void)
 {
-	int ret;
-
 	spin_lock(&oprofilefs_lock);
-	ret = op_arm_model->setup_ctrs();
+	op_perf_setup();
 	spin_unlock(&oprofilefs_lock);
-	return ret;
+	return 0;
 }
 
 static int op_arm_start(void)
@@ -60,8 +210,9 @@
 
 	mutex_lock(&op_arm_mutex);
 	if (!op_arm_enabled) {
-		ret = op_arm_model->start();
-		op_arm_enabled = !ret;
+		ret = 0;
+		op_perf_start();
+		op_arm_enabled = 1;
 	}
 	mutex_unlock(&op_arm_mutex);
 	return ret;
@@ -71,113 +222,205 @@
 {
 	mutex_lock(&op_arm_mutex);
 	if (op_arm_enabled)
-		op_arm_model->stop();
+		op_perf_stop();
 	op_arm_enabled = 0;
 	mutex_unlock(&op_arm_mutex);
 }
 
 #ifdef CONFIG_PM
-static int op_arm_suspend(struct sys_device *dev, pm_message_t state)
+static int op_arm_suspend(struct platform_device *dev, pm_message_t state)
 {
 	mutex_lock(&op_arm_mutex);
 	if (op_arm_enabled)
-		op_arm_model->stop();
+		op_perf_stop();
 	mutex_unlock(&op_arm_mutex);
 	return 0;
 }
 
-static int op_arm_resume(struct sys_device *dev)
+static int op_arm_resume(struct platform_device *dev)
 {
 	mutex_lock(&op_arm_mutex);
-	if (op_arm_enabled && op_arm_model->start())
+	if (op_arm_enabled && op_perf_start())
 		op_arm_enabled = 0;
 	mutex_unlock(&op_arm_mutex);
 	return 0;
 }
 
-static struct sysdev_class oprofile_sysclass = {
-	.name		= "oprofile",
+static struct platform_driver oprofile_driver = {
+	.driver		= {
+		.name		= "arm-oprofile",
+	},
 	.resume		= op_arm_resume,
 	.suspend	= op_arm_suspend,
 };
 
-static struct sys_device device_oprofile = {
-	.id		= 0,
-	.cls		= &oprofile_sysclass,
-};
+static struct platform_device *oprofile_pdev;
 
 static int __init init_driverfs(void)
 {
 	int ret;
 
-	if (!(ret = sysdev_class_register(&oprofile_sysclass)))
-		ret = sysdev_register(&device_oprofile);
+	ret = platform_driver_register(&oprofile_driver);
+	if (ret)
+		goto out;
 
+	oprofile_pdev =	platform_device_register_simple(
+				oprofile_driver.driver.name, 0, NULL, 0);
+	if (IS_ERR(oprofile_pdev)) {
+		ret = PTR_ERR(oprofile_pdev);
+		platform_driver_unregister(&oprofile_driver);
+	}
+
+out:
 	return ret;
 }
 
 static void  exit_driverfs(void)
 {
-	sysdev_unregister(&device_oprofile);
-	sysdev_class_unregister(&oprofile_sysclass);
+	platform_device_unregister(oprofile_pdev);
+	platform_driver_unregister(&oprofile_driver);
 }
 #else
-#define init_driverfs()	do { } while (0)
+static int __init init_driverfs(void) { return 0; }
 #define exit_driverfs() do { } while (0)
 #endif /* CONFIG_PM */
 
+static int report_trace(struct stackframe *frame, void *d)
+{
+	unsigned int *depth = d;
+
+	if (*depth) {
+		oprofile_add_trace(frame->pc);
+		(*depth)--;
+	}
+
+	return *depth == 0;
+}
+
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ */
+struct frame_tail {
+	struct frame_tail *fp;
+	unsigned long sp;
+	unsigned long lr;
+} __attribute__((packed));
+
+static struct frame_tail* user_backtrace(struct frame_tail *tail)
+{
+	struct frame_tail buftail[2];
+
+	/* Also check accessibility of one struct frame_tail beyond */
+	if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+		return NULL;
+	if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail)))
+		return NULL;
+
+	oprofile_add_trace(buftail[0].lr);
+
+	/* frame pointers should strictly progress back up the stack
+	 * (towards higher addresses) */
+	if (tail >= buftail[0].fp)
+		return NULL;
+
+	return buftail[0].fp-1;
+}
+
+static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+	struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+
+	if (!user_mode(regs)) {
+		struct stackframe frame;
+		frame.fp = regs->ARM_fp;
+		frame.sp = regs->ARM_sp;
+		frame.lr = regs->ARM_lr;
+		frame.pc = regs->ARM_pc;
+		walk_stackframe(&frame, report_trace, &depth);
+		return;
+	}
+
+	while (depth-- && tail && !((unsigned long) tail & 3))
+		tail = user_backtrace(tail);
+}
+
 int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
-	struct op_arm_model_spec *spec = NULL;
-	int ret = -ENODEV;
+	int cpu, ret = 0;
 
-	ops->backtrace = arm_backtrace;
+	perf_num_counters = armpmu_get_max_events();
 
-#ifdef CONFIG_CPU_XSCALE
-	spec = &op_xscale_spec;
-#endif
+	counter_config = kcalloc(perf_num_counters,
+			sizeof(struct op_counter_config), GFP_KERNEL);
 
-#ifdef CONFIG_OPROFILE_ARMV6
-	spec = &op_armv6_spec;
-#endif
-
-#ifdef CONFIG_OPROFILE_MPCORE
-	spec = &op_mpcore_spec;
-#endif
-
-#ifdef CONFIG_OPROFILE_ARMV7
-	spec = &op_armv7_spec;
-#endif
-
-	if (spec) {
-		ret = spec->init();
-		if (ret < 0)
-			return ret;
-
-		counter_config = kcalloc(spec->num_counters, sizeof(struct op_counter_config),
-					 GFP_KERNEL);
-		if (!counter_config)
-			return -ENOMEM;
-
-		op_arm_model = spec;
-		init_driverfs();
-		ops->create_files = op_arm_create_files;
-		ops->setup = op_arm_setup;
-		ops->shutdown = op_arm_stop;
-		ops->start = op_arm_start;
-		ops->stop = op_arm_stop;
-		ops->cpu_type = op_arm_model->name;
-		printk(KERN_INFO "oprofile: using %s\n", spec->name);
+	if (!counter_config) {
+		pr_info("oprofile: failed to allocate %d "
+				"counters\n", perf_num_counters);
+		return -ENOMEM;
 	}
 
+	ret = init_driverfs();
+	if (ret) {
+		kfree(counter_config);
+		return ret;
+	}
+
+	for_each_possible_cpu(cpu) {
+		perf_events[cpu] = kcalloc(perf_num_counters,
+				sizeof(struct perf_event *), GFP_KERNEL);
+		if (!perf_events[cpu]) {
+			pr_info("oprofile: failed to allocate %d perf events "
+					"for cpu %d\n", perf_num_counters, cpu);
+			while (--cpu >= 0)
+				kfree(perf_events[cpu]);
+			return -ENOMEM;
+		}
+	}
+
+	ops->backtrace		= arm_backtrace;
+	ops->create_files	= op_arm_create_files;
+	ops->setup		= op_arm_setup;
+	ops->start		= op_arm_start;
+	ops->stop		= op_arm_stop;
+	ops->shutdown		= op_arm_stop;
+	ops->cpu_type		= op_name_from_perf_id(armpmu_get_pmu_id());
+
+	if (!ops->cpu_type)
+		ret = -ENODEV;
+	else
+		pr_info("oprofile: using %s\n", ops->cpu_type);
+
 	return ret;
 }
 
 void oprofile_arch_exit(void)
 {
-	if (op_arm_model) {
+	int cpu, id;
+	struct perf_event *event;
+
+	if (*perf_events) {
 		exit_driverfs();
-		op_arm_model = NULL;
+		for_each_possible_cpu(cpu) {
+			for (id = 0; id < perf_num_counters; ++id) {
+				event = perf_events[cpu][id];
+				if (event != NULL)
+					perf_event_release_kernel(event);
+			}
+			kfree(perf_events[cpu]);
+		}
 	}
-	kfree(counter_config);
+
+	if (counter_config)
+		kfree(counter_config);
 }
+#else
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+	pr_info("oprofile: hardware counters not available\n");
+	return -ENODEV;
+}
+void oprofile_arch_exit(void) {}
+#endif /* CONFIG_HW_PERF_EVENTS */
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
deleted file mode 100644
index 8c4e4f6..0000000
--- a/arch/arm/oprofile/op_arm_model.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file op_arm_model.h
- * interface to ARM machine specific operations
- *
- * @remark Copyright 2004 Oprofile Authors
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-
-#ifndef OP_ARM_MODEL_H
-#define OP_ARM_MODEL_H
-
-struct op_arm_model_spec {
-	int (*init)(void);
-	unsigned int num_counters;
-	int (*setup_ctrs)(void);
-	int (*start)(void);
-	void (*stop)(void);
-	char *name;
-};
-
-#ifdef CONFIG_CPU_XSCALE
-extern struct op_arm_model_spec op_xscale_spec;
-#endif
-
-extern struct op_arm_model_spec op_armv6_spec;
-extern struct op_arm_model_spec op_mpcore_spec;
-extern struct op_arm_model_spec op_armv7_spec;
-
-extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
-
-extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
-extern void op_arm_exit(void);
-#endif /* OP_ARM_MODEL_H */
diff --git a/arch/arm/oprofile/op_counter.h b/arch/arm/oprofile/op_counter.h
deleted file mode 100644
index ca942a6..0000000
--- a/arch/arm/oprofile/op_counter.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * @file op_counter.h
- *
- * @remark Copyright 2004 Oprofile Authors
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-
-#ifndef OP_COUNTER_H
-#define OP_COUNTER_H
-
-/* Per performance monitor configuration as set via
- * oprofilefs.
- */
-struct op_counter_config {
-	unsigned long count;
-	unsigned long enabled;
-	unsigned long event;
-	unsigned long unit_mask;
-	unsigned long kernel;
-	unsigned long user;
-};
-
-extern struct op_counter_config *counter_config;
-
-#endif /* OP_COUNTER_H */
diff --git a/arch/arm/oprofile/op_model_arm11_core.c b/arch/arm/oprofile/op_model_arm11_core.c
deleted file mode 100644
index ef3e265..0000000
--- a/arch/arm/oprofile/op_model_arm11_core.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * @file op_model_arm11_core.c
- * ARM11 Event Monitor Driver
- * @remark Copyright 2004 ARM SMP Development Team
- */
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/smp.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-#include "op_model_arm11_core.h"
-
-/*
- * ARM11 PMU support
- */
-static inline void arm11_write_pmnc(u32 val)
-{
-	/* upper 4bits and 7, 11 are write-as-0 */
-	val &= 0x0ffff77f;
-	asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r" (val));
-}
-
-static inline u32 arm11_read_pmnc(void)
-{
-	u32 val;
-	asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r" (val));
-	return val;
-}
-
-static void arm11_reset_counter(unsigned int cnt)
-{
-	u32 val = -(u32)counter_config[CPU_COUNTER(smp_processor_id(), cnt)].count;
-	switch (cnt) {
-	case CCNT:
-		asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r" (val));
-		break;
-
-	case PMN0:
-		asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r" (val));
-		break;
-
-	case PMN1:
-		asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r" (val));
-		break;
-	}
-}
-
-int arm11_setup_pmu(void)
-{
-	unsigned int cnt;
-	u32 pmnc;
-
-	if (arm11_read_pmnc() & PMCR_E) {
-		printk(KERN_ERR "oprofile: CPU%u PMU still enabled when setup new event counter.\n", smp_processor_id());
-		return -EBUSY;
-	}
-
-	/* initialize PMNC, reset overflow, D bit, C bit and P bit. */
-	arm11_write_pmnc(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT |
-			 PMCR_C | PMCR_P);
-
-	for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) {
-		unsigned long event;
-
-		if (!counter_config[CPU_COUNTER(smp_processor_id(), cnt)].enabled)
-			continue;
-
-		event = counter_config[CPU_COUNTER(smp_processor_id(), cnt)].event & 255;
-
-		/*
-		 * Set event (if destined for PMNx counters)
-		 */
-		if (cnt == PMN0) {
-			pmnc |= event << 20;
-		} else if (cnt == PMN1) {
-			pmnc |= event << 12;
-		}
-
-		/*
-		 * We don't need to set the event if it's a cycle count
-		 * Enable interrupt for this counter
-		 */
-		pmnc |= PMCR_IEN_PMN0 << cnt;
-		arm11_reset_counter(cnt);
-	}
-	arm11_write_pmnc(pmnc);
-
-	return 0;
-}
-
-int arm11_start_pmu(void)
-{
-	arm11_write_pmnc(arm11_read_pmnc() | PMCR_E);
-	return 0;
-}
-
-int arm11_stop_pmu(void)
-{
-	unsigned int cnt;
-
-	arm11_write_pmnc(arm11_read_pmnc() & ~PMCR_E);
-
-	for (cnt = PMN0; cnt <= CCNT; cnt++)
-		arm11_reset_counter(cnt);
-
-	return 0;
-}
-
-/*
- * CPU counters' IRQ handler (one IRQ per CPU)
- */
-static irqreturn_t arm11_pmu_interrupt(int irq, void *arg)
-{
-	struct pt_regs *regs = get_irq_regs();
-	unsigned int cnt;
-	u32 pmnc;
-
-	pmnc = arm11_read_pmnc();
-
-	for (cnt = PMN0; cnt <= CCNT; cnt++) {
-		if ((pmnc & (PMCR_OFL_PMN0 << cnt)) && (pmnc & (PMCR_IEN_PMN0 << cnt))) {
-			arm11_reset_counter(cnt);
-			oprofile_add_sample(regs, CPU_COUNTER(smp_processor_id(), cnt));
-		}
-	}
-	/* Clear counter flag(s) */
-	arm11_write_pmnc(pmnc);
-	return IRQ_HANDLED;
-}
-
-int arm11_request_interrupts(const int *irqs, int nr)
-{
-	unsigned int i;
-	int ret = 0;
-
-	for(i = 0; i < nr; i++) {
-		ret = request_irq(irqs[i], arm11_pmu_interrupt, IRQF_DISABLED, "CP15 PMU", NULL);
-		if (ret != 0) {
-			printk(KERN_ERR "oprofile: unable to request IRQ%u for MPCORE-EM\n",
-			       irqs[i]);
-			break;
-		}
-	}
-
-	if (i != nr)
-		while (i-- != 0)
-			free_irq(irqs[i], NULL);
-
-	return ret;
-}
-
-void arm11_release_interrupts(const int *irqs, int nr)
-{
-	unsigned int i;
-
-	for (i = 0; i < nr; i++)
-		free_irq(irqs[i], NULL);
-}
diff --git a/arch/arm/oprofile/op_model_arm11_core.h b/arch/arm/oprofile/op_model_arm11_core.h
deleted file mode 100644
index 1902b99..0000000
--- a/arch/arm/oprofile/op_model_arm11_core.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * @file op_model_arm11_core.h
- * ARM11 Event Monitor Driver
- * @remark Copyright 2004 ARM SMP Development Team
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 Oprofile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-#ifndef OP_MODEL_ARM11_CORE_H
-#define OP_MODEL_ARM11_CORE_H
-
-/*
- * Per-CPU PMCR
- */
-#define PMCR_E		(1 << 0)	/* Enable */
-#define PMCR_P		(1 << 1)	/* Count reset */
-#define PMCR_C		(1 << 2)	/* Cycle counter reset */
-#define PMCR_D		(1 << 3)	/* Cycle counter counts every 64th cpu cycle */
-#define PMCR_IEN_PMN0	(1 << 4)	/* Interrupt enable count reg 0 */
-#define PMCR_IEN_PMN1	(1 << 5)	/* Interrupt enable count reg 1 */
-#define PMCR_IEN_CCNT	(1 << 6)	/* Interrupt enable cycle counter */
-#define PMCR_OFL_PMN0	(1 << 8)	/* Count reg 0 overflow */
-#define PMCR_OFL_PMN1	(1 << 9)	/* Count reg 1 overflow */
-#define PMCR_OFL_CCNT	(1 << 10)	/* Cycle counter overflow */
-
-#define PMN0 0
-#define PMN1 1
-#define CCNT 2
-
-#define CPU_COUNTER(cpu, counter)	((cpu) * 3 + (counter))
-
-int arm11_setup_pmu(void);
-int arm11_start_pmu(void);
-int arm11_stop_pmu(void);
-int arm11_request_interrupts(const int *, int);
-void arm11_release_interrupts(const int *, int);
-
-#endif
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c
deleted file mode 100644
index f73ce87..0000000
--- a/arch/arm/oprofile/op_model_mpcore.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/**
- * @file op_model_mpcore.c
- * MPCORE Event Monitor Driver
- * @remark Copyright 2004 ARM SMP Development Team
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 Oprofile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- *
- *  Counters:
- *    0: PMN0 on CPU0, per-cpu configurable event counter
- *    1: PMN1 on CPU0, per-cpu configurable event counter
- *    2: CCNT on CPU0
- *    3: PMN0 on CPU1
- *    4: PMN1 on CPU1
- *    5: CCNT on CPU1
- *    6: PMN0 on CPU1
- *    7: PMN1 on CPU1
- *    8: CCNT on CPU1
- *    9: PMN0 on CPU1
- *   10: PMN1 on CPU1
- *   11: CCNT on CPU1
- *   12-19: configurable SCU event counters
- */
-
-/* #define DEBUG */
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/sched.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-#include <mach/hardware.h>
-#include <mach/board-eb.h>
-#include <asm/system.h>
-#include <asm/pmu.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-#include "op_model_arm11_core.h"
-#include "op_model_mpcore.h"
-
-/*
- * MPCore SCU event monitor support
- */
-#define SCU_EVENTMONITORS_VA_BASE __io_address(REALVIEW_EB11MP_SCU_BASE + 0x10)
-
-/*
- * Bitmask of used SCU counters
- */
-static unsigned int scu_em_used;
-static const struct pmu_irqs *pmu_irqs;
-
-/*
- * 2 helper fns take a counter number from 0-7 (not the userspace-visible counter number)
- */
-static inline void scu_reset_counter(struct eventmonitor __iomem *emc, unsigned int n)
-{
-	writel(-(u32)counter_config[SCU_COUNTER(n)].count, &emc->MC[n]);
-}
-
-static inline void scu_set_event(struct eventmonitor __iomem *emc, unsigned int n, u32 event)
-{
-	event &= 0xff;
-	writeb(event, &emc->MCEB[n]);
-}
-
-/*
- * SCU counters' IRQ handler (one IRQ per counter => 2 IRQs per CPU)
- */
-static irqreturn_t scu_em_interrupt(int irq, void *arg)
-{
-	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
-	unsigned int cnt;
-
-	cnt = irq - IRQ_EB11MP_PMU_SCU0;
-	oprofile_add_sample(get_irq_regs(), SCU_COUNTER(cnt));
-	scu_reset_counter(emc, cnt);
-
-	/* Clear overflow flag for this counter */
-	writel(1 << (cnt + 16), &emc->PMCR);
-
-	return IRQ_HANDLED;
-}
-
-/* Configure just the SCU counters that the user has requested */
-static void scu_setup(void)
-{
-	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
-	unsigned int i;
-
-	scu_em_used = 0;
-
-	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-		if (counter_config[SCU_COUNTER(i)].enabled &&
-		    counter_config[SCU_COUNTER(i)].event) {
-			scu_set_event(emc, i, 0); /* disable counter for now */
-			scu_em_used |= 1 << i;
-		}
-	}
-}
-
-static int scu_start(void)
-{
-	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
-	unsigned int temp, i;
-	unsigned long event;
-	int ret = 0;
-
-	/*
-	 * request the SCU counter interrupts that we need
-	 */
-	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-		if (scu_em_used & (1 << i)) {
-			ret = request_irq(IRQ_EB11MP_PMU_SCU0 + i, scu_em_interrupt, IRQF_DISABLED, "SCU PMU", NULL);
-			if (ret) {
-				printk(KERN_ERR "oprofile: unable to request IRQ%u for SCU Event Monitor\n",
-				       IRQ_EB11MP_PMU_SCU0 + i);
-				goto err_free_scu;
-			}
-		}
-	}
-
-	/*
-	 * clear overflow and enable interrupt for all used counters
-	 */
-	temp = readl(&emc->PMCR);
-	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-		if (scu_em_used & (1 << i)) {
-			scu_reset_counter(emc, i);
-			event = counter_config[SCU_COUNTER(i)].event;
-			scu_set_event(emc, i, event);
-
-			/* clear overflow/interrupt */
-			temp |= 1 << (i + 16);
-			/* enable interrupt*/
-			temp |= 1 << (i + 8);
-		}
-	}
-
-	/* Enable all 8 counters */
-	temp |= PMCR_E;
-	writel(temp, &emc->PMCR);
-
-	return 0;
-
- err_free_scu:
-	while (i--)
-		free_irq(IRQ_EB11MP_PMU_SCU0 + i, NULL);
-	return ret;
-}
-
-static void scu_stop(void)
-{
-	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
-	unsigned int temp, i;
-
-	/* Disable counter interrupts */
-	/* Don't disable all 8 counters (with the E bit) as they may be in use */
-	temp = readl(&emc->PMCR);
-	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-		if (scu_em_used & (1 << i))
-			temp &= ~(1 << (i + 8));
-	}
-	writel(temp, &emc->PMCR);
-
-	/* Free counter interrupts and reset counters */
-	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-		if (scu_em_used & (1 << i)) {
-			scu_reset_counter(emc, i);
-			free_irq(IRQ_EB11MP_PMU_SCU0 + i, NULL);
-		}
-	}
-}
-
-struct em_function_data {
-	int (*fn)(void);
-	int ret;
-};
-
-static void em_func(void *data)
-{
-	struct em_function_data *d = data;
-	int ret = d->fn();
-	if (ret)
-		d->ret = ret;
-}
-
-static int em_call_function(int (*fn)(void))
-{
-	struct em_function_data data;
-
-	data.fn = fn;
-	data.ret = 0;
-
-	preempt_disable();
-	smp_call_function(em_func, &data, 1);
-	em_func(&data);
-	preempt_enable();
-
-	return data.ret;
-}
-
-/*
- * Glue to stick the individual ARM11 PMUs and the SCU
- * into the oprofile framework.
- */
-static int em_setup_ctrs(void)
-{
-	int ret;
-
-	/* Configure CPU counters by cross-calling to the other CPUs */
-	ret = em_call_function(arm11_setup_pmu);
-	if (ret == 0)
-		scu_setup();
-
-	return 0;
-}
-
-static int em_start(void)
-{
-	int ret;
-
-	pmu_irqs = reserve_pmu();
-	if (IS_ERR(pmu_irqs)) {
-		ret = PTR_ERR(pmu_irqs);
-		goto out;
-	}
-
-	ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-	if (ret == 0) {
-		em_call_function(arm11_start_pmu);
-
-		ret = scu_start();
-		if (ret) {
-			arm11_release_interrupts(pmu_irqs->irqs,
-						 pmu_irqs->num_irqs);
-		} else {
-			release_pmu(pmu_irqs);
-			pmu_irqs = NULL;
-		}
-	}
-
-out:
-	return ret;
-}
-
-static void em_stop(void)
-{
-	em_call_function(arm11_stop_pmu);
-	arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-	scu_stop();
-	release_pmu(pmu_irqs);
-}
-
-/*
- * Why isn't there a function to route an IRQ to a specific CPU in
- * genirq?
- */
-static void em_route_irq(int irq, unsigned int cpu)
-{
-	struct irq_desc *desc = irq_desc + irq;
-	const struct cpumask *mask = cpumask_of(cpu);
-
-	spin_lock_irq(&desc->lock);
-	cpumask_copy(desc->affinity, mask);
-	desc->chip->set_affinity(irq, mask);
-	spin_unlock_irq(&desc->lock);
-}
-
-static int em_setup(void)
-{
-	/*
-	 * Send SCU PMU interrupts to the "owner" CPU.
-	 */
-	em_route_irq(IRQ_EB11MP_PMU_SCU0, 0);
-	em_route_irq(IRQ_EB11MP_PMU_SCU1, 0);
-	em_route_irq(IRQ_EB11MP_PMU_SCU2, 1);
-	em_route_irq(IRQ_EB11MP_PMU_SCU3, 1);
-	em_route_irq(IRQ_EB11MP_PMU_SCU4, 2);
-	em_route_irq(IRQ_EB11MP_PMU_SCU5, 2);
-	em_route_irq(IRQ_EB11MP_PMU_SCU6, 3);
-	em_route_irq(IRQ_EB11MP_PMU_SCU7, 3);
-
-	return init_pmu();
-}
-
-struct op_arm_model_spec op_mpcore_spec = {
-	.init		= em_setup,
-	.num_counters	= MPCORE_NUM_COUNTERS,
-	.setup_ctrs	= em_setup_ctrs,
-	.start		= em_start,
-	.stop		= em_stop,
-	.name		= "arm/mpcore",
-};
diff --git a/arch/arm/oprofile/op_model_mpcore.h b/arch/arm/oprofile/op_model_mpcore.h
deleted file mode 100644
index 73d8110..0000000
--- a/arch/arm/oprofile/op_model_mpcore.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file op_model_mpcore.c
- * MPCORE Event Monitor Driver
- * @remark Copyright 2004 ARM SMP Development Team
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 Oprofile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-#ifndef OP_MODEL_MPCORE_H
-#define OP_MODEL_MPCORE_H
-
-struct eventmonitor {
-	unsigned long PMCR;
-	unsigned char MCEB[8];
-	unsigned long MC[8];
-};
-
-/*
- * List of userspace counter numbers: note that the structure is important.
- * The code relies on CPUn's counters being CPU0's counters + 3n
- * and on CPU0's counters starting at 0
- */
-
-#define COUNTER_CPU0_PMN0 0
-#define COUNTER_CPU0_PMN1 1
-#define COUNTER_CPU0_CCNT 2
-
-#define COUNTER_CPU1_PMN0 3
-#define COUNTER_CPU1_PMN1 4
-#define COUNTER_CPU1_CCNT 5
-
-#define COUNTER_CPU2_PMN0 6
-#define COUNTER_CPU2_PMN1 7
-#define COUNTER_CPU2_CCNT 8
-
-#define COUNTER_CPU3_PMN0 9
-#define COUNTER_CPU3_PMN1 10
-#define COUNTER_CPU3_CCNT 11
-
-#define COUNTER_SCU_MN0 12
-#define COUNTER_SCU_MN1 13
-#define COUNTER_SCU_MN2 14
-#define COUNTER_SCU_MN3 15
-#define COUNTER_SCU_MN4 16
-#define COUNTER_SCU_MN5 17
-#define COUNTER_SCU_MN6 18
-#define COUNTER_SCU_MN7 19
-#define NUM_SCU_COUNTERS 8
-
-#define SCU_COUNTER(number)	((number) + COUNTER_SCU_MN0)
-
-#define MPCORE_NUM_COUNTERS	SCU_COUNTER(NUM_SCU_COUNTERS)
-
-#endif
diff --git a/arch/arm/oprofile/op_model_v6.c b/arch/arm/oprofile/op_model_v6.c
deleted file mode 100644
index a22357a..0000000
--- a/arch/arm/oprofile/op_model_v6.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * @file op_model_v6.c
- * ARM11 Performance Monitor Driver
- *
- * Based on op_model_xscale.c
- *
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 OProfile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Tony Lindgren <tony@atomide.com>
- */
-
-/* #define DEBUG */
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/sched.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/pmu.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-#include "op_model_arm11_core.h"
-
-static const struct pmu_irqs *pmu_irqs;
-
-static void armv6_pmu_stop(void)
-{
-	arm11_stop_pmu();
-	arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-	release_pmu(pmu_irqs);
-	pmu_irqs = NULL;
-}
-
-static int armv6_pmu_start(void)
-{
-	int ret;
-
-	pmu_irqs = reserve_pmu();
-	if (IS_ERR(pmu_irqs)) {
-		ret = PTR_ERR(pmu_irqs);
-		goto out;
-	}
-
-	ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-	if (ret >= 0) {
-		ret = arm11_start_pmu();
-	} else {
-		release_pmu(pmu_irqs);
-		pmu_irqs = NULL;
-	}
-
-out:
-	return ret;
-}
-
-static int armv6_detect_pmu(void)
-{
-	return 0;
-}
-
-struct op_arm_model_spec op_armv6_spec = {
-	.init		= armv6_detect_pmu,
-	.num_counters	= 3,
-	.setup_ctrs	= arm11_setup_pmu,
-	.start		= armv6_pmu_start,
-	.stop		= armv6_pmu_stop,
-	.name		= "arm/armv6",
-};
diff --git a/arch/arm/oprofile/op_model_v7.c b/arch/arm/oprofile/op_model_v7.c
deleted file mode 100644
index 8642d08..0000000
--- a/arch/arm/oprofile/op_model_v7.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/**
- * op_model_v7.c
- * ARM V7 (Cortex A8) Event Monitor Driver
- *
- * Copyright 2008 Jean Pihet <jpihet@mvista.com>
- * Copyright 2004 ARM SMP Development Team
- *
- * 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/types.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/smp.h>
-
-#include <asm/pmu.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-#include "op_model_v7.h"
-
-/* #define DEBUG */
-
-
-/*
- * ARM V7 PMNC support
- */
-
-static u32 cnt_en[CNTMAX];
-
-static inline void armv7_pmnc_write(u32 val)
-{
-	val &= PMNC_MASK;
-	asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (val));
-}
-
-static inline u32 armv7_pmnc_read(void)
-{
-	u32 val;
-
-	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
-	return val;
-}
-
-static inline u32 armv7_pmnc_enable_counter(unsigned int cnt)
-{
-	u32 val;
-
-	if (cnt >= CNTMAX) {
-		printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
-			" %d\n", smp_processor_id(), cnt);
-		return -1;
-	}
-
-	if (cnt == CCNT)
-		val = CNTENS_C;
-	else
-		val = (1 << (cnt - CNT0));
-
-	val &= CNTENS_MASK;
-	asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
-
-	return cnt;
-}
-
-static inline u32 armv7_pmnc_disable_counter(unsigned int cnt)
-{
-	u32 val;
-
-	if (cnt >= CNTMAX) {
-		printk(KERN_ERR "oprofile: CPU%u disabling wrong PMNC counter"
-			" %d\n", smp_processor_id(), cnt);
-		return -1;
-	}
-
-	if (cnt == CCNT)
-		val = CNTENC_C;
-	else
-		val = (1 << (cnt - CNT0));
-
-	val &= CNTENC_MASK;
-	asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
-
-	return cnt;
-}
-
-static inline u32 armv7_pmnc_enable_intens(unsigned int cnt)
-{
-	u32 val;
-
-	if (cnt >= CNTMAX) {
-		printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
-			" interrupt enable %d\n", smp_processor_id(), cnt);
-		return -1;
-	}
-
-	if (cnt == CCNT)
-		val = INTENS_C;
-	else
-		val = (1 << (cnt - CNT0));
-
-	val &= INTENS_MASK;
-	asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
-
-	return cnt;
-}
-
-static inline u32 armv7_pmnc_getreset_flags(void)
-{
-	u32 val;
-
-	/* Read */
-	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
-
-	/* Write to clear flags */
-	val &= FLAG_MASK;
-	asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
-
-	return val;
-}
-
-static inline int armv7_pmnc_select_counter(unsigned int cnt)
-{
-	u32 val;
-
-	if ((cnt == CCNT) || (cnt >= CNTMAX)) {
-		printk(KERN_ERR "oprofile: CPU%u selecting wrong PMNC counteri"
-			" %d\n", smp_processor_id(), cnt);
-		return -1;
-	}
-
-	val = (cnt - CNT0) & SELECT_MASK;
-	asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
-
-	return cnt;
-}
-
-static inline void armv7_pmnc_write_evtsel(unsigned int cnt, u32 val)
-{
-	if (armv7_pmnc_select_counter(cnt) == cnt) {
-		val &= EVTSEL_MASK;
-		asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
-	}
-}
-
-static void armv7_pmnc_reset_counter(unsigned int cnt)
-{
-	u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
-	u32 val = -(u32)counter_config[cpu_cnt].count;
-
-	switch (cnt) {
-	case CCNT:
-		armv7_pmnc_disable_counter(cnt);
-
-		asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val));
-
-		if (cnt_en[cnt] != 0)
-		    armv7_pmnc_enable_counter(cnt);
-
-		break;
-
-	case CNT0:
-	case CNT1:
-	case CNT2:
-	case CNT3:
-		armv7_pmnc_disable_counter(cnt);
-
-		if (armv7_pmnc_select_counter(cnt) == cnt)
-		    asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val));
-
-		if (cnt_en[cnt] != 0)
-		    armv7_pmnc_enable_counter(cnt);
-
-		break;
-
-	default:
-		printk(KERN_ERR "oprofile: CPU%u resetting wrong PMNC counter"
-			" %d\n", smp_processor_id(), cnt);
-		break;
-	}
-}
-
-int armv7_setup_pmnc(void)
-{
-	unsigned int cnt;
-
-	if (armv7_pmnc_read() & PMNC_E) {
-		printk(KERN_ERR "oprofile: CPU%u PMNC still enabled when setup"
-			" new event counter.\n", smp_processor_id());
-		return -EBUSY;
-	}
-
-	/* Initialize & Reset PMNC: C bit and P bit */
-	armv7_pmnc_write(PMNC_P | PMNC_C);
-
-
-	for (cnt = CCNT; cnt < CNTMAX; cnt++) {
-		unsigned long event;
-		u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
-
-		/*
-		 * Disable counter
-		 */
-		armv7_pmnc_disable_counter(cnt);
-		cnt_en[cnt] = 0;
-
-		if (!counter_config[cpu_cnt].enabled)
-			continue;
-
-		event = counter_config[cpu_cnt].event & 255;
-
-		/*
-		 * Set event (if destined for PMNx counters)
-		 * We don't need to set the event if it's a cycle count
-		 */
-		if (cnt != CCNT)
-			armv7_pmnc_write_evtsel(cnt, event);
-
-		/*
-		 * Enable interrupt for this counter
-		 */
-		armv7_pmnc_enable_intens(cnt);
-
-		/*
-		 * Reset counter
-		 */
-		armv7_pmnc_reset_counter(cnt);
-
-		/*
-		 * Enable counter
-		 */
-		armv7_pmnc_enable_counter(cnt);
-		cnt_en[cnt] = 1;
-	}
-
-	return 0;
-}
-
-static inline void armv7_start_pmnc(void)
-{
-	armv7_pmnc_write(armv7_pmnc_read() | PMNC_E);
-}
-
-static inline void armv7_stop_pmnc(void)
-{
-	armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
-}
-
-/*
- * CPU counters' IRQ handler (one IRQ per CPU)
- */
-static irqreturn_t armv7_pmnc_interrupt(int irq, void *arg)
-{
-	struct pt_regs *regs = get_irq_regs();
-	unsigned int cnt;
-	u32 flags;
-
-
-	/*
-	 * Stop IRQ generation
-	 */
-	armv7_stop_pmnc();
-
-	/*
-	 * Get and reset overflow status flags
-	 */
-	flags = armv7_pmnc_getreset_flags();
-
-	/*
-	 * Cycle counter
-	 */
-	if (flags & FLAG_C) {
-		u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), CCNT);
-		armv7_pmnc_reset_counter(CCNT);
-		oprofile_add_sample(regs, cpu_cnt);
-	}
-
-	/*
-	 * PMNC counters 0:3
-	 */
-	for (cnt = CNT0; cnt < CNTMAX; cnt++) {
-		if (flags & (1 << (cnt - CNT0))) {
-			u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
-			armv7_pmnc_reset_counter(cnt);
-			oprofile_add_sample(regs, cpu_cnt);
-		}
-	}
-
-	/*
-	 * Allow IRQ generation
-	 */
-	armv7_start_pmnc();
-
-	return IRQ_HANDLED;
-}
-
-int armv7_request_interrupts(const int *irqs, int nr)
-{
-	unsigned int i;
-	int ret = 0;
-
-	for (i = 0; i < nr; i++) {
-		ret = request_irq(irqs[i], armv7_pmnc_interrupt,
-				IRQF_DISABLED, "CP15 PMNC", NULL);
-		if (ret != 0) {
-			printk(KERN_ERR "oprofile: unable to request IRQ%u"
-				" for ARMv7\n",
-			       irqs[i]);
-			break;
-		}
-	}
-
-	if (i != nr)
-		while (i-- != 0)
-			free_irq(irqs[i], NULL);
-
-	return ret;
-}
-
-void armv7_release_interrupts(const int *irqs, int nr)
-{
-	unsigned int i;
-
-	for (i = 0; i < nr; i++)
-		free_irq(irqs[i], NULL);
-}
-
-#ifdef DEBUG
-static void armv7_pmnc_dump_regs(void)
-{
-	u32 val;
-	unsigned int cnt;
-
-	printk(KERN_INFO "PMNC registers dump:\n");
-
-	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
-	printk(KERN_INFO "PMNC  =0x%08x\n", val);
-
-	asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
-	printk(KERN_INFO "CNTENS=0x%08x\n", val);
-
-	asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
-	printk(KERN_INFO "INTENS=0x%08x\n", val);
-
-	asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
-	printk(KERN_INFO "FLAGS =0x%08x\n", val);
-
-	asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
-	printk(KERN_INFO "SELECT=0x%08x\n", val);
-
-	asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
-	printk(KERN_INFO "CCNT  =0x%08x\n", val);
-
-	for (cnt = CNT0; cnt < CNTMAX; cnt++) {
-		armv7_pmnc_select_counter(cnt);
-		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
-		printk(KERN_INFO "CNT[%d] count =0x%08x\n", cnt-CNT0, val);
-		asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
-		printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", cnt-CNT0, val);
-	}
-}
-#endif
-
-static const struct pmu_irqs *pmu_irqs;
-
-static void armv7_pmnc_stop(void)
-{
-#ifdef DEBUG
-	armv7_pmnc_dump_regs();
-#endif
-	armv7_stop_pmnc();
-	armv7_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-	release_pmu(pmu_irqs);
-	pmu_irqs = NULL;
-}
-
-static int armv7_pmnc_start(void)
-{
-	int ret;
-
-	pmu_irqs = reserve_pmu();
-	if (IS_ERR(pmu_irqs))
-		return PTR_ERR(pmu_irqs);
-
-#ifdef DEBUG
-	armv7_pmnc_dump_regs();
-#endif
-	ret = armv7_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-	if (ret >= 0) {
-		armv7_start_pmnc();
-	} else {
-		release_pmu(pmu_irqs);
-		pmu_irqs = NULL;
-	}
-
-	return ret;
-}
-
-static int armv7_detect_pmnc(void)
-{
-	return 0;
-}
-
-struct op_arm_model_spec op_armv7_spec = {
-	.init		= armv7_detect_pmnc,
-	.num_counters	= 5,
-	.setup_ctrs	= armv7_setup_pmnc,
-	.start		= armv7_pmnc_start,
-	.stop		= armv7_pmnc_stop,
-	.name		= "arm/armv7",
-};
diff --git a/arch/arm/oprofile/op_model_v7.h b/arch/arm/oprofile/op_model_v7.h
deleted file mode 100644
index 9ca334b..0000000
--- a/arch/arm/oprofile/op_model_v7.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * op_model_v7.h
- * ARM v7 (Cortex A8) Event Monitor Driver
- *
- * Copyright 2008 Jean Pihet <jpihet@mvista.com>
- * Copyright 2004 ARM SMP Development Team
- * Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * Copyright 2000-2004 MontaVista Software Inc
- * Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * Copyright 2004 Intel Corporation
- * Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * Copyright 2004 Oprofile Authors
- *
- * Read the file COPYING
- *
- * 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 OP_MODEL_V7_H
-#define OP_MODEL_V7_H
-
-/*
- * Per-CPU PMNC: config reg
- */
-#define PMNC_E		(1 << 0)	/* Enable all counters */
-#define PMNC_P		(1 << 1)	/* Reset all counters */
-#define PMNC_C		(1 << 2)	/* Cycle counter reset */
-#define PMNC_D		(1 << 3)	/* CCNT counts every 64th cpu cycle */
-#define PMNC_X		(1 << 4)	/* Export to ETM */
-#define PMNC_DP		(1 << 5)	/* Disable CCNT if non-invasive debug*/
-#define	PMNC_MASK	0x3f		/* Mask for writable bits */
-
-/*
- * Available counters
- */
-#define CCNT 		0
-#define CNT0 		1
-#define CNT1 		2
-#define CNT2 		3
-#define CNT3 		4
-#define CNTMAX 		5
-
-#define CPU_COUNTER(cpu, counter)	((cpu) * CNTMAX + (counter))
-
-/*
- * CNTENS: counters enable reg
- */
-#define CNTENS_P0	(1 << 0)
-#define CNTENS_P1	(1 << 1)
-#define CNTENS_P2	(1 << 2)
-#define CNTENS_P3	(1 << 3)
-#define CNTENS_C	(1 << 31)
-#define	CNTENS_MASK	0x8000000f	/* Mask for writable bits */
-
-/*
- * CNTENC: counters disable reg
- */
-#define CNTENC_P0	(1 << 0)
-#define CNTENC_P1	(1 << 1)
-#define CNTENC_P2	(1 << 2)
-#define CNTENC_P3	(1 << 3)
-#define CNTENC_C	(1 << 31)
-#define	CNTENC_MASK	0x8000000f	/* Mask for writable bits */
-
-/*
- * INTENS: counters overflow interrupt enable reg
- */
-#define INTENS_P0	(1 << 0)
-#define INTENS_P1	(1 << 1)
-#define INTENS_P2	(1 << 2)
-#define INTENS_P3	(1 << 3)
-#define INTENS_C	(1 << 31)
-#define	INTENS_MASK	0x8000000f	/* Mask for writable bits */
-
-/*
- * EVTSEL: Event selection reg
- */
-#define	EVTSEL_MASK	0x7f		/* Mask for writable bits */
-
-/*
- * SELECT: Counter selection reg
- */
-#define	SELECT_MASK	0x1f		/* Mask for writable bits */
-
-/*
- * FLAG: counters overflow flag status reg
- */
-#define FLAG_P0		(1 << 0)
-#define FLAG_P1		(1 << 1)
-#define FLAG_P2		(1 << 2)
-#define FLAG_P3		(1 << 3)
-#define FLAG_C		(1 << 31)
-#define	FLAG_MASK	0x8000000f	/* Mask for writable bits */
-
-
-int armv7_setup_pmu(void);
-int armv7_start_pmu(void);
-int armv7_stop_pmu(void);
-int armv7_request_interrupts(const int *, int);
-void armv7_release_interrupts(const int *, int);
-
-#endif
diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c
deleted file mode 100644
index 1d34a02..0000000
--- a/arch/arm/oprofile/op_model_xscale.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/**
- * @file op_model_xscale.c
- * XScale Performance Monitor Driver
- *
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 OProfile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-
-/* #define DEBUG */
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/sched.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <asm/cputype.h>
-#include <asm/pmu.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-
-#define	PMU_ENABLE	0x001	/* Enable counters */
-#define PMN_RESET	0x002	/* Reset event counters */
-#define	CCNT_RESET	0x004	/* Reset clock counter */
-#define	PMU_RESET	(CCNT_RESET | PMN_RESET)
-#define PMU_CNT64	0x008	/* Make CCNT count every 64th cycle */
-
-/*
- * Different types of events that can be counted by the XScale PMU
- * as used by Oprofile userspace. Here primarily for documentation
- * purposes.
- */
-
-#define EVT_ICACHE_MISS			0x00
-#define	EVT_ICACHE_NO_DELIVER		0x01
-#define	EVT_DATA_STALL			0x02
-#define	EVT_ITLB_MISS			0x03
-#define	EVT_DTLB_MISS			0x04
-#define	EVT_BRANCH			0x05
-#define	EVT_BRANCH_MISS			0x06
-#define	EVT_INSTRUCTION			0x07
-#define	EVT_DCACHE_FULL_STALL		0x08
-#define	EVT_DCACHE_FULL_STALL_CONTIG	0x09
-#define	EVT_DCACHE_ACCESS		0x0A
-#define	EVT_DCACHE_MISS			0x0B
-#define	EVT_DCACE_WRITE_BACK		0x0C
-#define	EVT_PC_CHANGED			0x0D
-#define	EVT_BCU_REQUEST			0x10
-#define	EVT_BCU_FULL			0x11
-#define	EVT_BCU_DRAIN			0x12
-#define	EVT_BCU_ECC_NO_ELOG		0x14
-#define	EVT_BCU_1_BIT_ERR		0x15
-#define	EVT_RMW				0x16
-/* EVT_CCNT is not hardware defined */
-#define EVT_CCNT			0xFE
-#define EVT_UNUSED			0xFF
-
-struct pmu_counter {
-	volatile unsigned long ovf;
-	unsigned long reset_counter;
-};
-
-enum { CCNT, PMN0, PMN1, PMN2, PMN3, MAX_COUNTERS };
-
-static struct pmu_counter results[MAX_COUNTERS];
-
-/*
- * There are two versions of the PMU in current XScale processors
- * with differing register layouts and number of performance counters.
- * e.g. IOP32x is xsc1 whilst IOP33x is xsc2.
- * We detect which register layout to use in xscale_detect_pmu()
- */
-enum { PMU_XSC1, PMU_XSC2 };
-
-struct pmu_type {
-	int id;
-	char *name;
-	int num_counters;
-	unsigned int int_enable;
-	unsigned int cnt_ovf[MAX_COUNTERS];
-	unsigned int int_mask[MAX_COUNTERS];
-};
-
-static struct pmu_type pmu_parms[] = {
-	{
-		.id		= PMU_XSC1,
-		.name		= "arm/xscale1",
-		.num_counters	= 3,
-		.int_mask	= { [PMN0] = 0x10, [PMN1] = 0x20,
-				    [CCNT] = 0x40 },
-		.cnt_ovf	= { [CCNT] = 0x400, [PMN0] = 0x100,
-				    [PMN1] = 0x200},
-	},
-	{
-		.id		= PMU_XSC2,
-		.name		= "arm/xscale2",
-		.num_counters	= 5,
-		.int_mask	= { [CCNT] = 0x01, [PMN0] = 0x02,
-				    [PMN1] = 0x04, [PMN2] = 0x08,
-				    [PMN3] = 0x10 },
-		.cnt_ovf	= { [CCNT] = 0x01, [PMN0] = 0x02,
-				    [PMN1] = 0x04, [PMN2] = 0x08,
-				    [PMN3] = 0x10 },
-	},
-};
-
-static struct pmu_type *pmu;
-
-static void write_pmnc(u32 val)
-{
-	if (pmu->id == PMU_XSC1) {
-		/* upper 4bits and 7, 11 are write-as-0 */
-		val &= 0xffff77f;
-		__asm__ __volatile__ ("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
-	} else {
-		/* bits 4-23 are write-as-0, 24-31 are write ignored */
-		val &= 0xf;
-		__asm__ __volatile__ ("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
-	}
-}
-
-static u32 read_pmnc(void)
-{
-	u32 val;
-
-	if (pmu->id == PMU_XSC1)
-		__asm__ __volatile__ ("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
-	else {
-		__asm__ __volatile__ ("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
-		/* bits 1-2 and 4-23 are read-unpredictable */
-		val &= 0xff000009;
-	}
-
-	return val;
-}
-
-static u32 __xsc1_read_counter(int counter)
-{
-	u32 val = 0;
-
-	switch (counter) {
-	case CCNT:
-		__asm__ __volatile__ ("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
-		break;
-	case PMN0:
-		__asm__ __volatile__ ("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
-		break;
-	case PMN1:
-		__asm__ __volatile__ ("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
-		break;
-	}
-	return val;
-}
-
-static u32 __xsc2_read_counter(int counter)
-{
-	u32 val = 0;
-
-	switch (counter) {
-	case CCNT:
-		__asm__ __volatile__ ("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
-		break;
-	case PMN0:
-		__asm__ __volatile__ ("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
-		break;
-	case PMN1:
-		__asm__ __volatile__ ("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
-		break;
-	case PMN2:
-		__asm__ __volatile__ ("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
-		break;
-	case PMN3:
-		__asm__ __volatile__ ("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
-		break;
-	}
-	return val;
-}
-
-static u32 read_counter(int counter)
-{
-	u32 val;
-
-	if (pmu->id == PMU_XSC1)
-		val = __xsc1_read_counter(counter);
-	else
-		val = __xsc2_read_counter(counter);
-
-	return val;
-}
-
-static void __xsc1_write_counter(int counter, u32 val)
-{
-	switch (counter) {
-	case CCNT:
-		__asm__ __volatile__ ("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
-		break;
-	case PMN0:
-		__asm__ __volatile__ ("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
-		break;
-	case PMN1:
-		__asm__ __volatile__ ("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
-		break;
-	}
-}
-
-static void __xsc2_write_counter(int counter, u32 val)
-{
-	switch (counter) {
-	case CCNT:
-		__asm__ __volatile__ ("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
-		break;
-	case PMN0:
-		__asm__ __volatile__ ("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
-		break;
-	case PMN1:
-		__asm__ __volatile__ ("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
-		break;
-	case PMN2:
-		__asm__ __volatile__ ("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
-		break;
-	case PMN3:
-		__asm__ __volatile__ ("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
-		break;
-	}
-}
-
-static void write_counter(int counter, u32 val)
-{
-	if (pmu->id == PMU_XSC1)
-		__xsc1_write_counter(counter, val);
-	else
-		__xsc2_write_counter(counter, val);
-}
-
-static int xscale_setup_ctrs(void)
-{
-	u32 evtsel, pmnc;
-	int i;
-
-	for (i = CCNT; i < MAX_COUNTERS; i++) {
-		if (counter_config[i].enabled)
-			continue;
-
-		counter_config[i].event = EVT_UNUSED;
-	}
-
-	switch (pmu->id) {
-	case PMU_XSC1:
-		pmnc = (counter_config[PMN1].event << 20) | (counter_config[PMN0].event << 12);
-		pr_debug("xscale_setup_ctrs: pmnc: %#08x\n", pmnc);
-		write_pmnc(pmnc);
-		break;
-
-	case PMU_XSC2:
-		evtsel = counter_config[PMN0].event | (counter_config[PMN1].event << 8) |
-			(counter_config[PMN2].event << 16) | (counter_config[PMN3].event << 24);
-
-		pr_debug("xscale_setup_ctrs: evtsel %#08x\n", evtsel);
-		__asm__ __volatile__ ("mcr p14, 0, %0, c8, c1, 0" : : "r" (evtsel));
-		break;
-	}
-
-	for (i = CCNT; i < MAX_COUNTERS; i++) {
-		if (counter_config[i].event == EVT_UNUSED) {
-			counter_config[i].event = 0;
-			pmu->int_enable &= ~pmu->int_mask[i];
-			continue;
-		}
-
-		results[i].reset_counter = counter_config[i].count;
-		write_counter(i, -(u32)counter_config[i].count);
-		pmu->int_enable |= pmu->int_mask[i];
-		pr_debug("xscale_setup_ctrs: counter%d %#08x from %#08lx\n", i,
-			read_counter(i), counter_config[i].count);
-	}
-
-	return 0;
-}
-
-static void inline __xsc1_check_ctrs(void)
-{
-	int i;
-	u32 pmnc = read_pmnc();
-
-	/* NOTE: there's an A stepping errata that states if an overflow */
-	/*       bit already exists and another occurs, the previous     */
-	/*       Overflow bit gets cleared. There's no workaround.	 */
-	/*	 Fixed in B stepping or later			 	 */
-
-	/* Write the value back to clear the overflow flags. Overflow */
-	/* flags remain in pmnc for use below */
-	write_pmnc(pmnc & ~PMU_ENABLE);
-
-	for (i = CCNT; i <= PMN1; i++) {
-		if (!(pmu->int_mask[i] & pmu->int_enable))
-			continue;
-
-		if (pmnc & pmu->cnt_ovf[i])
-			results[i].ovf++;
-	}
-}
-
-static void inline __xsc2_check_ctrs(void)
-{
-	int i;
-	u32 flag = 0, pmnc = read_pmnc();
-
-	pmnc &= ~PMU_ENABLE;
-	write_pmnc(pmnc);
-
-	/* read overflow flag register */
-	__asm__ __volatile__ ("mrc p14, 0, %0, c5, c1, 0" : "=r" (flag));
-
-	for (i = CCNT; i <= PMN3; i++) {
-		if (!(pmu->int_mask[i] & pmu->int_enable))
-			continue;
-
-		if (flag & pmu->cnt_ovf[i])
-			results[i].ovf++;
-	}
-
-	/* writeback clears overflow bits */
-	__asm__ __volatile__ ("mcr p14, 0, %0, c5, c1, 0" : : "r" (flag));
-}
-
-static irqreturn_t xscale_pmu_interrupt(int irq, void *arg)
-{
-	int i;
-	u32 pmnc;
-
-	if (pmu->id == PMU_XSC1)
-		__xsc1_check_ctrs();
-	else
-		__xsc2_check_ctrs();
-
-	for (i = CCNT; i < MAX_COUNTERS; i++) {
-		if (!results[i].ovf)
-			continue;
-
-		write_counter(i, -(u32)results[i].reset_counter);
-		oprofile_add_sample(get_irq_regs(), i);
-		results[i].ovf--;
-	}
-
-	pmnc = read_pmnc() | PMU_ENABLE;
-	write_pmnc(pmnc);
-
-	return IRQ_HANDLED;
-}
-
-static const struct pmu_irqs *pmu_irqs;
-
-static void xscale_pmu_stop(void)
-{
-	u32 pmnc = read_pmnc();
-
-	pmnc &= ~PMU_ENABLE;
-	write_pmnc(pmnc);
-
-	free_irq(pmu_irqs->irqs[0], results);
-	release_pmu(pmu_irqs);
-	pmu_irqs = NULL;
-}
-
-static int xscale_pmu_start(void)
-{
-	int ret;
-	u32 pmnc;
-
-	pmu_irqs = reserve_pmu();
-	if (IS_ERR(pmu_irqs))
-		return PTR_ERR(pmu_irqs);
-
-	pmnc = read_pmnc();
-
-	ret = request_irq(pmu_irqs->irqs[0], xscale_pmu_interrupt,
-			  IRQF_DISABLED, "XScale PMU", (void *)results);
-
-	if (ret < 0) {
-		printk(KERN_ERR "oprofile: unable to request IRQ%d for XScale PMU\n",
-		       pmu_irqs->irqs[0]);
-		release_pmu(pmu_irqs);
-		pmu_irqs = NULL;
-		return ret;
-	}
-
-	if (pmu->id == PMU_XSC1)
-		pmnc |= pmu->int_enable;
-	else {
-		__asm__ __volatile__ ("mcr p14, 0, %0, c4, c1, 0" : : "r" (pmu->int_enable));
-		pmnc &= ~PMU_CNT64;
-	}
-
-	pmnc |= PMU_ENABLE;
-	write_pmnc(pmnc);
-	pr_debug("xscale_pmu_start: pmnc: %#08x mask: %08x\n", pmnc, pmu->int_enable);
-	return 0;
-}
-
-static int xscale_detect_pmu(void)
-{
-	int ret = 0;
-	u32 id;
-
-	id = (read_cpuid(CPUID_ID) >> 13) & 0x7;
-
-	switch (id) {
-	case 1:
-		pmu = &pmu_parms[PMU_XSC1];
-		break;
-	case 2:
-		pmu = &pmu_parms[PMU_XSC2];
-		break;
-	default:
-		ret = -ENODEV;
-		break;
-	}
-
-	if (!ret) {
-		op_xscale_spec.name = pmu->name;
-		op_xscale_spec.num_counters = pmu->num_counters;
-		pr_debug("xscale_detect_pmu: detected %s PMU\n", pmu->name);
-	}
-
-	return ret;
-}
-
-struct op_arm_model_spec op_xscale_spec = {
-	.init		= xscale_detect_pmu,
-	.setup_ctrs	= xscale_setup_ctrs,
-	.start		= xscale_pmu_start,
-	.stop		= xscale_pmu_stop,
-};
-
diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile
index 36bff03..69b09c1 100644
--- a/arch/arm/plat-iop/Makefile
+++ b/arch/arm/plat-iop/Makefile
@@ -13,6 +13,7 @@
 obj-$(CONFIG_ARCH_IOP32X) += io.o
 obj-$(CONFIG_ARCH_IOP32X) += cp6.o
 obj-$(CONFIG_ARCH_IOP32X) += adma.o
+obj-$(CONFIG_ARCH_IOP32X) += pmu.o
 
 # IOP33X
 obj-$(CONFIG_ARCH_IOP33X) += gpio.o
@@ -23,6 +24,7 @@
 obj-$(CONFIG_ARCH_IOP33X) += io.o
 obj-$(CONFIG_ARCH_IOP33X) += cp6.o
 obj-$(CONFIG_ARCH_IOP33X) += adma.o
+obj-$(CONFIG_ARCH_IOP33X) += pmu.o
 
 # IOP13XX
 obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
diff --git a/arch/arm/plat-iop/pmu.c b/arch/arm/plat-iop/pmu.c
new file mode 100644
index 0000000..a2024b8
--- /dev/null
+++ b/arch/arm/plat-iop/pmu.c
@@ -0,0 +1,40 @@
+/*
+ * PMU IRQ registration for the iop3xx xscale PMU families.
+ * 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 <linux/platform_device.h>
+#include <asm/pmu.h>
+#include <mach/irqs.h>
+
+static struct resource pmu_resource = {
+#ifdef CONFIG_ARCH_IOP32X
+	.start	= IRQ_IOP32X_CORE_PMU,
+	.end	= IRQ_IOP32X_CORE_PMU,
+#endif
+#ifdef CONFIG_ARCH_IOP33X
+	.start	= IRQ_IOP33X_CORE_PMU,
+	.end	= IRQ_IOP33X_CORE_PMU,
+#endif
+	.flags	= IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+	.name		= "arm-pmu",
+	.id		= ARM_PMU_DEVICE_CPU,
+	.resource	= &pmu_resource,
+	.num_resources	= 1,
+};
+
+static int __init iop3xx_pmu_init(void)
+{
+	platform_device_register(&pmu_device);
+	return 0;
+}
+
+arch_initcall(iop3xx_pmu_init);
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
index 159daf5..5da3f97 100644
--- a/arch/arm/plat-nomadik/Kconfig
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -19,4 +19,9 @@
 	  to multiple interrupt generating programmable
 	  32-bit free running decrementing counters.
 
+config NOMADIK_GPIO
+	bool
+	help
+	  Support for the Nomadik GPIO controller.
+
 endif
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile
index 37c7cdd..c335473 100644
--- a/arch/arm/plat-nomadik/Makefile
+++ b/arch/arm/plat-nomadik/Makefile
@@ -3,3 +3,4 @@
 # Licensed under GPLv2
 
 obj-$(CONFIG_HAS_MTU)	+= timer.o
+obj-$(CONFIG_NOMADIK_GPIO)	+= gpio.o
diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
similarity index 74%
rename from arch/arm/mach-nomadik/gpio.c
rename to arch/arm/plat-nomadik/gpio.c
index 66b1c91..5a6ef25 100644
--- a/arch/arm/mach-nomadik/gpio.c
+++ b/arch/arm/plat-nomadik/gpio.c
@@ -13,8 +13,10 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
-#include <linux/amba/bus.h>
+#include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
@@ -36,8 +38,9 @@
 struct nmk_gpio_chip {
 	struct gpio_chip chip;
 	void __iomem *addr;
+	struct clk *clk;
 	unsigned int parent_irq;
-	spinlock_t *lock;
+	spinlock_t lock;
 	/* Keep track of configured edges */
 	u32 edge_rising;
 	u32 edge_falling;
@@ -108,12 +111,37 @@
 	writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
 }
 
-static void nmk_gpio_irq_mask(unsigned int irq)
+static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
+				  int gpio, bool enable)
+{
+	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);
+		if (enable)
+			reg |= bitmask;
+		else
+			reg &= ~bitmask;
+		writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC);
+	}
+	if (nmk_chip->edge_falling & bitmask) {
+		reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC);
+		if (enable)
+			reg |= bitmask;
+		else
+			reg &= ~bitmask;
+		writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC);
+	}
+}
+
+static void nmk_gpio_irq_modify(unsigned int irq, bool enable)
 {
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 	unsigned long flags;
-	u32 bitmask, reg;
+	u32 bitmask;
 
 	gpio = NOMADIK_IRQ_TO_GPIO(irq);
 	nmk_chip = get_irq_chip_data(irq);
@@ -121,51 +149,24 @@
 	if (!nmk_chip)
 		return;
 
-	/* we must individually clear the two edges */
 	spin_lock_irqsave(&nmk_chip->lock, flags);
-	if (nmk_chip->edge_rising & bitmask) {
-		reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
-		reg &= ~bitmask;
-		writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
-	}
-	if (nmk_chip->edge_falling & bitmask) {
-		reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
-		reg &= ~bitmask;
-		writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
-	}
+	__nmk_gpio_irq_modify(nmk_chip, gpio, enable);
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+}
+
+static void nmk_gpio_irq_mask(unsigned int irq)
+{
+	nmk_gpio_irq_modify(irq, false);
 };
 
 static void nmk_gpio_irq_unmask(unsigned int irq)
 {
-	int gpio;
-	struct nmk_gpio_chip *nmk_chip;
-	unsigned long flags;
-	u32 bitmask, reg;
-
-	gpio = NOMADIK_IRQ_TO_GPIO(irq);
-	nmk_chip = get_irq_chip_data(irq);
-	bitmask = nmk_gpio_get_bitmask(gpio);
-	if (!nmk_chip)
-		return;
-
-	/* we must individually set the two edges */
-	spin_lock_irqsave(&nmk_chip->lock, flags);
-	if (nmk_chip->edge_rising & bitmask) {
-		reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
-		reg |= bitmask;
-		writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
-	}
-	if (nmk_chip->edge_falling & bitmask) {
-		reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
-		reg |= bitmask;
-		writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
-	}
-	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+	nmk_gpio_irq_modify(irq, true);
 }
 
 static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
 {
+	bool enabled = !(irq_to_desc(irq)->status & IRQ_DISABLED);
 	int gpio;
 	struct nmk_gpio_chip *nmk_chip;
 	unsigned long flags;
@@ -184,20 +185,22 @@
 
 	spin_lock_irqsave(&nmk_chip->lock, flags);
 
+	if (enabled)
+		__nmk_gpio_irq_modify(nmk_chip, gpio, false);
+
 	nmk_chip->edge_rising &= ~bitmask;
 	if (type & IRQ_TYPE_EDGE_RISING)
 		nmk_chip->edge_rising |= bitmask;
-	writel(nmk_chip->edge_rising, nmk_chip->addr + NMK_GPIO_RIMSC);
 
 	nmk_chip->edge_falling &= ~bitmask;
 	if (type & IRQ_TYPE_EDGE_FALLING)
 		nmk_chip->edge_falling |= bitmask;
-	writel(nmk_chip->edge_falling, nmk_chip->addr + NMK_GPIO_FIMSC);
+
+	if (enabled)
+		__nmk_gpio_irq_modify(nmk_chip, gpio, true);
 
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
 
-	nmk_gpio_irq_unmask(irq);
-
 	return 0;
 }
 
@@ -212,21 +215,27 @@
 static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
 	struct nmk_gpio_chip *nmk_chip;
-	struct irq_chip *host_chip;
+	struct irq_chip *host_chip = get_irq_chip(irq);
 	unsigned int gpio_irq;
 	u32 pending;
 	unsigned int first_irq;
 
+	if (host_chip->mask_ack)
+		host_chip->mask_ack(irq);
+	else {
+		host_chip->mask(irq);
+		if (host_chip->ack)
+			host_chip->ack(irq);
+	}
+
 	nmk_chip = get_irq_data(irq);
 	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
 	while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
 		gpio_irq = first_irq + __ffs(pending);
 		generic_handle_irq(gpio_irq);
 	}
-	if (0) {/* don't ack parent irq, as ack == disable */
-		host_chip = get_irq_chip(irq);
-		host_chip->ack(irq);
-	}
+
+	host_chip->unmask(irq);
 }
 
 static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
@@ -240,6 +249,7 @@
 		set_irq_handler(i, handle_edge_irq);
 		set_irq_flags(i, IRQF_VALID);
 		set_irq_chip_data(i, nmk_chip);
+		set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
 	}
 	set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
 	set_irq_data(nmk_chip->parent_irq, nmk_chip);
@@ -298,30 +308,59 @@
 	.can_sleep		= 0,
 };
 
-static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id)
+static int __init nmk_gpio_probe(struct platform_device *dev)
 {
-	struct nmk_gpio_platform_data *pdata;
+	struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
 	struct nmk_gpio_chip *nmk_chip;
 	struct gpio_chip *chip;
+	struct resource *res;
+	struct clk *clk;
+	int irq;
 	int ret;
 
-	pdata = dev->dev.platform_data;
-	ret = amba_request_regions(dev, pdata->name);
-	if (ret)
-		return ret;
+	if (!pdata)
+		return -ENODEV;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENOENT;
+		goto out;
+	}
+
+	irq = platform_get_irq(dev, 0);
+	if (irq < 0) {
+		ret = irq;
+		goto out;
+	}
+
+	if (request_mem_region(res->start, resource_size(res),
+			       dev_name(&dev->dev)) == NULL) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	clk = clk_get(&dev->dev, NULL);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		goto out_release;
+	}
+
+	clk_enable(clk);
 
 	nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
 	if (!nmk_chip) {
 		ret = -ENOMEM;
-		goto out_amba;
+		goto out_clk;
 	}
 	/*
 	 * The virt address in nmk_chip->addr is in the nomadik register space,
 	 * so we can simply convert the resource address, without remapping
 	 */
-	nmk_chip->addr = io_p2v(dev->res.start);
+	nmk_chip->clk = clk;
+	nmk_chip->addr = io_p2v(res->start);
 	nmk_chip->chip = nmk_gpio_template;
-	nmk_chip->parent_irq = pdata->parent_irq;
+	nmk_chip->parent_irq = irq;
+	spin_lock_init(&nmk_chip->lock);
 
 	chip = &nmk_chip->chip;
 	chip->base = pdata->first_gpio;
@@ -333,7 +372,7 @@
 	if (ret)
 		goto out_free;
 
-	amba_set_drvdata(dev, nmk_chip);
+	platform_set_drvdata(dev, nmk_chip);
 
 	nmk_gpio_init_irq(nmk_chip);
 
@@ -341,51 +380,50 @@
 		 nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
 	return 0;
 
- out_free:
+out_free:
 	kfree(nmk_chip);
- out_amba:
-	amba_release_regions(dev);
+out_clk:
+	clk_disable(clk);
+	clk_put(clk);
+out_release:
+	release_mem_region(res->start, resource_size(res));
+out:
 	dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
 		  pdata->first_gpio, pdata->first_gpio+31);
 	return ret;
 }
 
-static int nmk_gpio_remove(struct amba_device *dev)
+static int __exit nmk_gpio_remove(struct platform_device *dev)
 {
 	struct nmk_gpio_chip *nmk_chip;
+	struct resource *res;
 
-	nmk_chip = amba_get_drvdata(dev);
+	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);
-	amba_release_regions(dev);
+	release_mem_region(res->start, resource_size(res));
 	return 0;
 }
 
 
-/* We have 0x1f080060 and 0x1f180060, accept both using the mask */
-static struct amba_id nmk_gpio_ids[] = {
-	{
-		.id	= 0x1f080060,
-		.mask	= 0xffefffff,
-	},
-	{0, 0},
-};
-
-static struct amba_driver nmk_gpio_driver = {
-	.drv = {
+static struct platform_driver nmk_gpio_driver = {
+	.driver = {
 		.owner = THIS_MODULE,
 		.name = "gpio",
 		},
 	.probe = nmk_gpio_probe,
-	.remove = nmk_gpio_remove,
+	.remove = __exit_p(nmk_gpio_remove),
 	.suspend = NULL, /* to be done */
 	.resume = NULL,
-	.id_table = nmk_gpio_ids,
 };
 
 static int __init nmk_gpio_init(void)
 {
-	return amba_driver_register(&nmk_gpio_driver);
+	return platform_driver_register(&nmk_gpio_driver);
 }
 
 arch_initcall(nmk_gpio_init);
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h
new file mode 100644
index 0000000..4200811
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/gpio.h
@@ -0,0 +1,70 @@
+/*
+ * Structures and registers for GPIO access in the Nomadik SoC
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ *     Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ *
+ * 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_PLAT_GPIO_H
+#define __ASM_PLAT_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+/*
+ * These currently cause a function call to happen, they may be optimized
+ * if needed by adding cpu-specific defines to identify blocks
+ * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
+ */
+#define gpio_get_value  __gpio_get_value
+#define gpio_set_value  __gpio_set_value
+#define gpio_cansleep   __gpio_cansleep
+#define gpio_to_irq     __gpio_to_irq
+
+/*
+ * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
+ * the "gpio" namespace for generic and cross-machine functions
+ */
+
+/* Register in the logic block */
+#define NMK_GPIO_DAT	0x00
+#define NMK_GPIO_DATS	0x04
+#define NMK_GPIO_DATC	0x08
+#define NMK_GPIO_PDIS	0x0c
+#define NMK_GPIO_DIR	0x10
+#define NMK_GPIO_DIRS	0x14
+#define NMK_GPIO_DIRC	0x18
+#define NMK_GPIO_SLPC	0x1c
+#define NMK_GPIO_AFSLA	0x20
+#define NMK_GPIO_AFSLB	0x24
+
+#define NMK_GPIO_RIMSC	0x40
+#define NMK_GPIO_FIMSC	0x44
+#define NMK_GPIO_IS	0x48
+#define NMK_GPIO_IC	0x4c
+#define NMK_GPIO_RWIMSC	0x50
+#define NMK_GPIO_FWIMSC	0x54
+#define NMK_GPIO_WKS	0x58
+
+/* Alternate functions: function C is set in hw by setting both A and B */
+#define NMK_GPIO_ALT_GPIO	0
+#define NMK_GPIO_ALT_A	1
+#define NMK_GPIO_ALT_B	2
+#define NMK_GPIO_ALT_C	(NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+
+extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
+extern int nmk_gpio_get_mode(int gpio);
+
+/*
+ * Platform data to register a block: only the initial gpio/irq number.
+ */
+struct nmk_gpio_platform_data {
+	char *name;
+	int first_gpio;
+	int first_irq;
+};
+
+#endif /* __ASM_PLAT_GPIO_H */
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index fa7cb3a..0ff3798 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -2,7 +2,7 @@
  *  linux/arch/arm/mach-nomadik/timer.c
  *
  * Copyright (C) 2008 STMicroelectronics
- * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
+ * Copyright (C) 2010 Alessandro Rubini
  *
  * 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
@@ -18,123 +18,150 @@
 
 #include <plat/mtu.h>
 
-static u32	nmdk_count;		/* accumulated count */
-static u32	nmdk_cycle;		/* write-once */
-
-/* setup by the platform code */
-void __iomem *mtu_base;
+void __iomem *mtu_base; /* ssigned by machine code */
 
 /*
- * clocksource: the MTU device is a decrementing counters, so we negate
- * the value being read.
+ * Kernel assumes that sched_clock can be called early
+ * but the MTU may not yet be initialized.
  */
+static cycle_t nmdk_read_timer_dummy(struct clocksource *cs)
+{
+	return 0;
+}
+
+/* clocksource: MTU decrements, so we negate the value being read. */
 static cycle_t nmdk_read_timer(struct clocksource *cs)
 {
-	u32 count = readl(mtu_base + MTU_VAL(0));
-	return nmdk_count + nmdk_cycle - count;
-
+	return -readl(mtu_base + MTU_VAL(0));
 }
 
 static struct clocksource nmdk_clksrc = {
 	.name		= "mtu_0",
-	.rating		= 120,
-	.read		= nmdk_read_timer,
+	.rating		= 200,
+	.read		= nmdk_read_timer_dummy,
+	.mask		= CLOCKSOURCE_MASK(32),
 	.shift		= 20,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 /*
- * Clockevent device: currently only periodic mode is supported
+ * Override the global weak sched_clock symbol with this
+ * local implementation which uses the clocksource to get some
+ * better resolution when scheduling the kernel. We accept that
+ * this wraps around for now, since it is just a relative time
+ * stamp. (Inspired by OMAP implementation.)
  */
+unsigned long long notrace sched_clock(void)
+{
+	return clocksource_cyc2ns(nmdk_clksrc.read(
+				  &nmdk_clksrc),
+				  nmdk_clksrc.mult,
+				  nmdk_clksrc.shift);
+}
+
+/* Clockevent device: use one-shot mode */
 static void nmdk_clkevt_mode(enum clock_event_mode mode,
 			     struct clock_event_device *dev)
 {
+	u32 cr;
+
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		/* count current value? */
-		writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
+		pr_err("%s: periodic mode not supported\n", __func__);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
-		BUG(); /* Not supported, yet */
-		/* FALLTHROUGH */
+		/* Load highest value, enable device, enable interrupts */
+		cr = readl(mtu_base + MTU_CR(1));
+		writel(0, mtu_base + MTU_LR(1));
+		writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1));
+		writel(0x2, mtu_base + MTU_IMSC);
+		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	case CLOCK_EVT_MODE_UNUSED:
-		writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
+		/* disable irq */
+		writel(0, mtu_base + MTU_IMSC);
 		break;
 	case CLOCK_EVT_MODE_RESUME:
 		break;
 	}
 }
 
+static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
+{
+	/* writing the value has immediate effect */
+	writel(evt, mtu_base + MTU_LR(1));
+	return 0;
+}
+
 static struct clock_event_device nmdk_clkevt = {
-	.name		= "mtu_0",
-	.features	= CLOCK_EVT_FEAT_PERIODIC,
+	.name		= "mtu_1",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
 	.shift		= 32,
-	.rating		= 100,
+	.rating		= 200,
 	.set_mode	= nmdk_clkevt_mode,
+	.set_next_event	= nmdk_clkevt_next,
 };
 
 /*
- * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
- * as we are the only users of mtu0 by now.
+ * IRQ Handler for timer 1 of the MTU block.
  */
 static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
 {
-	/* ack: "interrupt clear register" */
-	writel(1 << 0, mtu_base + MTU_ICR);
+	struct clock_event_device *evdev = dev_id;
 
-	/* we can't count lost ticks, unfortunately */
-	nmdk_count += nmdk_cycle;
-	nmdk_clkevt.event_handler(&nmdk_clkevt);
-
+	writel(1 << 1, mtu_base + MTU_ICR); /* Interrupt clear reg */
+	evdev->event_handler(evdev);
 	return IRQ_HANDLED;
 }
 
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
 static struct irqaction nmdk_timer_irq = {
 	.name		= "Nomadik Timer Tick",
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
 	.handler	= nmdk_timer_interrupt,
+	.dev_id		= &nmdk_clkevt,
 };
 
-static void nmdk_timer_reset(void)
-{
-	u32 cr;
-
-	writel(0, mtu_base + MTU_CR(0)); /* off */
-
-	/* configure load and background-load, and fire it up */
-	writel(nmdk_cycle, mtu_base + MTU_LR(0));
-	writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
-	cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
-	writel(cr, mtu_base + MTU_CR(0));
-	writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
-}
-
 void __init nmdk_timer_init(void)
 {
 	unsigned long rate;
-	int bits;
+	u32 cr = MTU_CRn_32BITS;;
 
-	rate = CLOCK_TICK_RATE; /* 2.4MHz */
-	nmdk_cycle = (rate + HZ/2) / HZ;
+	/*
+	 * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500:
+	 * use a divide-by-16 counter if it's more than 16MHz
+	 */
+	rate = CLOCK_TICK_RATE;
+	if (rate > 16 << 20) {
+		rate /= 16;
+		cr |= MTU_CRn_PRESCALE_16;
+	} else {
+		cr |= MTU_CRn_PRESCALE_1;
+	}
 
-	/* Init the timer and register clocksource */
-	nmdk_timer_reset();
+	/* Timer 0 is the free running clocksource */
+	writel(cr, mtu_base + MTU_CR(0));
+	writel(0, mtu_base + MTU_LR(0));
+	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);
-	bits =  8*sizeof(nmdk_count);
-	nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
+	/* Now the scheduling clock is ready */
+	nmdk_clksrc.read = nmdk_read_timer;
 
 	if (clocksource_register(&nmdk_clksrc))
-		printk(KERN_ERR "timer: failed to initialize clock "
-			"source %s\n", nmdk_clksrc.name);
+		pr_err("timer: failed to initialize clock source %s\n",
+		       nmdk_clksrc.name);
+
+	/* Timer 1 is used for events, fix according to rate */
+	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 =
+		clockevent_delta2ns(0x00000002, &nmdk_clkevt);
+	nmdk_clkevt.cpumask	= cpumask_of(0);
 
 	/* Register irq and clockevents */
 	setup_irq(IRQ_MTU0, &nmdk_timer_irq);
-	nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
-	nmdk_clkevt.cpumask = cpumask_of(0);
 	clockevents_register_device(&nmdk_clkevt);
 }
diff --git a/arch/arm/plat-pxa/Kconfig b/arch/arm/plat-pxa/Kconfig
index b158e98..da53395 100644
--- a/arch/arm/plat-pxa/Kconfig
+++ b/arch/arm/plat-pxa/Kconfig
@@ -1,3 +1,8 @@
 if PLAT_PXA
 
+config PXA_SSP
+	tristate
+	help
+	  Enable support for PXA2xx SSP ports
+
 endif
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
index 0264bfb..6187edf 100644
--- a/arch/arm/plat-pxa/Makefile
+++ b/arch/arm/plat-pxa/Makefile
@@ -2,10 +2,11 @@
 # Makefile for code common across different PXA processor families
 #
 
-obj-y	:= dma.o
+obj-y	:= dma.o pmu.o
 
 obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
 obj-$(CONFIG_PXA3xx)		+= mfp.o
 obj-$(CONFIG_ARCH_MMP)		+= mfp.o
 
 obj-$(CONFIG_HAVE_PWM)		+= pwm.o
+obj-$(CONFIG_PXA_SSP)		+= ssp.o
diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h
index 857a683..9e604c8 100644
--- a/arch/arm/plat-pxa/include/plat/mfp.h
+++ b/arch/arm/plat-pxa/include/plat/mfp.h
@@ -316,6 +316,13 @@
 	MFP_PIN_PMIC_INT,
 	MFP_PIN_RDY,
 
+	/* additional pins on MMP2 */
+	MFP_PIN_TWSI1_SCL,
+	MFP_PIN_TWSI1_SDA,
+	MFP_PIN_TWSI4_SCL,
+	MFP_PIN_TWSI4_SDA,
+	MFP_PIN_CLK_REQ,
+
 	MFP_PIN_MAX,
 };
 
diff --git a/arch/arm/mach-pxa/include/mach/regs-ssp.h b/arch/arm/plat-pxa/include/plat/ssp.h
similarity index 74%
rename from arch/arm/mach-pxa/include/mach/regs-ssp.h
rename to arch/arm/plat-pxa/include/plat/ssp.h
index 6a2ed35..fe43150 100644
--- a/arch/arm/mach-pxa/include/mach/regs-ssp.h
+++ b/arch/arm/plat-pxa/include/plat/ssp.h
@@ -1,5 +1,26 @@
-#ifndef __ASM_ARCH_REGS_SSP_H
-#define __ASM_ARCH_REGS_SSP_H
+/*
+ *  ssp.h
+ *
+ *  Copyright (C) 2003 Russell King, 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.
+ *
+ * This driver supports the following PXA CPU/SSP ports:-
+ *
+ *       PXA250     SSP
+ *       PXA255     SSP, NSSP
+ *       PXA26x     SSP, NSSP, ASSP
+ *       PXA27x     SSP1, SSP2, SSP3
+ *       PXA3xx     SSP1, SSP2, SSP3, SSP4
+ */
+
+#ifndef __ASM_ARCH_SSP_H
+#define __ASM_ARCH_SSP_H
+
+#include <linux/list.h>
+#include <linux/io.h>
 
 /*
  * SSP Serial Port Registers
@@ -19,10 +40,7 @@
 #define SSRSA		(0x34)  /* SSP Rx Timeslot Active */
 #define SSTSS		(0x38)  /* SSP Timeslot Status */
 #define SSACD		(0x3C)  /* SSP Audio Clock Divider */
-
-#if defined(CONFIG_PXA3xx)
 #define SSACDD		(0x40)	/* SSP Audio Clock Dither Divider */
-#endif
 
 /* Common PXA2xx bits first */
 #define SSCR0_DSS	(0x0000000f)	/* Data Size Select (mask) */
@@ -33,29 +51,19 @@
 #define SSCR0_National	(0x2 << 4)	/* National Microwire */
 #define SSCR0_ECS	(1 << 6)	/* External clock select */
 #define SSCR0_SSE	(1 << 7)	/* Synchronous Serial Port Enable */
+#define SSCR0_SCR(x)	((x) << 8)	/* Serial Clock Rate (mask) */
 
-#if defined(CONFIG_PXA25x)
-#define SSCR0_SCR	(0x0000ff00)	/* Serial Clock Rate (mask) */
-#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */
-#elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-#define SSCR0_SCR	(0x000fff00)	/* Serial Clock Rate (mask) */
-#define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */
-#endif
-
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
+/* PXA27x, PXA3xx */
 #define SSCR0_EDSS	(1 << 20)	/* Extended data size select */
 #define SSCR0_NCS	(1 << 21)	/* Network clock select */
 #define SSCR0_RIM	(1 << 22)	/* Receive FIFO overrrun interrupt mask */
 #define SSCR0_TUM	(1 << 23)	/* Transmit FIFO underrun interrupt mask */
 #define SSCR0_FRDC	(0x07000000)	/* Frame rate divider control (mask) */
 #define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24)	/* Time slots per frame [1..8] */
+#define SSCR0_FPCKE	(1 << 29)	/* FIFO packing enable */
 #define SSCR0_ACS	(1 << 30)	/* Audio clock select */
 #define SSCR0_MOD	(1 << 31)	/* Mode (normal or network) */
-#endif
 
-#if defined(CONFIG_PXA3xx)
-#define SSCR0_FPCKE	(1 << 29)	/* FIFO packing enable */
-#endif
 
 #define SSCR1_RIE	(1 << 0)	/* Receive FIFO Interrupt Enable */
 #define SSCR1_TIE	(1 << 1)	/* Transmit FIFO Interrupt Enable */
@@ -75,10 +83,6 @@
 #define SSSR_RFS	(1 << 6)	/* Receive FIFO Service Request */
 #define SSSR_ROR	(1 << 7)	/* Receive FIFO Overrun */
 
-#define SSCR0_TIM		(1 << 23)	/* Transmit FIFO Under Run Interrupt Mask */
-#define SSCR0_RIM		(1 << 22)	/* Receive FIFO Over Run interrupt Mask */
-#define SSCR0_NCS		(1 << 21)	/* Network Clock Select */
-#define SSCR0_EDSS		(1 << 20)	/* Extended Data Size Select */
 
 /* extra bits in PXA255, PXA26x and PXA27x SSP ports */
 #define SSCR0_TISSP		(1 << 4)	/* TI Sync Serial Protocol */
@@ -108,27 +112,75 @@
 #define SSSR_TINT		(1 << 19)	/* Receiver Time-out Interrupt */
 #define SSSR_PINT		(1 << 18)	/* Peripheral Trailing Byte Interrupt */
 
-#if defined(CONFIG_PXA3xx)
-#define SSPSP_EDMYSTOP(x)	((x) << 28)     /* Extended Dummy Stop */
-#define SSPSP_EDMYSTRT(x)	((x) << 26)     /* Extended Dummy Start */
-#endif
 
-#define SSPSP_FSRT		(1 << 25)	/* Frame Sync Relative Timing */
-#define SSPSP_DMYSTOP(x)	((x) << 23)	/* Dummy Stop */
-#define SSPSP_SFRMWDTH(x)	((x) << 16)	/* Serial Frame Width */
-#define SSPSP_SFRMDLY(x)	((x) << 9)	/* Serial Frame Delay */
-#define SSPSP_DMYSTRT(x)	((x) << 7)	/* Dummy Start */
-#define SSPSP_STRTDLY(x)	((x) << 4)	/* Start Delay */
-#define SSPSP_ETDS		(1 << 3)	/* End of Transfer data State */
-#define SSPSP_SFRMP		(1 << 2)	/* Serial Frame Polarity */
 #define SSPSP_SCMODE(x)		((x) << 0)	/* Serial Bit Rate Clock Mode */
+#define SSPSP_SFRMP		(1 << 2)	/* Serial Frame Polarity */
+#define SSPSP_ETDS		(1 << 3)	/* End of Transfer data State */
+#define SSPSP_STRTDLY(x)	((x) << 4)	/* Start Delay */
+#define SSPSP_DMYSTRT(x)	((x) << 7)	/* Dummy Start */
+#define SSPSP_SFRMDLY(x)	((x) << 9)	/* Serial Frame Delay */
+#define SSPSP_SFRMWDTH(x)	((x) << 16)	/* Serial Frame Width */
+#define SSPSP_DMYSTOP(x)	((x) << 23)	/* Dummy Stop */
+#define SSPSP_FSRT		(1 << 25)	/* Frame Sync Relative Timing */
+
+/* PXA3xx */
+#define SSPSP_EDMYSTRT(x)	((x) << 26)     /* Extended Dummy Start */
+#define SSPSP_EDMYSTOP(x)	((x) << 28)     /* Extended Dummy Stop */
+#define SSPSP_TIMING_MASK	(0x7f8001f0)
 
 #define SSACD_SCDB		(1 << 3)	/* SSPSYSCLK Divider Bypass */
 #define SSACD_ACPS(x)		((x) << 4)	/* Audio clock PLL select */
 #define SSACD_ACDS(x)		((x) << 0)	/* Audio clock divider select */
-#if defined(CONFIG_PXA3xx)
 #define SSACD_SCDX8		(1 << 7)	/* SYSCLK division ratio select */
-#endif
 
+enum pxa_ssp_type {
+	SSP_UNDEFINED = 0,
+	PXA25x_SSP,  /* pxa 210, 250, 255, 26x */
+	PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
+	PXA27x_SSP,
+	PXA168_SSP,
+};
 
-#endif /* __ASM_ARCH_REGS_SSP_H */
+struct ssp_device {
+	struct platform_device *pdev;
+	struct list_head	node;
+
+	struct clk	*clk;
+	void __iomem	*mmio_base;
+	unsigned long	phys_base;
+
+	const char	*label;
+	int		port_id;
+	int		type;
+	int		use_count;
+	int		irq;
+	int		drcmr_rx;
+	int		drcmr_tx;
+};
+
+/**
+ * pxa_ssp_write_reg - Write to a SSP register
+ *
+ * @dev: SSP device to access
+ * @reg: Register to write to
+ * @val: Value to be written.
+ */
+static inline void pxa_ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val)
+{
+	__raw_writel(val, dev->mmio_base + reg);
+}
+
+/**
+ * pxa_ssp_read_reg - Read from a SSP register
+ *
+ * @dev: SSP device to access
+ * @reg: Register to read from
+ */
+static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg)
+{
+	return __raw_readl(dev->mmio_base + reg);
+}
+
+struct ssp_device *pxa_ssp_request(int port, const char *label);
+void pxa_ssp_free(struct ssp_device *);
+#endif /* __ASM_ARCH_SSP_H */
diff --git a/arch/arm/plat-pxa/mfp.c b/arch/arm/plat-pxa/mfp.c
index be58f9f..b77e018 100644
--- a/arch/arm/plat-pxa/mfp.c
+++ b/arch/arm/plat-pxa/mfp.c
@@ -110,6 +110,7 @@
 	MFPR_LPM_PULL_LOW,
 	MFPR_LPM_PULL_HIGH,
 	MFPR_LPM_FLOAT,
+	MFPR_LPM_INPUT,
 };
 
 /* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
diff --git a/arch/arm/plat-pxa/pmu.c b/arch/arm/plat-pxa/pmu.c
new file mode 100644
index 0000000..267ceb6
--- /dev/null
+++ b/arch/arm/plat-pxa/pmu.c
@@ -0,0 +1,33 @@
+/*
+ * PMU IRQ registration for the PXA xscale PMU families.
+ * 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 <linux/platform_device.h>
+#include <asm/pmu.h>
+#include <mach/irqs.h>
+
+static struct resource pmu_resource = {
+	.start	= IRQ_PMU,
+	.end	= IRQ_PMU,
+	.flags	= IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+	.name		= "arm-pmu",
+	.id		= ARM_PMU_DEVICE_CPU,
+	.resource	= &pmu_resource,
+	.num_resources	= 1,
+};
+
+static int __init pxa_pmu_init(void)
+{
+	platform_device_register(&pmu_device);
+	return 0;
+}
+arch_initcall(pxa_pmu_init);
diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c
new file mode 100644
index 0000000..c6357e5
--- /dev/null
+++ b/arch/arm/plat-pxa/ssp.c
@@ -0,0 +1,224 @@
+/*
+ *  linux/arch/arm/mach-pxa/ssp.c
+ *
+ *  based on linux/arch/arm/mach-sa1100/ssp.c by Russell King
+ *
+ *  Copyright (C) 2003 Russell King.
+ *  Copyright (C) 2003 Wolfson Microelectronics PLC
+ *
+ * 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.
+ *
+ *  PXA2xx SSP driver.  This provides the generic core for simple
+ *  IO-based SSP applications and allows easy port setup for DMA access.
+ *
+ *  Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <plat/ssp.h>
+
+static DEFINE_MUTEX(ssp_lock);
+static LIST_HEAD(ssp_list);
+
+struct ssp_device *pxa_ssp_request(int port, const char *label)
+{
+	struct ssp_device *ssp = NULL;
+
+	mutex_lock(&ssp_lock);
+
+	list_for_each_entry(ssp, &ssp_list, node) {
+		if (ssp->port_id == port && ssp->use_count == 0) {
+			ssp->use_count++;
+			ssp->label = label;
+			break;
+		}
+	}
+
+	mutex_unlock(&ssp_lock);
+
+	if (&ssp->node == &ssp_list)
+		return NULL;
+
+	return ssp;
+}
+EXPORT_SYMBOL(pxa_ssp_request);
+
+void pxa_ssp_free(struct ssp_device *ssp)
+{
+	mutex_lock(&ssp_lock);
+	if (ssp->use_count) {
+		ssp->use_count--;
+		ssp->label = NULL;
+	} else
+		dev_err(&ssp->pdev->dev, "device already free\n");
+	mutex_unlock(&ssp_lock);
+}
+EXPORT_SYMBOL(pxa_ssp_free);
+
+static int __devinit pxa_ssp_probe(struct platform_device *pdev)
+{
+	const struct platform_device_id *id = platform_get_device_id(pdev);
+	struct resource *res;
+	struct ssp_device *ssp;
+	int ret = 0;
+
+	ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL);
+	if (ssp == NULL) {
+		dev_err(&pdev->dev, "failed to allocate memory");
+		return -ENOMEM;
+	}
+	ssp->pdev = pdev;
+
+	ssp->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(ssp->clk)) {
+		ret = PTR_ERR(ssp->clk);
+		goto err_free;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no SSP RX DRCMR defined\n");
+		ret = -ENODEV;
+		goto err_free_clk;
+	}
+	ssp->drcmr_rx = res->start;
+
+	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no SSP TX DRCMR defined\n");
+		ret = -ENODEV;
+		goto err_free_clk;
+	}
+	ssp->drcmr_tx = res->start;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no memory resource defined\n");
+		ret = -ENODEV;
+		goto err_free_clk;
+	}
+
+	res = request_mem_region(res->start, resource_size(res),
+			pdev->name);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to request memory resource\n");
+		ret = -EBUSY;
+		goto err_free_clk;
+	}
+
+	ssp->phys_base = res->start;
+
+	ssp->mmio_base = ioremap(res->start, resource_size(res));
+	if (ssp->mmio_base == NULL) {
+		dev_err(&pdev->dev, "failed to ioremap() registers\n");
+		ret = -ENODEV;
+		goto err_free_mem;
+	}
+
+	ssp->irq = platform_get_irq(pdev, 0);
+	if (ssp->irq < 0) {
+		dev_err(&pdev->dev, "no IRQ resource defined\n");
+		ret = -ENODEV;
+		goto err_free_io;
+	}
+
+	/* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
+	 * starts from 0, do a translation here
+	 */
+	ssp->port_id = pdev->id + 1;
+	ssp->use_count = 0;
+	ssp->type = (int)id->driver_data;
+
+	mutex_lock(&ssp_lock);
+	list_add(&ssp->node, &ssp_list);
+	mutex_unlock(&ssp_lock);
+
+	platform_set_drvdata(pdev, ssp);
+	return 0;
+
+err_free_io:
+	iounmap(ssp->mmio_base);
+err_free_mem:
+	release_mem_region(res->start, resource_size(res));
+err_free_clk:
+	clk_put(ssp->clk);
+err_free:
+	kfree(ssp);
+	return ret;
+}
+
+static int __devexit pxa_ssp_remove(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct ssp_device *ssp;
+
+	ssp = platform_get_drvdata(pdev);
+	if (ssp == NULL)
+		return -ENODEV;
+
+	iounmap(ssp->mmio_base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	clk_put(ssp->clk);
+
+	mutex_lock(&ssp_lock);
+	list_del(&ssp->node);
+	mutex_unlock(&ssp_lock);
+
+	kfree(ssp);
+	return 0;
+}
+
+static const struct platform_device_id ssp_id_table[] = {
+	{ "pxa25x-ssp",		PXA25x_SSP },
+	{ "pxa25x-nssp",	PXA25x_NSSP },
+	{ "pxa27x-ssp",		PXA27x_SSP },
+	{ "pxa168-ssp",		PXA168_SSP },
+	{ },
+};
+
+static struct platform_driver pxa_ssp_driver = {
+	.probe		= pxa_ssp_probe,
+	.remove		= __devexit_p(pxa_ssp_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "pxa2xx-ssp",
+	},
+	.id_table	= ssp_id_table,
+};
+
+static int __init pxa_ssp_init(void)
+{
+	return platform_driver_register(&pxa_ssp_driver);
+}
+
+static void __exit pxa_ssp_exit(void)
+{
+	platform_driver_unregister(&pxa_ssp_driver);
+}
+
+arch_initcall(pxa_ssp_init);
+module_exit(pxa_ssp_exit);
+
+MODULE_DESCRIPTION("PXA SSP driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 6e93ef8..3ce8f01 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -9,6 +9,7 @@
 	select NO_IOPORT
 	select ARCH_REQUIRE_GPIOLIB
 	select S3C_DEVICE_NAND
+	select S3C_GPIO_CFG_S3C24XX
 	help
 	  Base platform code for any Samsung S3C24XX device
 
@@ -44,6 +45,12 @@
 	  Clock code for the S3C2410, and similar processors which
 	  is currently includes the S3C2410, S3C2440, S3C2442.
 
+config S3C2443_CLOCK
+	bool
+	help
+	  Clock code for the S3C2443 and similar processors, which includes
+	  the S3C2416 and S3C2450.
+
 config S3C24XX_DCLK
 	bool
 	help
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index c2237c4..44aea88 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -30,6 +30,7 @@
 obj-$(CONFIG_PM)		+= irq-pm.o
 obj-$(CONFIG_PM)		+= sleep.o
 obj-$(CONFIG_S3C2410_CLOCK)	+= s3c2410-clock.o
+obj-$(CONFIG_S3C2443_CLOCK)	+= s3c2443-clock.o
 obj-$(CONFIG_S3C2410_DMA)	+= dma.o
 obj-$(CONFIG_S3C2410_IOTIMING)	+= s3c2410-iotiming.o
 obj-$(CONFIG_S3C2412_IOTIMING)	+= s3c2412-iotiming.o
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index 9e0e20a..7b44d0c 100644
--- a/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -42,6 +42,7 @@
 #include <plat/nand.h>
 
 #include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
 
@@ -185,10 +186,10 @@
 {
 	/* Configure the LEDs (even if we have no LED support)*/
 
-	s3c2410_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
-	s3c2410_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
-	s3c2410_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
-	s3c2410_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
+	s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
 
 	s3c2410_gpio_setpin(S3C2410_GPF(4), 1);
 	s3c2410_gpio_setpin(S3C2410_GPF(5), 1);
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 9ca64df..76d0858 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -49,6 +49,7 @@
 #include <plat/s3c2400.h>
 #include <plat/s3c2410.h>
 #include <plat/s3c2412.h>
+#include <plat/s3c2416.h>
 #include <plat/s3c244x.h>
 #include <plat/s3c2443.h>
 
@@ -57,6 +58,7 @@
 static const char name_s3c2400[]  = "S3C2400";
 static const char name_s3c2410[]  = "S3C2410";
 static const char name_s3c2412[]  = "S3C2412";
+static const char name_s3c2416[]  = "S3C2416/S3C2450";
 static const char name_s3c2440[]  = "S3C2440";
 static const char name_s3c2442[]  = "S3C2442";
 static const char name_s3c2442b[]  = "S3C2442B";
@@ -137,6 +139,15 @@
 		.init		= s3c2412_init,
 		.name		= name_s3c2412,
 	},
+	{			/* a strange version of the s3c2416 */
+		.idcode		= 0x32450003,
+		.idmask		= 0xffffffff,
+		.map_io		= s3c2416_map_io,
+		.init_clocks	= s3c2416_init_clocks,
+		.init_uarts	= s3c2416_init_uarts,
+		.init		= s3c2416_init,
+		.name		= name_s3c2416,
+	},
 	{
 		.idcode		= 0x32443001,
 		.idmask		= 0xffffffff,
@@ -170,6 +181,16 @@
 
 static unsigned long s3c24xx_read_idcode_v5(void)
 {
+#if defined(CONFIG_CPU_S3C2416)
+	/* s3c2416 is v5, with S3C24XX_GSTATUS1 instead of S3C2412_GSTATUS1 */
+
+	u32 gs = __raw_readl(S3C24XX_GSTATUS1);
+
+	/* test for s3c2416 or similar device */
+	if ((gs >> 16) == 0x3245)
+		return gs;
+#endif
+
 #if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
 	return __raw_readl(S3C2412_GSTATUS1);
 #else
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
index 5467470..45126d3 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/gpio.c
  *
- * Copyright (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2004-2010 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C24XX GPIO support
@@ -20,12 +20,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
-
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/gpio.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
@@ -34,123 +34,34 @@
 
 #include <mach/regs-gpio.h>
 
-void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
-{
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long mask;
-	unsigned long con;
-	unsigned long flags;
-
-	if (pin < S3C2410_GPIO_BANKB) {
-		mask = 1 << S3C2410_GPIO_OFFSET(pin);
-	} else {
-		mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
-	}
-
-	switch (function) {
-	case S3C2410_GPIO_LEAVE:
-		mask = 0;
-		function = 0;
-		break;
-
-	case S3C2410_GPIO_INPUT:
-	case S3C2410_GPIO_OUTPUT:
-	case S3C2410_GPIO_SFN2:
-	case S3C2410_GPIO_SFN3:
-		if (pin < S3C2410_GPIO_BANKB) {
-			function -= 1;
-			function &= 1;
-			function <<= S3C2410_GPIO_OFFSET(pin);
-		} else {
-			function &= 3;
-			function <<= S3C2410_GPIO_OFFSET(pin)*2;
-		}
-	}
-
-	/* modify the specified register wwith IRQs off */
-
-	local_irq_save(flags);
-
-	con  = __raw_readl(base + 0x00);
-	con &= ~mask;
-	con |= function;
-
-	__raw_writel(con, base + 0x00);
-
-	local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
-
-unsigned int s3c2410_gpio_getcfg(unsigned int pin)
-{
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long val = __raw_readl(base);
-
-	if (pin < S3C2410_GPIO_BANKB) {
-		val >>= S3C2410_GPIO_OFFSET(pin);
-		val &= 1;
-		val += 1;
-	} else {
-		val >>= S3C2410_GPIO_OFFSET(pin)*2;
-		val &= 3;
-	}
-
-	return val | S3C2410_GPIO_INPUT;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getcfg);
+/* gpiolib wrappers until these are totally eliminated */
 
 void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
 {
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-	unsigned long flags;
-	unsigned long up;
+	int ret;
 
-	if (pin < S3C2410_GPIO_BANKB)
-		return;
+	WARN_ON(to);	/* should be none of these left */
 
-	local_irq_save(flags);
+	if (!to) {
+		/* if pull is enabled, try first with up, and if that
+		 * fails, try using down */
 
-	up = __raw_readl(base + 0x08);
-	up &= ~(1L << offs);
-	up |= to << offs;
-	__raw_writel(up, base + 0x08);
-
-	local_irq_restore(flags);
+		ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
+		if (ret)
+			s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
+	} else {
+		s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
+	}
 }
-
 EXPORT_SYMBOL(s3c2410_gpio_pullup);
 
-int s3c2410_gpio_getpull(unsigned int pin)
-{
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-
-	if (pin < S3C2410_GPIO_BANKB)
-		return -EINVAL;
-
-	return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getpull);
-
 void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
 {
-	void __iomem *base = S3C24XX_GPIO_BASE(pin);
-	unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-	unsigned long flags;
-	unsigned long dat;
+	/* do this via gpiolib until all users removed */
 
-	local_irq_save(flags);
-
-	dat = __raw_readl(base + 0x04);
-	dat &= ~(1 << offs);
-	dat |= to << offs;
-	__raw_writel(dat, base + 0x04);
-
-	local_irq_restore(flags);
+	gpio_request(pin, "temporary");
+	gpio_set_value(pin, to);
+	gpio_free(pin);
 }
 
 EXPORT_SYMBOL(s3c2410_gpio_setpin);
@@ -181,22 +92,3 @@
 }
 
 EXPORT_SYMBOL(s3c2410_modify_misccr);
-
-int s3c2410_gpio_getirq(unsigned int pin)
-{
-	if (pin < S3C2410_GPF(0) || pin > S3C2410_GPG(15))
-		return -EINVAL;	/* not valid interrupts */
-
-	if (pin < S3C2410_GPG(0) && pin > S3C2410_GPF(7))
-		return -EINVAL;	/* not valid pin */
-
-	if (pin < S3C2410_GPF(4))
-		return (pin - S3C2410_GPF(0)) + IRQ_EINT0;
-
-	if (pin < S3C2410_GPG(0))
-		return (pin - S3C2410_GPF(4)) + IRQ_EINT4;
-
-	return (pin - S3C2410_GPG(0)) + IRQ_EINT8;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
index 4f0f11a..4c0896f 100644
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/gpiolib.c
  *
- * Copyright (c) 2008 Simtec Electronics
+ * Copyright (c) 2008-2010 Simtec Electronics
  *	http://armlinux.simtec.co.uk/
  *	Ben Dooks <ben@simtec.co.uk>
  *
@@ -21,6 +21,8 @@
 #include <linux/gpio.h>
 
 #include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <plat/pm.h>
@@ -77,10 +79,21 @@
 	return IRQ_EINT8 + offset;
 }
 
+static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
+	.set_config	= s3c_gpio_setcfg_s3c24xx_a,
+	.get_config	= s3c_gpio_getcfg_s3c24xx_a,
+};
+
+struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
+	.set_config	= s3c_gpio_setcfg_s3c24xx,
+	.get_config	= s3c_gpio_getcfg_s3c24xx,
+};
+
 struct s3c_gpio_chip s3c24xx_gpios[] = {
 	[0] = {
 		.base	= S3C2410_GPACON,
 		.pm	= __gpio_pm(&s3c_gpio_pm_1bit),
+		.config	= &s3c24xx_gpiocfg_banka,
 		.chip	= {
 			.base			= S3C2410_GPA(0),
 			.owner			= THIS_MODULE,
@@ -161,15 +174,58 @@
 			.ngpio			= 11,
 		},
 	},
+		/* GPIOS for the S3C2443 and later devices. */
+	{
+		.base	= S3C2440_GPJCON,
+		.pm	= __gpio_pm(&s3c_gpio_pm_2bit),
+		.chip	= {
+			.base			= S3C2410_GPJ(0),
+			.owner			= THIS_MODULE,
+			.label			= "GPIOJ",
+			.ngpio			= 16,
+		},
+	}, {
+		.base	= S3C2443_GPKCON,
+		.pm	= __gpio_pm(&s3c_gpio_pm_2bit),
+		.chip	= {
+			.base			= S3C2410_GPK(0),
+			.owner			= THIS_MODULE,
+			.label			= "GPIOK",
+			.ngpio			= 16,
+		},
+	}, {
+		.base	= S3C2443_GPLCON,
+		.pm	= __gpio_pm(&s3c_gpio_pm_2bit),
+		.chip	= {
+			.base			= S3C2410_GPL(0),
+			.owner			= THIS_MODULE,
+			.label			= "GPIOL",
+			.ngpio			= 15,
+		},
+	}, {
+		.base	= S3C2443_GPMCON,
+		.pm	= __gpio_pm(&s3c_gpio_pm_2bit),
+		.chip	= {
+			.base			= S3C2410_GPM(0),
+			.owner			= THIS_MODULE,
+			.label			= "GPIOM",
+			.ngpio			= 2,
+		},
+	},
 };
 
+
 static __init int s3c24xx_gpiolib_init(void)
 {
 	struct s3c_gpio_chip *chip = s3c24xx_gpios;
 	int gpn;
 
-	for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++)
+	for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
+		if (!chip->config)
+			chip->config = &s3c24xx_gpiocfg_default;
+
 		s3c_gpiolib_add(chip);
+	}
 
 	return 0;
 }
diff --git a/arch/arm/plat-s3c24xx/include/plat/pll.h b/arch/arm/plat-s3c24xx/include/plat/pll.h
index 7ea8bff..005729a 100644
--- a/arch/arm/plat-s3c24xx/include/plat/pll.h
+++ b/arch/arm/plat-s3c24xx/include/plat/pll.h
@@ -35,3 +35,28 @@
 
 	return (unsigned int)fvco;
 }
+
+#define S3C2416_PLL_M_SHIFT	(14)
+#define S3C2416_PLL_P_SHIFT	(5)
+#define S3C2416_PLL_S_MASK	(7)
+#define S3C2416_PLL_M_MASK	((1 << 10) - 1)
+#define S3C2416_PLL_P_MASK	(63)
+
+static inline unsigned int
+s3c2416_get_pll(unsigned int pllval, unsigned int baseclk)
+{
+	unsigned int m, p, s;
+	uint64_t fvco;
+
+	m = pllval >> S3C2416_PLL_M_SHIFT;
+	p = pllval >> S3C2416_PLL_P_SHIFT;
+
+	s = pllval & S3C2416_PLL_S_MASK;
+	m &= S3C2416_PLL_M_MASK;
+	p &= S3C2416_PLL_P_MASK;
+
+	fvco = (uint64_t)baseclk * m;
+	do_div(fvco, (p << s));
+
+	return (unsigned int)fvco;
+}
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
new file mode 100644
index 0000000..dc3c090
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+ *
+ * Header file for s3c2416 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifdef CONFIG_CPU_S3C2416
+
+struct s3c2410_uartcfg;
+
+extern  int s3c2416_init(void);
+
+extern void s3c2416_map_io(void);
+
+extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2416_init_clocks(int xtal);
+
+extern  int s3c2416_baseclk_add(void);
+
+#else
+#define s3c2416_init_clocks NULL
+#define s3c2416_init_uarts NULL
+#define s3c2416_map_io NULL
+#define s3c2416_init NULL
+#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
index 815b107..a19715f 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
@@ -30,3 +30,22 @@
 #define s3c2443_map_io NULL
 #define s3c2443_init NULL
 #endif
+
+/* common code used by s3c2443 and others.
+ * note, not to be used outside of arch/arm/mach-s3c* */
+
+struct clk;	/* some files don't need clk.h otherwise */
+
+typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
+typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
+
+extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv);
+extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv);
+
+extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
+
+extern struct clksrc_clk clk_epllref;
+extern struct clksrc_clk clk_esysclk;
+extern struct clksrc_clk clk_msysclk;
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index 3620dd2..60627e6 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -43,6 +43,7 @@
 
 #include <asm/mach/time.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/pm.h>
 
 #define PFX "s3c24xx-pm: "
@@ -90,22 +91,22 @@
 {
 	unsigned long irqstate;
 	unsigned long pinstate;
-	int irq = s3c2410_gpio_getirq(pin);
+	int irq = gpio_to_irq(pin);
 
 	if (irqoffs < 4)
 		irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
 	else
 		irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
 
-	pinstate = s3c2410_gpio_getcfg(pin);
+	pinstate = s3c_gpio_getcfg(pin);
 
 	if (!irqstate) {
 		if (pinstate == S3C2410_GPIO_IRQ)
-			S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
+			S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
 	} else {
 		if (pinstate == S3C2410_GPIO_IRQ) {
 			S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
-			s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
+			s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
 		}
 	}
 }
diff --git a/arch/arm/plat-s3c24xx/s3c2410-clock.c b/arch/arm/plat-s3c24xx/s3c2410-clock.c
index b61bdb7..9ecc5d9 100644
--- a/arch/arm/plat-s3c24xx/s3c2410-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2410-clock.c
@@ -87,7 +87,7 @@
 
 /* standard clock definitions */
 
-static struct clk init_clocks_disable[] = {
+static struct clk init_clocks_off[] = {
 	{
 		.name		= "nand",
 		.id		= -1,
@@ -249,17 +249,8 @@
 
 	/* install (and disable) the clocks we do not need immediately */
 
-	clkp = init_clocks_disable;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-
-		s3c2410_clkcon_enable(clkp, 0);
-	}
+	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
 	/* show the clock-slow value */
 
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
new file mode 100644
index 0000000..461f070
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -0,0 +1,472 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2443-clock.c
+ *
+ * Copyright (c) 2007, 2010 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 Clock control suport - common code
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+
+
+static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
+{
+	u32 ctrlbit = clk->ctrlbit;
+	u32 con = __raw_readl(reg);
+
+	if (enable)
+		con |= ctrlbit;
+	else
+		con &= ~ctrlbit;
+
+	__raw_writel(con, reg);
+	return 0;
+}
+
+int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
+{
+	return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+{
+	return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+{
+	return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
+}
+
+/* mpllref is a direct descendant of clk_xtal by default, but it is not
+ * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
+ * such directly equating the two source clocks is impossible.
+ */
+struct clk clk_mpllref = {
+	.name		= "mpllref",
+	.parent		= &clk_xtal,
+	.id		= -1,
+};
+
+static struct clk *clk_epllref_sources[] = {
+	[0] = &clk_mpllref,
+	[1] = &clk_mpllref,
+	[2] = &clk_xtal,
+	[3] = &clk_ext,
+};
+
+struct clksrc_clk clk_epllref = {
+	.clk	= {
+		.name		= "epllref",
+		.id		= -1,
+	},
+	.sources = &(struct clksrc_sources) {
+		.sources = clk_epllref_sources,
+		.nr_sources = ARRAY_SIZE(clk_epllref_sources),
+	},
+	.reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
+};
+
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
+
+static struct clk *clk_sysclk_sources[] = {
+	[0] = &clk_epllref.clk,
+	[1] = &clk_epll,
+};
+
+struct clksrc_clk clk_esysclk = {
+	.clk	= {
+		.name		= "esysclk",
+		.parent		= &clk_epll,
+		.id		= -1,
+	},
+	.sources = &(struct clksrc_sources) {
+		.sources = clk_sysclk_sources,
+		.nr_sources = ARRAY_SIZE(clk_sysclk_sources),
+	},
+	.reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
+};
+
+static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	unsigned long div = __raw_readl(S3C2443_CLKDIV0);
+
+	div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
+	div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);	/* x2 */
+
+	return parent_rate / (div + 1);
+}
+
+static struct clk clk_mdivclk = {
+	.name		= "mdivclk",
+	.parent		= &clk_mpllref,
+	.id		= -1,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_mdivclk,
+	},
+};
+
+static struct clk *clk_msysclk_sources[] = {
+	[0] = &clk_mpllref,
+	[1] = &clk_mpll,
+	[2] = &clk_mdivclk,
+	[3] = &clk_mpllref,
+};
+
+struct clksrc_clk clk_msysclk = {
+	.clk	= {
+		.name		= "msysclk",
+		.parent		= &clk_xtal,
+		.id		= -1,
+	},
+	.sources = &(struct clksrc_sources) {
+		.sources = clk_msysclk_sources,
+		.nr_sources = ARRAY_SIZE(clk_msysclk_sources),
+	},
+	.reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
+};
+
+/* prediv
+ *
+ * this divides the msysclk down to pass to h/p/etc.
+ */
+
+static unsigned long s3c2443_prediv_getrate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+	clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+	clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+	return rate / (clkdiv0 + 1);
+}
+
+static struct clk clk_prediv = {
+	.name		= "prediv",
+	.id		= -1,
+	.parent		= &clk_msysclk.clk,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_prediv_getrate,
+	},
+};
+
+/* usbhost
+ *
+ * usb host bus-clock, usually 48MHz to provide USB bus clock timing
+*/
+
+static struct clksrc_clk clk_usb_bus_host = {
+	.clk	= {
+		.name		= "usb-bus-host-parent",
+		.id		= -1,
+		.parent		= &clk_esysclk.clk,
+		.ctrlbit	= S3C2443_SCLKCON_USBHOST,
+		.enable		= s3c2443_clkcon_enable_s,
+	},
+	.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
+};
+
+/* common clksrc clocks */
+
+static struct clksrc_clk clksrc_clks[] = {
+	{
+		/* ART baud-rate clock sourced from esysclk via a divisor */
+		.clk	= {
+			.name		= "uartclk",
+			.id		= -1,
+			.parent		= &clk_esysclk.clk,
+		},
+		.reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
+	}, {
+		/* camera interface bus-clock, divided down from esysclk */
+		.clk	= {
+			.name		= "camif-upll",	/* same as 2440 name */
+			.id		= -1,
+			.parent		= &clk_esysclk.clk,
+			.ctrlbit	= S3C2443_SCLKCON_CAMCLK,
+			.enable		= s3c2443_clkcon_enable_s,
+		},
+		.reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
+	}, {
+		.clk	= {
+			.name		= "display-if",
+			.id		= -1,
+			.parent		= &clk_esysclk.clk,
+			.ctrlbit	= S3C2443_SCLKCON_DISPCLK,
+			.enable		= s3c2443_clkcon_enable_s,
+		},
+		.reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
+	},
+};
+
+
+static struct clk init_clocks_off[] = {
+	{
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_ADC,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_IIC,
+	}
+};
+
+static struct clk init_clocks[] = {
+	{
+		.name		= "dma",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA0,
+	}, {
+		.name		= "dma",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA1,
+	}, {
+		.name		= "dma",
+		.id		= 2,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA2,
+	}, {
+		.name		= "dma",
+		.id		= 3,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA3,
+	}, {
+		.name		= "dma",
+		.id		= 4,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA4,
+	}, {
+		.name		= "dma",
+		.id		= 5,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_DMA5,
+	}, {
+		.name		= "hsmmc",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_HSMMC,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_GPIO,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_USBH,
+	}, {
+		.name		= "usb-device",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_USBD,
+	}, {
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_LCDC,
+
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_PWMT,
+	}, {
+		.name		= "cfc",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_CFC,
+	}, {
+		.name		= "ssmc",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c2443_clkcon_enable_h,
+		.ctrlbit	= S3C2443_HCLKCON_SSMC,
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART2,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_UART3,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c2443_clkcon_enable_p,
+		.ctrlbit	= S3C2443_PCLKCON_RTC,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.ctrlbit	= S3C2443_PCLKCON_WDT,
+	}, {
+		.name		= "ac97",
+		.id		= -1,
+		.parent		= &clk_p,
+		.ctrlbit	= S3C2443_PCLKCON_AC97,
+	}, {
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_h,
+	}, {
+		.name		= "usb-bus-host",
+		.id		= -1,
+		.parent		= &clk_usb_bus_host.clk,
+	}
+};
+
+static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
+{
+	clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
+
+	return clkcon0 + 1;
+}
+
+/* EPLLCON compatible enough to get on/off information */
+
+void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
+						   fdiv_fn get_fdiv)
+{
+	unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+	unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
+	unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+	struct clk *xtal_clk;
+	unsigned long xtal;
+	unsigned long pll;
+	unsigned long fclk;
+	unsigned long hclk;
+	unsigned long pclk;
+	int ptr;
+
+	xtal_clk = clk_get(NULL, "xtal");
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	pll = get_mpll(mpllcon, xtal);
+	clk_msysclk.clk.rate = pll;
+
+	fclk = pll / get_fdiv(clkdiv0);
+	hclk = s3c2443_prediv_getrate(&clk_prediv);
+	hclk /= s3c2443_get_hdiv(clkdiv0);
+	pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
+
+	s3c24xx_setup_clocks(fclk, hclk, pclk);
+
+	printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
+	       (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+	       print_mhz(pll), print_mhz(fclk),
+	       print_mhz(hclk), print_mhz(pclk));
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
+		s3c_set_clksrc(&clksrc_clks[ptr], true);
+
+	/* ensure usb bus clock is within correct rate of 48MHz */
+
+	if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
+		printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
+		clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
+	}
+
+	printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+	       (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+	       print_mhz(clk_get_rate(&clk_epll)),
+	       print_mhz(clk_get_rate(&clk_usb_bus)));
+}
+
+static struct clk *clks[] __initdata = {
+	&clk_prediv,
+	&clk_mpllref,
+	&clk_mdivclk,
+	&clk_ext,
+	&clk_epll,
+	&clk_usb_bus,
+};
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+	&clk_usb_bus_host,
+	&clk_epllref,
+	&clk_esysclk,
+	&clk_msysclk,
+};
+
+void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
+				       fdiv_fn get_fdiv)
+{
+	int ptr;
+
+	/* s3c2443 parents h and p clocks from prediv */
+	clk_h.parent = &clk_prediv;
+	clk_p.parent = &clk_prediv;
+
+	clk_usb_bus.parent = &clk_usb_bus_host.clk;
+	clk_epll.parent = &clk_epllref.clk;
+
+	s3c24xx_register_baseclocks(xtal);
+	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+		s3c_register_clksrc(clksrcs[ptr], 1);
+
+	s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
+	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+	/* See s3c2443/etc notes on disabling clocks at init time */
+	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+	s3c2443_common_setup_clocks(get_mpll, get_fdiv);
+}
diff --git a/arch/arm/plat-s3c24xx/setup-i2c.c b/arch/arm/plat-s3c24xx/setup-i2c.c
index 71a6acc..9e90a7c 100644
--- a/arch/arm/plat-s3c24xx/setup-i2c.c
+++ b/arch/arm/plat-s3c24xx/setup-i2c.c
@@ -15,12 +15,13 @@
 
 struct platform_device;
 
+#include <plat/gpio-cfg.h>
 #include <plat/iic.h>
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
-	s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
-	s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
+	s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
+	s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
 }
diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
index da7a617..9793544 100644
--- a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
+++ b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
@@ -21,16 +21,16 @@
 					  int enable)
 {
 	if (enable) {
-		s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
-		s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
-		s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
+		s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
+		s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
+		s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
 		s3c2410_gpio_pullup(S3C2410_GPE(11), 0);
 		s3c2410_gpio_pullup(S3C2410_GPE(13), 0);
 	} else {
-		s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
-		s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
-		s3c2410_gpio_pullup(S3C2410_GPE(11), 1);
-		s3c2410_gpio_pullup(S3C2410_GPE(12), 1);
-		s3c2410_gpio_pullup(S3C2410_GPE(13), 1);
+		s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
+		s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
+		s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
+		s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
+		s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
 	}
 }
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
index 89fcf53..db9e9e4 100644
--- a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
@@ -23,16 +23,16 @@
 
 	printk(KERN_INFO "%s(%d)\n", __func__, enable);
 	if (enable) {
-		s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
-		s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
-		s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
+		s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
+		s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
+		s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
 		s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
 		s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
 	} else {
-		s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
-		s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
-		s3c2410_gpio_pullup(S3C2410_GPD(10), 1);
-		s3c2410_gpio_pullup(S3C2410_GPD(9), 1);
-		s3c2410_gpio_pullup(S3C2410_GPD(8), 1);
+		s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
+		s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
+		s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
+		s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
+		s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
 	}
 }
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
index 86b9edc..8ea663a 100644
--- a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
@@ -21,16 +21,16 @@
 				       int enable)
 {
 	if (enable) {
-		s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
-		s3c2410_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
-		s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
+		s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
+		s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
+		s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
 		s3c2410_gpio_pullup(S3C2410_GPG(5), 0);
 		s3c2410_gpio_pullup(S3C2410_GPG(6), 0);
 	} else {
-		s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
-		s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
-		s3c2410_gpio_pullup(S3C2410_GPG(5), 1);
-		s3c2410_gpio_pullup(S3C2410_GPG(6), 1);
-		s3c2410_gpio_pullup(S3C2410_GPG(7), 1);
+		s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
+		s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
+		s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
+		s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
+		s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
 	}
 }
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 1b25c9d..8bf79f3 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -376,6 +376,21 @@
 	}
 }
 
+/**
+ * s3c_disable_clocks() - disable an array of clocks
+ * @clkp: Pointer to the first clock in the array.
+ * @nr_clks: Number of clocks to register.
+ *
+ * for internal use only at initialisation time. disable the clocks in the
+ * @clkp array.
+ */
+
+void __init s3c_disable_clocks(struct clk *clkp, int nr_clks)
+{
+	for (; nr_clks > 0; nr_clks--, clkp++)
+		(clkp->enable)(clkp, 0);
+}
+
 /* initalise all the clocks */
 
 int __init s3c24xx_register_baseclocks(unsigned long xtal)
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 44a84e8..3282db3 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -1,7 +1,7 @@
 /* linux/arch/arm/plat-s3c/gpio-config.c
  *
  * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
+ * Copyright 2008-2010 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	http://armlinux.simtec.co.uk/
  *
@@ -41,6 +41,26 @@
 }
 EXPORT_SYMBOL(s3c_gpio_cfgpin);
 
+unsigned s3c_gpio_getcfg(unsigned int pin)
+{
+	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+	unsigned long flags;
+	unsigned ret = 0;
+	int offset;
+
+	if (chip) {
+		offset = pin - chip->chip.base;
+
+		local_irq_save(flags);
+		ret = s3c_gpio_do_getcfg(chip, offset);
+		local_irq_restore(flags);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_getcfg);
+
+
 int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
 {
 	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
@@ -61,8 +81,8 @@
 EXPORT_SYMBOL(s3c_gpio_setpull);
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
-int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
-				  unsigned int off, unsigned int cfg)
+int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+			      unsigned int off, unsigned int cfg)
 {
 	void __iomem *reg = chip->base;
 	unsigned int shift = off;
@@ -87,6 +107,19 @@
 	return 0;
 }
 
+unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+				   unsigned int off)
+{
+	u32 con;
+
+	con = __raw_readl(chip->base);
+	con >>= off;
+	con &= 1;
+	con++;
+
+	return S3C_GPIO_SFN(con);
+}
+
 int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
 			    unsigned int off, unsigned int cfg)
 {
@@ -109,6 +142,19 @@
 
 	return 0;
 }
+
+unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
+				     unsigned int off)
+{
+	u32 con;
+
+	con = __raw_readl(chip->base);
+	con >>= off * 2;
+	con &= 3;
+
+	/* this conversion works for IN and OUT as well as special mode */
+	return S3C_GPIO_SPECIAL(con);
+}
 #endif
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
@@ -134,6 +180,25 @@
 
 	return 0;
 }
+
+unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+				      unsigned int off)
+{
+	void __iomem *reg = chip->base;
+	unsigned int shift = (off & 7) * 4;
+	u32 con;
+
+	if (off < 8 && chip->chip.ngpio > 8)
+		reg -= 4;
+
+	con = __raw_readl(reg);
+	con >>= shift;
+	con &= 0xf;
+
+	/* this conversion works for IN and OUT as well as special mode */
+	return S3C_GPIO_SPECIAL(con);
+}
+
 #endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
 
 #ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
@@ -164,3 +229,35 @@
 	return (__force s3c_gpio_pull_t)pup;
 }
 #endif
+
+#ifdef CONFIG_S3C_GPIO_PULL_UP
+int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+			 unsigned int off, s3c_gpio_pull_t pull)
+{
+	void __iomem *reg = chip->base + 0x08;
+	u32 pup = __raw_readl(reg);
+
+	pup = __raw_readl(reg);
+
+	if (pup == S3C_GPIO_PULL_UP)
+		pup &= ~(1 << off);
+	else if (pup == S3C_GPIO_PULL_NONE)
+		pup |= (1 << off);
+	else
+		return -EINVAL;
+
+	__raw_writel(pup, reg);
+	return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+				     unsigned int off)
+{
+	void __iomem *reg = chip->base + 0x08;
+	u32 pup = __raw_readl(reg);
+
+	pup &= (1 << off);
+	return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
+}
+#endif /* CONFIG_S3C_GPIO_PULL_UP */
+
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index 60b6269..12caf48 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -91,6 +91,7 @@
 extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
 
 extern void s3c_register_clocks(struct clk *clk, int nr_clks);
+extern void s3c_disable_clocks(struct clk *clkp, int nr_clks);
 
 extern int s3c24xx_register_baseclocks(unsigned long xtal);
 
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index d316b4a..5dbeb79 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -73,6 +73,7 @@
 extern struct sysdev_class s3c2410_sysclass;
 extern struct sysdev_class s3c2410a_sysclass;
 extern struct sysdev_class s3c2412_sysclass;
+extern struct sysdev_class s3c2416_sysclass;
 extern struct sysdev_class s3c2440_sysclass;
 extern struct sysdev_class s3c2442_sysclass;
 extern struct sysdev_class s3c2443_sysclass;
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index dda19da..3e21c75 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -30,6 +30,12 @@
 	return (chip->config->set_config)(chip, off, config);
 }
 
+static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip,
+					  unsigned int off)
+{
+	return (chip->config->get_config)(chip, off);
+}
+
 static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
 				      unsigned int off, s3c_gpio_pull_t pull)
 {
@@ -53,6 +59,18 @@
 				   unsigned int off, unsigned int cfg);
 
 /**
+ * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg
+ * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the
+ * S3C_GPIO_SPECIAL() macro.
+ */
+unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
+				     unsigned int off);
+
+/**
  * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
  * @chip: The gpio chip that is being configured.
  * @off: The offset for the GPIO being configured.
@@ -65,6 +83,21 @@
 extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
 				     unsigned int off, unsigned int cfg);
 
+
+/**
+ * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable
+ * GPIO configuration value.
+ *
+ * @sa s3c_gpio_getcfg_s3c24xx
+ * @sa s3c_gpio_getcfg_s3c64xx_4bit
+ */
+extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+					  unsigned int off);
+
 /**
  * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
  * @chip: The gpio chip that is being configured.
@@ -85,6 +118,20 @@
 					unsigned int off, unsigned int cfg);
 
 
+/**
+ * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration
+ * register setting into a value the software can use, such as could be passed
+ * to s3c_gpio_setcfg_s3c64xx_4bit().
+ *
+ * @sa s3c_gpio_getcfg_s3c24xx
+ */
+extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+					     unsigned int off);
+
 /* Pull-{up,down} resistor controls.
  *
  * S3C2410,S3C2440,S3C24A0 = Pull-UP,
@@ -146,6 +193,17 @@
 					       unsigned int off);
 
 /**
+ * s3c_gpio_getpull_1up() - Get configuration for choice of up or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-up resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_1up.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+					    unsigned int off);
+
+/**
  * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
  * @chip: The gpio chip that is being configured.
  * @off: The offset for the GPIO being configured.
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 29cd6a8..8d01e85 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -77,6 +77,17 @@
  */
 extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
 
+/**
+ * s3c_gpio_getcfg - Read the current function for a GPIO pin
+ * @pin: The pin to read the configuration value for.
+ *
+ * Read the configuration state of the given @pin, returning a value that
+ * could be passed back to s3c_gpio_cfgpin().
+ *
+ * @sa s3c_gpio_cfgpin
+ */
+extern unsigned s3c_gpio_getcfg(unsigned int pin);
+
 /* Define values for the pull-{up,down} available for each gpio pin.
  *
  * These values control the state of the weak pull-{up,down} resistors
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 49ff406..f0584f2 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -108,6 +108,9 @@
 extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
 extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
 
+/* exported for core SoC support to change */
+extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
+
 #ifdef CONFIG_S3C_GPIO_TRACK
 extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
 
diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h
new file mode 100644
index 0000000..b8b7e1d
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pll6553x.h
@@ -0,0 +1,51 @@
+/* arch/arm/plat-samsung/include/plat/pll6553x.h
+ *	partially from arch/arm/mach-s3c64xx/include/mach/pll.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * Samsung PLL6553x PLL code
+ *
+ * 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.
+*/
+
+/* S3C6400 and compatible (S3C2416, etc.) EPLL code */
+
+#define PLL6553X_MDIV_MASK	((1 << (23-16)) - 1)
+#define PLL6553X_PDIV_MASK	((1 << (13-8)) - 1)
+#define PLL6553X_SDIV_MASK	((1 << (2-0)) - 1)
+#define PLL6553X_MDIV_SHIFT	(16)
+#define PLL6553X_PDIV_SHIFT	(8)
+#define PLL6553X_SDIV_SHIFT	(0)
+#define PLL6553X_KDIV_MASK	(0xffff)
+
+static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
+					     u32 pll0, u32 pll1)
+{
+	unsigned long result;
+	u32 mdiv, pdiv, sdiv, kdiv;
+	u64 tmp;
+
+	mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
+	pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
+	sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
+	kdiv = pll1 & PLL6553X_KDIV_MASK;
+
+	/* We need to multiple baseclk by mdiv (the integer part) and kdiv
+	 * which is in 2^16ths, so shift mdiv up (does not overflow) and
+	 * add kdiv before multiplying. The use of tmp is to avoid any
+	 * overflows before shifting bac down into result when multipling
+	 * by the mdiv and kdiv pair.
+	 */
+
+	tmp = baseclk;
+	tmp *= (mdiv << 16) + kdiv;
+	do_div(tmp, (pdiv << sdiv));
+	result = tmp >> 16;
+
+	return result;
+}
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
new file mode 100644
index 0000000..1bb3dbc
--- /dev/null
+++ b/arch/arm/plat-spear/Kconfig
@@ -0,0 +1,31 @@
+#
+# SPEAr Platform configuration file
+#
+
+if PLAT_SPEAR
+
+choice
+	prompt "ST SPEAr Family"
+	default ARCH_SPEAR3XX
+
+config ARCH_SPEAR3XX
+	bool "SPEAr3XX"
+	select ARM_VIC
+	select CPU_ARM926T
+	help
+	  Supports for ARM's SPEAR3XX family
+
+config ARCH_SPEAR6XX
+	bool "SPEAr6XX"
+	select ARM_VIC
+	select CPU_ARM926T
+	help
+	  Supports for ARM's SPEAR6XX family
+
+endchoice
+
+# Adding SPEAr machine specific configuration files
+source "arch/arm/mach-spear3xx/Kconfig"
+source "arch/arm/mach-spear6xx/Kconfig"
+
+endif
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
new file mode 100644
index 0000000..eb89540
--- /dev/null
+++ b/arch/arm/plat-spear/Makefile
@@ -0,0 +1,8 @@
+#
+# SPEAr Platform specific Makefile
+#
+
+# Common support
+obj-y	:= clock.o padmux.o time.o
+
+obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
new file mode 100644
index 0000000..ee4f90e
--- /dev/null
+++ b/arch/arm/plat-spear/clock.c
@@ -0,0 +1,435 @@
+/*
+ * arch/arm/plat-spear/clock.c
+ *
+ * Clock framework for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/bug.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <mach/misc_regs.h>
+#include <plat/clock.h>
+
+static DEFINE_SPINLOCK(clocks_lock);
+static LIST_HEAD(root_clks);
+
+static void propagate_rate(struct list_head *);
+
+static int generic_clk_enable(struct clk *clk)
+{
+	unsigned int val;
+
+	if (!clk->en_reg)
+		return -EFAULT;
+
+	val = readl(clk->en_reg);
+	if (unlikely(clk->flags & RESET_TO_ENABLE))
+		val &= ~(1 << clk->en_reg_bit);
+	else
+		val |= 1 << clk->en_reg_bit;
+
+	writel(val, clk->en_reg);
+
+	return 0;
+}
+
+static void generic_clk_disable(struct clk *clk)
+{
+	unsigned int val;
+
+	if (!clk->en_reg)
+		return;
+
+	val = readl(clk->en_reg);
+	if (unlikely(clk->flags & RESET_TO_ENABLE))
+		val |= 1 << clk->en_reg_bit;
+	else
+		val &= ~(1 << clk->en_reg_bit);
+
+	writel(val, clk->en_reg);
+}
+
+/* generic clk ops */
+static struct clkops generic_clkops = {
+	.enable = generic_clk_enable,
+	.disable = generic_clk_disable,
+};
+
+/*
+ * clk_enable - inform the system when the clock source should be running.
+ * @clk: clock source
+ *
+ * If the clock can not be enabled/disabled, this should return success.
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_enable(struct clk *clk)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	if (!clk || IS_ERR(clk))
+		return -EFAULT;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	if (clk->usage_count == 0) {
+		if (clk->ops && clk->ops->enable)
+			ret = clk->ops->enable(clk);
+	}
+	clk->usage_count++;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/*
+ * clk_disable - inform the system when the clock source is no longer required.
+ * @clk: clock source
+ *
+ * Inform the system that a clock source is no longer required by
+ * a driver and may be shut down.
+ *
+ * Implementation detail: if the clock source is shared between
+ * multiple drivers, clk_enable() calls must be balanced by the
+ * same number of clk_disable() calls for the clock source to be
+ * disabled.
+ */
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (!clk || IS_ERR(clk))
+		return;
+
+	WARN_ON(clk->usage_count == 0);
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	clk->usage_count--;
+	if (clk->usage_count == 0) {
+		if (clk->ops && clk->ops->disable)
+			clk->ops->disable(clk);
+	}
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/**
+ * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
+ *		 This is only valid once the clock source has been enabled.
+ * @clk: clock source
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+	unsigned long flags, rate;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	rate = clk->rate;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/**
+ * clk_set_parent - set the parent clock source for this clock
+ * @clk: clock source
+ * @parent: parent clock source
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int i, found = 0, val = 0;
+	unsigned long flags;
+
+	if (!clk || IS_ERR(clk) || !parent || IS_ERR(parent))
+		return -EFAULT;
+	if (clk->usage_count)
+		return -EBUSY;
+	if (!clk->pclk_sel)
+		return -EPERM;
+	if (clk->pclk == parent)
+		return 0;
+
+	for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
+		if (clk->pclk_sel->pclk_info[i].pclk == parent) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found)
+		return -EINVAL;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	/* reflect parent change in hardware */
+	val = readl(clk->pclk_sel->pclk_sel_reg);
+	val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift);
+	val |= clk->pclk_sel->pclk_info[i].pclk_mask << clk->pclk_sel_shift;
+	writel(val, clk->pclk_sel->pclk_sel_reg);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	/* reflect parent change in software */
+	clk->recalc(clk);
+	propagate_rate(&clk->children);
+	return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* registers clock in platform clock framework */
+void clk_register(struct clk_lookup *cl)
+{
+	struct clk *clk = cl->clk;
+	unsigned long flags;
+
+	if (!clk || IS_ERR(clk))
+		return;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+
+	INIT_LIST_HEAD(&clk->children);
+	if (clk->flags & ALWAYS_ENABLED)
+		clk->ops = NULL;
+	else if (!clk->ops)
+		clk->ops = &generic_clkops;
+
+	/* root clock don't have any parents */
+	if (!clk->pclk && !clk->pclk_sel) {
+		list_add(&clk->sibling, &root_clks);
+		/* add clocks with only one parent to parent's children list */
+	} else if (clk->pclk && !clk->pclk_sel) {
+		list_add(&clk->sibling, &clk->pclk->children);
+	} else {
+		/* add clocks with > 1 parent to 1st parent's children list */
+		list_add(&clk->sibling,
+			 &clk->pclk_sel->pclk_info[0].pclk->children);
+	}
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	/* add clock to arm clockdev framework */
+	clkdev_add(cl);
+}
+
+/**
+ * propagate_rate - recalculate and propagate all clocks in list head
+ *
+ * Recalculates all root clocks in list head, which if the clock's .recalc is
+ * set correctly, should also propagate their rates.
+ */
+static void propagate_rate(struct list_head *lhead)
+{
+	struct clk *clkp, *_temp;
+
+	list_for_each_entry_safe(clkp, _temp, lhead, sibling) {
+		if (clkp->recalc)
+			clkp->recalc(clkp);
+		propagate_rate(&clkp->children);
+	}
+}
+
+/* returns current programmed clocks clock info structure */
+static struct pclk_info *pclk_info_get(struct clk *clk)
+{
+	unsigned int mask, i;
+	unsigned long flags;
+	struct pclk_info *info = NULL;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	mask = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
+			& clk->pclk_sel->pclk_sel_mask;
+
+	for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
+		if (clk->pclk_sel->pclk_info[i].pclk_mask == mask)
+			info = &clk->pclk_sel->pclk_info[i];
+	}
+	spin_unlock_irqrestore(&clocks_lock, flags);
+
+	return info;
+}
+
+/*
+ * Set pclk as cclk's parent and add clock sibling node to current parents
+ * children list
+ */
+static void change_parent(struct clk *cclk, struct clk *pclk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	list_del(&cclk->sibling);
+	list_add(&cclk->sibling, &pclk->children);
+
+	cclk->pclk = pclk;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/*
+ * calculates current programmed rate of pll1
+ *
+ * In normal mode
+ * rate = (2 * M[15:8] * Fin)/(N * 2^P)
+ *
+ * In Dithered mode
+ * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
+ */
+void pll1_clk_recalc(struct clk *clk)
+{
+	struct pll_clk_config *config = clk->private_data;
+	unsigned int num = 2, den = 0, val, mode = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	mode = (readl(config->mode_reg) >> PLL_MODE_SHIFT) &
+		PLL_MODE_MASK;
+
+	val = readl(config->cfg_reg);
+	/* calculate denominator */
+	den = (val >> PLL_DIV_P_SHIFT) & PLL_DIV_P_MASK;
+	den = 1 << den;
+	den *= (val >> PLL_DIV_N_SHIFT) & PLL_DIV_N_MASK;
+
+	/* calculate numerator & denominator */
+	if (!mode) {
+		/* Normal mode */
+		num *= (val >> PLL_NORM_FDBK_M_SHIFT) & PLL_NORM_FDBK_M_MASK;
+	} else {
+		/* Dithered mode */
+		num *= (val >> PLL_DITH_FDBK_M_SHIFT) & PLL_DITH_FDBK_M_MASK;
+		den *= 256;
+	}
+
+	clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/* calculates current programmed rate of ahb or apb bus */
+void bus_clk_recalc(struct clk *clk)
+{
+	struct bus_clk_config *config = clk->private_data;
+	unsigned int div;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	div = ((readl(config->reg) >> config->shift) & config->mask) + 1;
+	clk->rate = (unsigned long)clk->pclk->rate / div;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/*
+ * calculates current programmed rate of auxiliary synthesizers
+ * used by: UART, FIRDA
+ *
+ * Fout from synthesizer can be given from two equations:
+ * Fout1 = (Fin * X/Y)/2
+ * Fout2 = Fin * X/Y
+ *
+ * Selection of eqn 1 or 2 is programmed in register
+ */
+void aux_clk_recalc(struct clk *clk)
+{
+	struct aux_clk_config *config = clk->private_data;
+	struct pclk_info *pclk_info = NULL;
+	unsigned int num = 1, den = 1, val, eqn;
+	unsigned long flags;
+
+	/* get current programmed parent */
+	pclk_info = pclk_info_get(clk);
+	if (!pclk_info) {
+		spin_lock_irqsave(&clocks_lock, flags);
+		clk->pclk = NULL;
+		clk->rate = 0;
+		spin_unlock_irqrestore(&clocks_lock, flags);
+		return;
+	}
+
+	change_parent(clk, pclk_info->pclk);
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	if (pclk_info->scalable) {
+		val = readl(config->synth_reg);
+
+		eqn = (val >> AUX_EQ_SEL_SHIFT) & AUX_EQ_SEL_MASK;
+		if (eqn == AUX_EQ1_SEL)
+			den *= 2;
+
+		/* calculate numerator */
+		num = (val >> AUX_XSCALE_SHIFT) & AUX_XSCALE_MASK;
+
+		/* calculate denominator */
+		den *= (val >> AUX_YSCALE_SHIFT) & AUX_YSCALE_MASK;
+		val = (((clk->pclk->rate/10000) * num) / den) * 10000;
+	} else
+		val = clk->pclk->rate;
+
+	clk->rate = val;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/*
+ * calculates current programmed rate of gpt synthesizers
+ * Fout from synthesizer can be given from below equations:
+ * Fout= Fin/((2 ^ (N+1)) * (M+1))
+ */
+void gpt_clk_recalc(struct clk *clk)
+{
+	struct aux_clk_config *config = clk->private_data;
+	struct pclk_info *pclk_info = NULL;
+	unsigned int div = 1, val;
+	unsigned long flags;
+
+	pclk_info = pclk_info_get(clk);
+	if (!pclk_info) {
+		spin_lock_irqsave(&clocks_lock, flags);
+		clk->pclk = NULL;
+		clk->rate = 0;
+		spin_unlock_irqrestore(&clocks_lock, flags);
+		return;
+	}
+
+	change_parent(clk, pclk_info->pclk);
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	if (pclk_info->scalable) {
+		val = readl(config->synth_reg);
+		div += (val >> GPT_MSCALE_SHIFT) & GPT_MSCALE_MASK;
+		div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1);
+	}
+
+	clk->rate = (unsigned long)clk->pclk->rate / div;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/*
+ * Used for clocks that always have same value as the parent clock divided by a
+ * fixed divisor
+ */
+void follow_parent(struct clk *clk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	clk->rate = clk->pclk->rate;
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/**
+ * recalc_root_clocks - recalculate and propagate all root clocks
+ *
+ * Recalculates all root clocks (clocks with no parent), which if the
+ * clock's .recalc is set correctly, should also propagate their rates.
+ */
+void recalc_root_clocks(void)
+{
+	propagate_rate(&root_clks);
+}
diff --git a/arch/arm/plat-spear/include/plat/clkdev.h b/arch/arm/plat-spear/include/plat/clkdev.h
new file mode 100644
index 0000000..a2d0112
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/clkdev.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-spear/include/plat/clkdev.h
+ *
+ * Clock Dev framework definitions for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __PLAT_CLKDEV_H
+#define __PLAT_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif /* __PLAT_CLKDEV_H */
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
new file mode 100644
index 0000000..298bafc
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -0,0 +1,126 @@
+/*
+ * arch/arm/plat-spear/include/plat/clock.h
+ *
+ * Clock framework definitions for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __PLAT_CLOCK_H
+#define __PLAT_CLOCK_H
+
+#include <linux/list.h>
+#include <asm/clkdev.h>
+#include <linux/types.h>
+
+/* clk structure flags */
+#define	ALWAYS_ENABLED		(1 << 0) /* clock always enabled */
+#define	RESET_TO_ENABLE		(1 << 1) /* reset register bit to enable clk */
+
+/**
+ * struct clkops - clock operations
+ * @enable: pointer to clock enable function
+ * @disable: pointer to clock disable function
+ */
+struct clkops {
+	int (*enable) (struct clk *);
+	void (*disable) (struct clk *);
+};
+
+/**
+ * struct pclk_info - parents info
+ * @pclk: pointer to parent clk
+ * @pclk_mask: value to be written for selecting this parent
+ * @scalable: Is parent scalable (1 - YES, 0 - NO)
+ */
+struct pclk_info {
+	struct clk *pclk;
+	u8 pclk_mask;
+	u8 scalable;
+};
+
+/**
+ * struct pclk_sel - parents selection configuration
+ * @pclk_info: pointer to array of parent clock info
+ * @pclk_count: number of parents
+ * @pclk_sel_reg: register for selecting a parent
+ * @pclk_sel_mask: mask for selecting parent (can be used to clear bits also)
+ */
+struct pclk_sel {
+	struct pclk_info *pclk_info;
+	u8 pclk_count;
+	unsigned int *pclk_sel_reg;
+	unsigned int pclk_sel_mask;
+};
+
+/**
+ * struct clk - clock structure
+ * @usage_count: num of users who enabled this clock
+ * @flags: flags for clock properties
+ * @rate: programmed clock rate in Hz
+ * @en_reg: clk enable/disable reg
+ * @en_reg_bit: clk enable/disable bit
+ * @ops: clk enable/disable ops - generic_clkops selected if NULL
+ * @recalc: pointer to clock rate recalculate function
+ * @pclk: current parent clk
+ * @pclk_sel: pointer to parent selection structure
+ * @pclk_sel_shift: register shift for selecting parent of this clock
+ * @children: list for childrens or this clock
+ * @sibling: node for list of clocks having same parents
+ * @private_data: clock specific private data
+ */
+struct clk {
+	unsigned int usage_count;
+	unsigned int flags;
+	unsigned long rate;
+	unsigned int *en_reg;
+	u8 en_reg_bit;
+	const struct clkops *ops;
+	void (*recalc) (struct clk *);
+
+	struct clk *pclk;
+	struct pclk_sel *pclk_sel;
+	unsigned int pclk_sel_shift;
+
+	struct list_head children;
+	struct list_head sibling;
+	void *private_data;
+};
+
+/* pll configuration structure */
+struct pll_clk_config {
+	unsigned int *mode_reg;
+	unsigned int *cfg_reg;
+};
+
+/* ahb and apb bus configuration structure */
+struct bus_clk_config {
+	unsigned int *reg;
+	unsigned int mask;
+	unsigned int shift;
+};
+
+/*
+ * Aux clk configuration structure: applicable to GPT, UART and FIRDA
+ */
+struct aux_clk_config {
+	unsigned int *synth_reg;
+};
+
+/* platform specific clock functions */
+void clk_register(struct clk_lookup *cl);
+void recalc_root_clocks(void);
+
+/* clock recalc functions */
+void follow_parent(struct clk *clk);
+void pll1_clk_recalc(struct clk *clk);
+void bus_clk_recalc(struct clk *clk);
+void gpt_clk_recalc(struct clk *clk);
+void aux_clk_recalc(struct clk *clk);
+
+#endif /* __PLAT_CLOCK_H */
diff --git a/arch/arm/plat-spear/include/plat/debug-macro.S b/arch/arm/plat-spear/include/plat/debug-macro.S
new file mode 100644
index 0000000..1670734
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/debug-macro.S
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/plat-spear/include/plat/debug-macro.S
+ *
+ * Debugging macro include header for spear platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/amba/serial.h>
+#include <mach/spear.h>
+
+		.macro	addruart, rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1					@ MMU enabled?
+		moveq	\rx, =SPEAR_DBG_UART_BASE		@ Physical base
+		movne	\rx, =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/plat-spear/include/plat/gpio.h b/arch/arm/plat-spear/include/plat/gpio.h
new file mode 100644
index 0000000..b857c91
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/gpio.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/plat-spear/include/plat/gpio.h
+ *
+ * GPIO macros for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __PLAT_GPIO_H
+#define __PLAT_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define gpio_to_irq	__gpio_to_irq
+
+#endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/plat-spear/include/plat/io.h b/arch/arm/plat-spear/include/plat/io.h
new file mode 100644
index 0000000..4d4ba82
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/io.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/plat-spear/include/plat/io.h
+ *
+ * IO definitions for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __PLAT_IO_H
+#define __PLAT_IO_H
+
+#define IO_SPACE_LIMIT		0xFFFFFFFF
+
+#define __io(a)			__typesafe_io(a)
+#define __mem_pci(a)		(a)
+
+#endif /* __PLAT_IO_H */
diff --git a/arch/arm/plat-spear/include/plat/memory.h b/arch/arm/plat-spear/include/plat/memory.h
new file mode 100644
index 0000000..27a4aba
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/memory.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-spear/include/plat/memory.h
+ *
+ * Memory map for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __PLAT_MEMORY_H
+#define __PLAT_MEMORY_H
+
+/* Physical DRAM offset */
+#define PHYS_OFFSET		UL(0x00000000)
+
+#endif /* __PLAT_MEMORY_H */
diff --git a/arch/arm/plat-spear/include/plat/padmux.h b/arch/arm/plat-spear/include/plat/padmux.h
new file mode 100644
index 0000000..877f3ad
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/padmux.h
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/plat-spear/include/plat/padmux.h
+ *
+ * SPEAr platform specific gpio pads muxing file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __PLAT_PADMUX_H
+#define __PLAT_PADMUX_H
+
+#include <linux/types.h>
+
+/*
+ * struct pmx_reg: configuration structure for mode reg and mux reg
+ *
+ * offset: offset of mode reg
+ * mask: mask of mode reg
+ */
+struct pmx_reg {
+	u32 offset;
+	u32 mask;
+};
+
+/*
+ * struct pmx_dev_mode: configuration structure every group of modes of a device
+ *
+ * ids: all modes for this configuration
+ * mask: mask for supported mode
+ */
+struct pmx_dev_mode {
+	u32 ids;
+	u32 mask;
+};
+
+/*
+ * struct pmx_mode: mode definition structure
+ *
+ * name: mode name
+ * mask: mode mask
+ */
+struct pmx_mode {
+	char *name;
+	u32 id;
+	u32 mask;
+};
+
+/*
+ * struct pmx_dev: device definition structure
+ *
+ * name: device name
+ * modes: device configuration array for different modes supported
+ * mode_count: size of modes array
+ * is_active: is peripheral active/enabled
+ * enb_on_reset: if 1, mask bits to be cleared in reg otherwise to be set in reg
+ */
+struct pmx_dev {
+	char *name;
+	struct pmx_dev_mode *modes;
+	u8 mode_count;
+	bool is_active;
+	bool enb_on_reset;
+};
+
+/*
+ * struct pmx_driver: driver definition structure
+ *
+ * mode: mode to be set
+ * devs: array of pointer to pmx devices
+ * devs_count: ARRAY_SIZE of devs
+ * base: base address of soc config registers
+ * mode_reg: structure of mode config register
+ * mux_reg: structure of device mux config register
+ */
+struct pmx_driver {
+	struct pmx_mode *mode;
+	struct pmx_dev **devs;
+	u8 devs_count;
+	u32 *base;
+	struct pmx_reg mode_reg;
+	struct pmx_reg mux_reg;
+};
+
+/* pmx functions */
+int pmx_register(struct pmx_driver *driver);
+
+#endif /* __PLAT_PADMUX_H */
diff --git a/arch/arm/plat-spear/include/plat/shirq.h b/arch/arm/plat-spear/include/plat/shirq.h
new file mode 100644
index 0000000..03ed8b5
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/shirq.h
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/plat-spear/include/plat/shirq.h
+ *
+ * SPEAr platform shared irq layer header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __PLAT_SHIRQ_H
+#define __PLAT_SHIRQ_H
+
+#include <linux/irq.h>
+#include <linux/types.h>
+
+/*
+ * struct shirq_dev_config: shared irq device configuration
+ *
+ * virq: virtual irq number of device
+ * enb_mask: enable mask of device
+ * status_mask: status mask of device
+ * clear_mask: clear mask of device
+ */
+struct shirq_dev_config {
+	u32 virq;
+	u32 enb_mask;
+	u32 status_mask;
+	u32 clear_mask;
+};
+
+/*
+ * struct shirq_regs: shared irq register configuration
+ *
+ * base: base address of shared irq register
+ * enb_reg: enable register offset
+ * reset_to_enb: val 1 indicates, we need to clear bit for enabling interrupt
+ * status_reg: status register offset
+ * status_reg_mask: status register valid mask
+ * clear_reg: clear register offset
+ * reset_to_clear: val 1 indicates, we need to clear bit for clearing interrupt
+ */
+struct shirq_regs {
+	void __iomem *base;
+	u32 enb_reg;
+	u32 reset_to_enb;
+	u32 status_reg;
+	u32 status_reg_mask;
+	u32 clear_reg;
+	u32 reset_to_clear;
+};
+
+/*
+ * struct spear_shirq: shared irq structure
+ *
+ * irq: hardware irq number
+ * dev_config: array of device config structures which are using "irq" line
+ * dev_count: size of dev_config array
+ * regs: register configuration for shared irq block
+ */
+struct spear_shirq {
+	u32 irq;
+	struct shirq_dev_config *dev_config;
+	u32 dev_count;
+	struct shirq_regs regs;
+};
+
+int spear_shirq_register(struct spear_shirq *shirq);
+
+#endif /* __PLAT_SHIRQ_H */
diff --git a/arch/arm/plat-spear/include/plat/system.h b/arch/arm/plat-spear/include/plat/system.h
new file mode 100644
index 0000000..55a4e40
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/system.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/plat-spear/include/plat/system.h
+ *
+ * SPEAr platform specific architecture functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __PLAT_SYSTEM_H
+#define __PLAT_SYSTEM_H
+
+#include <asm/hardware/sp810.h>
+#include <linux/io.h>
+#include <mach/spear.h>
+
+static inline void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	if (mode == 's') {
+		/* software reset, Jump into ROM at address 0 */
+		cpu_reset(0);
+	} else {
+		/* hardware reset, Use on-chip reset capability */
+		sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE);
+	}
+}
+
+#endif /* __PLAT_SYSTEM_H */
diff --git a/arch/arm/plat-spear/include/plat/timex.h b/arch/arm/plat-spear/include/plat/timex.h
new file mode 100644
index 0000000..914d09d
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/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.kumar@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.
+ */
+
+#ifndef __PLAT_TIMEX_H
+#define __PLAT_TIMEX_H
+
+#define CLOCK_TICK_RATE			48000000
+
+#endif /* __PLAT_TIMEX_H */
diff --git a/arch/arm/plat-spear/include/plat/uncompress.h b/arch/arm/plat-spear/include/plat/uncompress.h
new file mode 100644
index 0000000..99ba678
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/uncompress.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/plat-spear/include/plat/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/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(base + UART01x_FR) & UART01x_FR_TXFF)
+		barrier();
+
+	writel(c, base + UART01x_DR);
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif /* __PLAT_UNCOMPRESS_H */
diff --git a/arch/arm/plat-spear/include/plat/vmalloc.h b/arch/arm/plat-spear/include/plat/vmalloc.h
new file mode 100644
index 0000000..09e9372
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/vmalloc.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/plat-spear/include/plat/vmalloc.h
+ *
+ * Defining Vmalloc area for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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.
+ */
+
+#ifndef __PLAT_VMALLOC_H
+#define __PLAT_VMALLOC_H
+
+#define VMALLOC_END		0xF0000000
+
+#endif /* __PLAT_VMALLOC_H */
diff --git a/arch/arm/plat-spear/padmux.c b/arch/arm/plat-spear/padmux.c
new file mode 100644
index 0000000..d2aab3a
--- /dev/null
+++ b/arch/arm/plat-spear/padmux.c
@@ -0,0 +1,164 @@
+/*
+ * arch/arm/plat-spear/include/plat/padmux.c
+ *
+ * SPEAr platform specific gpio pads muxing source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <plat/padmux.h>
+
+/*
+ * struct pmx: pmx definition structure
+ *
+ * base: base address of configuration registers
+ * mode_reg: mode configurations
+ * mux_reg: muxing configurations
+ * active_mode: pointer to current active mode
+ */
+struct pmx {
+	u32 base;
+	struct pmx_reg mode_reg;
+	struct pmx_reg mux_reg;
+	struct pmx_mode *active_mode;
+};
+
+static struct pmx *pmx;
+
+/**
+ * pmx_mode_set - Enables an multiplexing mode
+ * @mode - pointer to pmx mode
+ *
+ * It will set mode of operation in hardware.
+ * Returns -ve on Err otherwise 0
+ */
+static int pmx_mode_set(struct pmx_mode *mode)
+{
+	u32 val;
+
+	if (!mode->name)
+		return -EFAULT;
+
+	pmx->active_mode = mode;
+
+	val = readl(pmx->base + pmx->mode_reg.offset);
+	val &= ~pmx->mode_reg.mask;
+	val |= mode->mask & pmx->mode_reg.mask;
+	writel(val, pmx->base + pmx->mode_reg.offset);
+
+	return 0;
+}
+
+/**
+ * pmx_devs_enable - Enables list of devices
+ * @devs - pointer to pmx device array
+ * @count - number of devices to enable
+ *
+ * It will enable pads for all required peripherals once and only once.
+ * If peripheral is not supported by current mode then request is rejected.
+ * Conflicts between peripherals are not handled and peripherals will be
+ * enabled in the order they are present in pmx_dev array.
+ * In case of conflicts last peripheral enalbed will be present.
+ * Returns -ve on Err otherwise 0
+ */
+static int pmx_devs_enable(struct pmx_dev **devs, u8 count)
+{
+	u32 val, i, mask;
+
+	if (!count)
+		return -EINVAL;
+
+	val = readl(pmx->base + pmx->mux_reg.offset);
+	for (i = 0; i < count; i++) {
+		u8 j = 0;
+
+		if (!devs[i]->name || !devs[i]->modes) {
+			printk(KERN_ERR "padmux: dev name or modes is null\n");
+			continue;
+		}
+		/* check if peripheral exists in active mode */
+		if (pmx->active_mode) {
+			bool found = false;
+			for (j = 0; j < devs[i]->mode_count; j++) {
+				if (devs[i]->modes[j].ids &
+						pmx->active_mode->id) {
+					found = true;
+					break;
+				}
+			}
+			if (found == false) {
+				printk(KERN_ERR "%s device not available in %s"\
+						"mode\n", devs[i]->name,
+						pmx->active_mode->name);
+				continue;
+			}
+		}
+
+		/* enable peripheral */
+		mask = devs[i]->modes[j].mask & pmx->mux_reg.mask;
+		if (devs[i]->enb_on_reset)
+			val &= ~mask;
+		else
+			val |= mask;
+
+		devs[i]->is_active = true;
+	}
+	writel(val, pmx->base + pmx->mux_reg.offset);
+	kfree(pmx);
+
+	/* this will ensure that multiplexing can't be changed now */
+	pmx = (struct pmx *)-1;
+
+	return 0;
+}
+
+/**
+ * pmx_register - registers a platform requesting pad mux feature
+ * @driver - pointer to driver structure containing driver specific parameters
+ *
+ * Also this must be called only once. This will allocate memory for pmx
+ * structure, will call pmx_mode_set, will call pmx_devs_enable.
+ * Returns -ve on Err otherwise 0
+ */
+int pmx_register(struct pmx_driver *driver)
+{
+	int ret = 0;
+
+	if (pmx)
+		return -EPERM;
+	if (!driver->base || !driver->devs)
+		return -EFAULT;
+
+	pmx = kzalloc(sizeof(*pmx), GFP_KERNEL);
+	if (!pmx)
+		return -ENOMEM;
+
+	pmx->base = (u32)driver->base;
+	pmx->mode_reg.offset = driver->mode_reg.offset;
+	pmx->mode_reg.mask = driver->mode_reg.mask;
+	pmx->mux_reg.offset = driver->mux_reg.offset;
+	pmx->mux_reg.mask = driver->mux_reg.mask;
+
+	/* choose mode to enable */
+	if (driver->mode) {
+		ret = pmx_mode_set(driver->mode);
+		if (ret)
+			goto pmx_fail;
+	}
+	ret = pmx_devs_enable(driver->devs, driver->devs_count);
+	if (ret)
+		goto pmx_fail;
+
+	return 0;
+
+pmx_fail:
+	return ret;
+}
diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c
new file mode 100644
index 0000000..2172d69
--- /dev/null
+++ b/arch/arm/plat-spear/shirq.c
@@ -0,0 +1,118 @@
+/*
+ * arch/arm/plat-spear/shirq.c
+ *
+ * SPEAr platform shared irq layer source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@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/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <plat/shirq.h>
+
+struct spear_shirq *shirq;
+static DEFINE_SPINLOCK(lock);
+
+static void shirq_irq_mask(unsigned irq)
+{
+	struct spear_shirq *shirq = get_irq_chip_data(irq);
+	u32 val, id = irq - shirq->dev_config[0].virq;
+	unsigned long flags;
+
+	if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1)
+		return;
+
+	spin_lock_irqsave(&lock, flags);
+	val = readl(shirq->regs.base + shirq->regs.enb_reg);
+	if (shirq->regs.reset_to_enb)
+		val |= shirq->dev_config[id].enb_mask;
+	else
+		val &= ~(shirq->dev_config[id].enb_mask);
+	writel(val, shirq->regs.base + shirq->regs.enb_reg);
+	spin_unlock_irqrestore(&lock, flags);
+}
+
+static void shirq_irq_unmask(unsigned irq)
+{
+	struct spear_shirq *shirq = get_irq_chip_data(irq);
+	u32 val, id = irq - shirq->dev_config[0].virq;
+	unsigned long flags;
+
+	if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1)
+		return;
+
+	spin_lock_irqsave(&lock, flags);
+	val = readl(shirq->regs.base + shirq->regs.enb_reg);
+	if (shirq->regs.reset_to_enb)
+		val &= ~(shirq->dev_config[id].enb_mask);
+	else
+		val |= shirq->dev_config[id].enb_mask;
+	writel(val, shirq->regs.base + shirq->regs.enb_reg);
+	spin_unlock_irqrestore(&lock, flags);
+}
+
+static struct irq_chip shirq_chip = {
+	.name		= "spear_shirq",
+	.ack		= shirq_irq_mask,
+	.mask		= shirq_irq_mask,
+	.unmask		= shirq_irq_unmask,
+};
+
+static void shirq_handler(unsigned irq, struct irq_desc *desc)
+{
+	u32 i, val, mask;
+	struct spear_shirq *shirq = get_irq_data(irq);
+
+	desc->chip->ack(irq);
+	while ((val = readl(shirq->regs.base + shirq->regs.status_reg) &
+				shirq->regs.status_reg_mask)) {
+		for (i = 0; (i < shirq->dev_count) && val; i++) {
+			if (!(shirq->dev_config[i].status_mask & val))
+				continue;
+
+			generic_handle_irq(shirq->dev_config[i].virq);
+
+			/* clear interrupt */
+			val &= ~shirq->dev_config[i].status_mask;
+			if ((shirq->regs.clear_reg == -1) ||
+					shirq->dev_config[i].clear_mask == -1)
+				continue;
+			mask = readl(shirq->regs.base + shirq->regs.clear_reg);
+			if (shirq->regs.reset_to_clear)
+				mask &= ~shirq->dev_config[i].clear_mask;
+			else
+				mask |= shirq->dev_config[i].clear_mask;
+			writel(mask, shirq->regs.base + shirq->regs.clear_reg);
+		}
+	}
+	desc->chip->unmask(irq);
+}
+
+int spear_shirq_register(struct spear_shirq *shirq)
+{
+	int i;
+
+	if (!shirq || !shirq->dev_config || !shirq->regs.base)
+		return -EFAULT;
+
+	if (!shirq->dev_count)
+		return -EINVAL;
+
+	set_irq_chained_handler(shirq->irq, shirq_handler);
+	for (i = 0; i < shirq->dev_count; i++) {
+		set_irq_chip(shirq->dev_config[i].virq, &shirq_chip);
+		set_irq_handler(shirq->dev_config[i].virq, handle_simple_irq);
+		set_irq_flags(shirq->dev_config[i].virq, IRQF_VALID);
+		set_irq_chip_data(shirq->dev_config[i].virq, shirq);
+	}
+
+	set_irq_data(shirq->irq, shirq);
+	return 0;
+}
diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
new file mode 100644
index 0000000..a1025d3
--- /dev/null
+++ b/arch/arm/plat-spear/time.c
@@ -0,0 +1,292 @@
+/*
+ * arch/arm/plat-spear/time.c
+ *
+ * Copyright (C) 2009 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/io.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/irq.h>
+#include <asm/mach/time.h>
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/spear.h>
+#include <mach/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
+
+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);
+
+/*
+ * 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));
+}
+
+static struct clocksource clksrc = {
+	.name = "tmr1",
+	.rating = 200,		/* its a pretty decent clock */
+	.read = clocksource_read_cycles,
+	.mask = 0xFFFF,		/* 16 bits */
+	.mult = 0,		/* to be computed */
+	.shift = 0,		/* to be computed */
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+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));
+
+	clocksource_set_clock(&clksrc, tick_rate);
+
+	/* register the clocksource */
+	clocksource_register(&clksrc);
+}
+
+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;
+
+	writew(cycles, gpt_base + LOAD(CLKEVT));
+
+	val = readw(gpt_base + CR(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(void)
+{
+	u32 tick_rate;
+
+	/* program the prescaler */
+	writew(CTRL_PRESCALER16, gpt_base + CR(CLKEVT));
+
+	tick_rate = clk_get_rate(gpt_clk);
+	tick_rate >>= CTRL_PRESCALER16;
+
+	clockevent_set_clock(&clkevt, tick_rate);
+
+	clkevt.max_delta_ns = clockevent_delta2ns(0xfff0,
+			&clkevt);
+	clkevt.min_delta_ns = clockevent_delta2ns(3, &clkevt);
+
+	clkevt.cpumask = cpumask_of(0);
+
+	clockevents_register_device(&clkevt);
+
+	setup_irq(SPEAR_GPT0_CHAN0_IRQ, &spear_timer_irq);
+}
+
+void __init spear_setup_timer(void)
+{
+	struct clk *pll3_clk;
+
+	if (!request_mem_region(SPEAR_GPT0_BASE, SZ_1K, "gpt0")) {
+		pr_err("%s:cannot get IO addr\n", __func__);
+		return;
+	}
+
+	gpt_base = (void __iomem *)ioremap(SPEAR_GPT0_BASE, SZ_1K);
+	if (!gpt_base) {
+		pr_err("%s:ioremap failed for gpt\n", __func__);
+		goto err_mem;
+	}
+
+	gpt_clk = clk_get_sys("gpt0", NULL);
+	if (!gpt_clk) {
+		pr_err("%s:couldn't get clk for gpt\n", __func__);
+		goto err_iomap;
+	}
+
+	pll3_clk = clk_get(NULL, "pll3_48m_clk");
+	if (!pll3_clk) {
+		pr_err("%s:couldn't get PLL3 as parent for gpt\n", __func__);
+		goto err_iomap;
+	}
+
+	clk_set_parent(gpt_clk, pll3_clk);
+
+	spear_clockevent_init();
+	spear_clocksource_init();
+
+	return;
+
+err_iomap:
+	iounmap(gpt_base);
+
+err_mem:
+	release_mem_region(SPEAR_GPT0_BASE, SZ_1K);
+}
+
+struct sys_timer spear_sys_timer = {
+	.init = spear_setup_timer,
+};
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
new file mode 100644
index 0000000..9b1a668
--- /dev/null
+++ b/arch/arm/plat-versatile/Makefile
@@ -0,0 +1,4 @@
+obj-y	:= clock.o
+obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
+obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o
+obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o
diff --git a/arch/arm/plat-versatile/clock.c b/arch/arm/plat-versatile/clock.c
new file mode 100644
index 0000000..5c8b656
--- /dev/null
+++ b/arch/arm/plat-versatile/clock.c
@@ -0,0 +1,74 @@
+/*
+ *  linux/arch/arm/plat-versatile/clock.c
+ *
+ *  Copyright (C) 2004 ARM Limited.
+ *  Written by Deep Blue Solutions Limited.
+ *
+ * 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <asm/hardware/icst.h>
+
+#include <mach/clkdev.h>
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	long ret = -EIO;
+	if (clk->ops && clk->ops->round)
+		ret = clk->ops->round(clk, rate);
+	return ret;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret = -EIO;
+	if (clk->ops && clk->ops->set)
+		ret = clk->ops->set(clk, rate);
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+long icst_clk_round(struct clk *clk, unsigned long rate)
+{
+	struct icst_vco vco;
+	vco = icst_hz_to_vco(clk->params, rate);
+	return icst_hz(clk->params, vco);
+}
+EXPORT_SYMBOL(icst_clk_round);
+
+int icst_clk_set(struct clk *clk, unsigned long rate)
+{
+	struct icst_vco vco;
+
+	vco = icst_hz_to_vco(clk->params, rate);
+	clk->rate = icst_hz(clk->params, vco);
+	clk->ops->setvco(clk, vco);
+
+	return 0;
+}
+EXPORT_SYMBOL(icst_clk_set);
diff --git a/arch/arm/plat-versatile/include/plat/clock.h b/arch/arm/plat-versatile/include/plat/clock.h
new file mode 100644
index 0000000..3cfb024
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/clock.h
@@ -0,0 +1,15 @@
+#ifndef PLAT_CLOCK_H
+#define PLAT_CLOCK_H
+
+#include <asm/hardware/icst.h>
+
+struct clk_ops {
+	long	(*round)(struct clk *, unsigned long);
+	int	(*set)(struct clk *, unsigned long);
+	void	(*setvco)(struct clk *, struct icst_vco);
+};
+
+int icst_clk_set(struct clk *, unsigned long);
+long icst_clk_round(struct clk *, unsigned long);
+
+#endif
diff --git a/arch/arm/plat-versatile/include/plat/timer-sp.h b/arch/arm/plat-versatile/include/plat/timer-sp.h
new file mode 100644
index 0000000..21e75e3
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/timer-sp.h
@@ -0,0 +1,2 @@
+void sp804_clocksource_init(void __iomem *);
+void sp804_clockevents_init(void __iomem *, unsigned int);
diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c
new file mode 100644
index 0000000..9768cf7
--- /dev/null
+++ b/arch/arm/plat-versatile/sched-clock.c
@@ -0,0 +1,53 @@
+/*
+ *  linux/arch/arm/plat-versatile/sched-clock.c
+ *
+ *  Copyright (C) 1999 - 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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/cnt32_to_63.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+#ifdef VERSATILE_SYS_BASE
+#define REFCOUNTER	(__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
+#endif
+
+#ifdef REALVIEW_SYS_BASE
+#define REFCOUNTER	(__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
+#endif
+
+/*
+ * This is the Realview and Versatile sched_clock implementation.  This
+ * has a resolution of 41.7ns, and a maximum value of about 35583 days.
+ *
+ * The return value is guaranteed to be monotonic in that range as
+ * long as there is always less than 89 seconds between successive
+ * calls to this function.
+ */
+unsigned long long sched_clock(void)
+{
+	unsigned long long v = cnt32_to_63(readl(REFCOUNTER));
+
+	/* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
+	v *= 125<<1;
+	do_div(v, 3<<1);
+
+	return v;
+}
diff --git a/arch/arm/plat-versatile/timer-sp.c b/arch/arm/plat-versatile/timer-sp.c
new file mode 100644
index 0000000..fb0d1c2
--- /dev/null
+++ b/arch/arm/plat-versatile/timer-sp.c
@@ -0,0 +1,156 @@
+/*
+ *  linux/arch/arm/plat-versatile/timer-sp.c
+ *
+ *  Copyright (C) 1999 - 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/arm_timer.h>
+
+#include <plat/timer-sp.h>
+
+/*
+ * These timers are currently always setup to be clocked at 1MHz.
+ */
+#define TIMER_FREQ_KHZ	(1000)
+#define TIMER_RELOAD	(TIMER_FREQ_KHZ * 1000 / HZ)
+
+static void __iomem *clksrc_base;
+
+static cycle_t sp804_read(struct clocksource *cs)
+{
+	return ~readl(clksrc_base + TIMER_VALUE);
+}
+
+static struct clocksource clocksource_sp804 = {
+	.name		= "timer3",
+	.rating		= 200,
+	.read		= sp804_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift		= 20,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sp804_clocksource_init(void __iomem *base)
+{
+	struct clocksource *cs = &clocksource_sp804;
+
+	clksrc_base = base;
+
+	/* setup timer 0 as free-running clocksource */
+	writel(0, clksrc_base + TIMER_CTRL);
+	writel(0xffffffff, clksrc_base + TIMER_LOAD);
+	writel(0xffffffff, clksrc_base + TIMER_VALUE);
+	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
+		clksrc_base + TIMER_CTRL);
+
+	cs->mult = clocksource_khz2mult(TIMER_FREQ_KHZ, cs->shift);
+	clocksource_register(cs);
+}
+
+
+static void __iomem *clkevt_base;
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	/* clear the interrupt */
+	writel(1, clkevt_base + TIMER_INTCLR);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static void sp804_set_mode(enum clock_event_mode mode,
+	struct clock_event_device *evt)
+{
+	unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE;
+
+	writel(ctrl, clkevt_base + TIMER_CTRL);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		writel(TIMER_RELOAD, clkevt_base + TIMER_LOAD);
+		ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* period set, and timer enabled in 'next_event' hook */
+		ctrl |= TIMER_CTRL_ONESHOT;
+		break;
+
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	default:
+		break;
+	}
+
+	writel(ctrl, clkevt_base + TIMER_CTRL);
+}
+
+static int sp804_set_next_event(unsigned long next,
+	struct clock_event_device *evt)
+{
+	unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
+
+	writel(next, clkevt_base + TIMER_LOAD);
+	writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+
+	return 0;
+}
+
+static struct clock_event_device sp804_clockevent = {
+	.name		= "timer0",
+	.shift		= 32,
+	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode	= sp804_set_mode,
+	.set_next_event	= sp804_set_next_event,
+	.rating		= 300,
+	.cpumask	= cpu_all_mask,
+};
+
+static struct irqaction sp804_timer_irq = {
+	.name		= "timer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= sp804_timer_interrupt,
+	.dev_id		= &sp804_clockevent,
+};
+
+void __init sp804_clockevents_init(void __iomem *base, unsigned int timer_irq)
+{
+	struct clock_event_device *evt = &sp804_clockevent;
+
+	clkevt_base = base;
+
+	evt->irq = timer_irq;
+	evt->mult = div_sc(TIMER_FREQ_KHZ, NSEC_PER_MSEC, evt->shift);
+	evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt);
+	evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
+
+	setup_irq(timer_irq, &sp804_timer_irq);
+	clockevents_register_device(evt);
+}
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 9c6170c..87ab056 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -564,7 +564,7 @@
 
 config I2C_VERSATILE
 	tristate "ARM Versatile/Realview I2C bus support"
-	depends on ARCH_VERSATILE || ARCH_REALVIEW
+	depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS
 	select I2C_ALGOBIT
 	help
 	  Say yes if you want to support the I2C serial bus on ARMs Versatile
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 64c1023..a829338 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -143,19 +143,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called bf54x-keys.
 
-config KEYBOARD_CORGI
-	tristate "Corgi keyboard (deprecated)"
-	depends on PXA_SHARPSL
-	help
-	  Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
-	  series of PDAs.
-
-	  This driver is now deprecated, use generic GPIO based matrix
-	  keyboard driver instead.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called corgikbd.
-
 config KEYBOARD_LKKBD
 	tristate "DECstation/VAXstation LK201/LK401 keyboard"
 	select SERIO
@@ -339,19 +326,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called pxa930_rotary.
 
-config KEYBOARD_SPITZ
-	tristate "Spitz keyboard (deprecated)"
-	depends on PXA_SHARPSL
-	help
-	  Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
-	  SL-C3000 and Sl-C3100 series of PDAs.
-
-	  This driver is now deprecated, use generic GPIO based matrix
-	  keyboard driver instead.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called spitzkbd.
-
 config KEYBOARD_STOWAWAY
 	tristate "Stowaway keyboard"
 	select SERIO
@@ -414,28 +388,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called twl4030_keypad.
 
-config KEYBOARD_TOSA
-	tristate "Tosa keyboard (deprecated)"
-	depends on MACH_TOSA
-	help
-	  Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
-
-	  This driver is now deprecated, use generic GPIO based matrix
-	  keyboard driver instead.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called tosakbd.
-
-config KEYBOARD_TOSA_USE_EXT_KEYCODES
-	bool "Tosa keyboard: use extended keycodes"
-	depends on KEYBOARD_TOSA
-	help
-	  Say Y here to enable the tosa keyboard driver to generate extended
-	  (>= 127) keycodes. Be aware, that they can't be correctly interpreted
-	  by either console keyboard driver or by Kdrive keybd driver.
-
-	  Say Y only if you know, what you are doing!
-
 config KEYBOARD_XTKBD
 	tristate "XT keyboard"
 	select SERIO
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 706c6b5..9a74127e 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -11,7 +11,6 @@
 obj-$(CONFIG_KEYBOARD_ATARI)		+= atakbd.o
 obj-$(CONFIG_KEYBOARD_ATKBD)		+= atkbd.o
 obj-$(CONFIG_KEYBOARD_BFIN)		+= bf54x-keys.o
-obj-$(CONFIG_KEYBOARD_CORGI)		+= corgikbd.o
 obj-$(CONFIG_KEYBOARD_DAVINCI)		+= davinci_keyscan.o
 obj-$(CONFIG_KEYBOARD_EP93XX)		+= ep93xx_keypad.o
 obj-$(CONFIG_KEYBOARD_GPIO)		+= gpio_keys.o
@@ -33,10 +32,8 @@
 obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)	+= pxa930_rotary.o
 obj-$(CONFIG_KEYBOARD_QT2160)		+= qt2160.o
 obj-$(CONFIG_KEYBOARD_SH_KEYSC)		+= sh_keysc.o
-obj-$(CONFIG_KEYBOARD_SPITZ)		+= spitzkbd.o
 obj-$(CONFIG_KEYBOARD_STOWAWAY)		+= stowaway.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)		+= sunkbd.o
-obj-$(CONFIG_KEYBOARD_TOSA)		+= tosakbd.o
 obj-$(CONFIG_KEYBOARD_TWL4030)		+= twl4030_keypad.o
 obj-$(CONFIG_KEYBOARD_XTKBD)		+= xtkbd.o
 obj-$(CONFIG_KEYBOARD_W90P910)		+= w90p910_keypad.o
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
deleted file mode 100644
index 634af6a..0000000
--- a/drivers/input/keyboard/corgikbd.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- *  Keyboard driver for Sharp Corgi models (SL-C7xx)
- *
- *  Copyright (c) 2004-2005 Richard Purdie
- *
- *  Based on xtkbd.c/locomkbd.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/delay.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/jiffies.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <mach/corgi.h>
-#include <mach/pxa2xx-gpio.h>
-#include <asm/hardware/scoop.h>
-
-#define KB_ROWS				8
-#define KB_COLS				12
-#define KB_ROWMASK(r)		(1 << (r))
-#define SCANCODE(r,c)		( ((r)<<4) + (c) + 1 )
-/* zero code, 124 scancodes */
-#define	NR_SCANCODES		( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 )
-
-#define SCAN_INTERVAL		(50) /* ms */
-#define HINGE_SCAN_INTERVAL	(250) /* ms */
-
-#define CORGI_KEY_CALENDER	KEY_F1
-#define CORGI_KEY_ADDRESS	KEY_F2
-#define CORGI_KEY_FN		KEY_F3
-#define CORGI_KEY_CANCEL	KEY_F4
-#define CORGI_KEY_OFF		KEY_SUSPEND
-#define CORGI_KEY_EXOK		KEY_F5
-#define CORGI_KEY_EXCANCEL	KEY_F6
-#define CORGI_KEY_EXJOGDOWN	KEY_F7
-#define CORGI_KEY_EXJOGUP	KEY_F8
-#define CORGI_KEY_JAP1		KEY_LEFTCTRL
-#define CORGI_KEY_JAP2		KEY_LEFTALT
-#define CORGI_KEY_MAIL		KEY_F10
-#define CORGI_KEY_OK		KEY_F11
-#define CORGI_KEY_MENU		KEY_F12
-
-static unsigned char corgikbd_keycode[NR_SCANCODES] = {
-	0,                                                                                                                /* 0 */
-	0, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, 0, 0, 0, 0, 0, 0, 0, 	                      /* 1-16 */
-	0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, 0, 0, 0, 0, 0, 0, 0,                                   /* 17-32 */
-	KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0,                                 /* 33-48 */
-	CORGI_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,         /* 49-64 */
-	CORGI_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, 0, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 	  /* 65-80 */
-	CORGI_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, 0, CORGI_KEY_FN, 0, 0, 0, 0,            /* 81-96 */
-	KEY_SYSRQ, CORGI_KEY_JAP1, CORGI_KEY_JAP2, CORGI_KEY_CANCEL, CORGI_KEY_OK, CORGI_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0,  /* 97-112 */
-	CORGI_KEY_OFF, CORGI_KEY_EXOK, CORGI_KEY_EXCANCEL, CORGI_KEY_EXJOGDOWN, CORGI_KEY_EXJOGUP, 0, 0, 0, 0, 0, 0, 0,   /* 113-124 */
-};
-
-
-struct corgikbd {
-	unsigned char keycode[ARRAY_SIZE(corgikbd_keycode)];
-	struct input_dev *input;
-
-	spinlock_t lock;
-	struct timer_list timer;
-	struct timer_list htimer;
-
-	unsigned int suspended;
-	unsigned long suspend_jiffies;
-};
-
-#define KB_DISCHARGE_DELAY	10
-#define KB_ACTIVATE_DELAY	10
-
-/* Helper functions for reading the keyboard matrix
- * Note: We should really be using the generic gpio functions to alter
- *       GPDR but it requires a function call per GPIO bit which is
- *       excessive when we need to access 12 bits at once, multiple times.
- * These functions must be called within local_irq_save()/local_irq_restore()
- * or similar.
- */
-static inline void corgikbd_discharge_all(void)
-{
-	/* STROBE All HiZ */
-	GPCR2  = CORGI_GPIO_ALL_STROBE_BIT;
-	GPDR2 &= ~CORGI_GPIO_ALL_STROBE_BIT;
-}
-
-static inline void corgikbd_activate_all(void)
-{
-	/* STROBE ALL -> High */
-	GPSR2  = CORGI_GPIO_ALL_STROBE_BIT;
-	GPDR2 |= CORGI_GPIO_ALL_STROBE_BIT;
-
-	udelay(KB_DISCHARGE_DELAY);
-
-	/* Clear any interrupts we may have triggered when altering the GPIO lines */
-	GEDR1 = CORGI_GPIO_HIGH_SENSE_BIT;
-	GEDR2 = CORGI_GPIO_LOW_SENSE_BIT;
-}
-
-static inline void corgikbd_activate_col(int col)
-{
-	/* STROBE col -> High, not col -> HiZ */
-	GPSR2 = CORGI_GPIO_STROBE_BIT(col);
-	GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col);
-}
-
-static inline void corgikbd_reset_col(int col)
-{
-	/* STROBE col -> Low */
-	GPCR2 = CORGI_GPIO_STROBE_BIT(col);
-	/* STROBE col -> out, not col -> HiZ */
-	GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col);
-}
-
-#define GET_ROWS_STATUS(c)	(((GPLR1 & CORGI_GPIO_HIGH_SENSE_BIT) >> CORGI_GPIO_HIGH_SENSE_RSHIFT) | ((GPLR2 & CORGI_GPIO_LOW_SENSE_BIT) << CORGI_GPIO_LOW_SENSE_LSHIFT))
-
-/*
- * The corgi keyboard only generates interrupts when a key is pressed.
- * When a key is pressed, we enable a timer which then scans the
- * keyboard to detect when the key is released.
- */
-
-/* Scan the hardware keyboard and push any changes up through the input layer */
-static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data)
-{
-	unsigned int row, col, rowd;
-	unsigned long flags;
-	unsigned int num_pressed;
-
-	if (corgikbd_data->suspended)
-		return;
-
-	spin_lock_irqsave(&corgikbd_data->lock, flags);
-
-	num_pressed = 0;
-	for (col = 0; col < KB_COLS; col++) {
-		/*
-		 * Discharge the output driver capacitatance
-		 * in the keyboard matrix. (Yes it is significant..)
-		 */
-
-		corgikbd_discharge_all();
-		udelay(KB_DISCHARGE_DELAY);
-
-		corgikbd_activate_col(col);
-		udelay(KB_ACTIVATE_DELAY);
-
-		rowd = GET_ROWS_STATUS(col);
-		for (row = 0; row < KB_ROWS; row++) {
-			unsigned int scancode, pressed;
-
-			scancode = SCANCODE(row, col);
-			pressed = rowd & KB_ROWMASK(row);
-
-			input_report_key(corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
-
-			if (pressed)
-				num_pressed++;
-
-			if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
-					&& time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) {
-				input_event(corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
-				corgikbd_data->suspend_jiffies=jiffies;
-			}
-		}
-		corgikbd_reset_col(col);
-	}
-
-	corgikbd_activate_all();
-
-	input_sync(corgikbd_data->input);
-
-	/* if any keys are pressed, enable the timer */
-	if (num_pressed)
-		mod_timer(&corgikbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL));
-
-	spin_unlock_irqrestore(&corgikbd_data->lock, flags);
-}
-
-/*
- * corgi keyboard interrupt handler.
- */
-static irqreturn_t corgikbd_interrupt(int irq, void *dev_id)
-{
-	struct corgikbd *corgikbd_data = dev_id;
-
-	if (!timer_pending(&corgikbd_data->timer)) {
-		/** wait chattering delay **/
-		udelay(20);
-		corgikbd_scankeyboard(corgikbd_data);
-	}
-
-	return IRQ_HANDLED;
-}
-
-/*
- * corgi timer checking for released keys
- */
-static void corgikbd_timer_callback(unsigned long data)
-{
-	struct corgikbd *corgikbd_data = (struct corgikbd *) data;
-	corgikbd_scankeyboard(corgikbd_data);
-}
-
-/*
- * The hinge switches generate no interrupt so they need to be
- * monitored by a timer.
- *
- * We debounce the switches and pass them to the input system.
- *
- *  gprr == 0x00 - Keyboard with Landscape Screen
- *          0x08 - No Keyboard with Portrait Screen
- *          0x0c - Keyboard and Screen Closed
- */
-
-#define READ_GPIO_BIT(x)    (GPLR(x) & GPIO_bit(x))
-#define HINGE_STABLE_COUNT 2
-static int sharpsl_hinge_state;
-static int hinge_count;
-
-static void corgikbd_hinge_timer(unsigned long data)
-{
-	struct corgikbd *corgikbd_data = (struct corgikbd *) data;
-	unsigned long gprr;
-	unsigned long flags;
-
-	gprr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_GPRR) & (CORGI_SCP_SWA | CORGI_SCP_SWB);
-	gprr |= (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0);
-	if (gprr != sharpsl_hinge_state) {
-		hinge_count = 0;
-		sharpsl_hinge_state = gprr;
-	} else if (hinge_count < HINGE_STABLE_COUNT) {
-		hinge_count++;
-		if (hinge_count >= HINGE_STABLE_COUNT) {
-			spin_lock_irqsave(&corgikbd_data->lock, flags);
-
-			input_report_switch(corgikbd_data->input, SW_LID, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
-			input_report_switch(corgikbd_data->input, SW_TABLET_MODE, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
-			input_report_switch(corgikbd_data->input, SW_HEADPHONE_INSERT, (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0));
-			input_sync(corgikbd_data->input);
-
-			spin_unlock_irqrestore(&corgikbd_data->lock, flags);
-		}
-	}
-	mod_timer(&corgikbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-}
-
-#ifdef CONFIG_PM
-static int corgikbd_suspend(struct platform_device *dev, pm_message_t state)
-{
-	int i;
-	struct corgikbd *corgikbd = platform_get_drvdata(dev);
-
-	corgikbd->suspended = 1;
-	/* strobe 0 is the power key so this can't be made an input for
-	   powersaving therefore i = 1 */
-	for (i = 1; i < CORGI_KEY_STROBE_NUM; i++)
-		pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_IN);
-
-	return 0;
-}
-
-static int corgikbd_resume(struct platform_device *dev)
-{
-	int i;
-	struct corgikbd *corgikbd = platform_get_drvdata(dev);
-
-	for (i = 1; i < CORGI_KEY_STROBE_NUM; i++)
-		pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
-
-	/* Upon resume, ignore the suspend key for a short while */
-	corgikbd->suspend_jiffies=jiffies;
-	corgikbd->suspended = 0;
-
-	return 0;
-}
-#else
-#define corgikbd_suspend	NULL
-#define corgikbd_resume		NULL
-#endif
-
-static int __devinit corgikbd_probe(struct platform_device *pdev)
-{
-	struct corgikbd *corgikbd;
-	struct input_dev *input_dev;
-	int i, err = -ENOMEM;
-
-	corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!corgikbd || !input_dev)
-		goto fail;
-
-	platform_set_drvdata(pdev, corgikbd);
-
-	corgikbd->input = input_dev;
-	spin_lock_init(&corgikbd->lock);
-
-	/* Init Keyboard rescan timer */
-	init_timer(&corgikbd->timer);
-	corgikbd->timer.function = corgikbd_timer_callback;
-	corgikbd->timer.data = (unsigned long) corgikbd;
-
-	/* Init Hinge Timer */
-	init_timer(&corgikbd->htimer);
-	corgikbd->htimer.function = corgikbd_hinge_timer;
-	corgikbd->htimer.data = (unsigned long) corgikbd;
-
-	corgikbd->suspend_jiffies=jiffies;
-
-	memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode));
-
-	input_dev->name = "Corgi Keyboard";
-	input_dev->phys = "corgikbd/input0";
-	input_dev->id.bustype = BUS_HOST;
-	input_dev->id.vendor = 0x0001;
-	input_dev->id.product = 0x0001;
-	input_dev->id.version = 0x0100;
-	input_dev->dev.parent = &pdev->dev;
-
-	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
-		BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
-	input_dev->keycode = corgikbd->keycode;
-	input_dev->keycodesize = sizeof(unsigned char);
-	input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
-
-	for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
-		set_bit(corgikbd->keycode[i], input_dev->keybit);
-	clear_bit(0, input_dev->keybit);
-	set_bit(SW_LID, input_dev->swbit);
-	set_bit(SW_TABLET_MODE, input_dev->swbit);
-	set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
-
-	err = input_register_device(corgikbd->input);
-	if (err)
-		goto fail;
-
-	mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-
-	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
-	for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) {
-		pxa_gpio_mode(CORGI_GPIO_KEY_SENSE(i) | GPIO_IN);
-		if (request_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd_interrupt,
-				IRQF_DISABLED | IRQF_TRIGGER_RISING,
-				"corgikbd", corgikbd))
-			printk(KERN_WARNING "corgikbd: Can't get IRQ: %d!\n", i);
-	}
-
-	/* Set Strobe lines as outputs - set high */
-	for (i = 0; i < CORGI_KEY_STROBE_NUM; i++)
-		pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
-
-	/* Setup the headphone jack as an input */
-	pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN);
-
-	return 0;
-
- fail:	input_free_device(input_dev);
-	kfree(corgikbd);
-	return err;
-}
-
-static int __devexit corgikbd_remove(struct platform_device *pdev)
-{
-	int i;
-	struct corgikbd *corgikbd = platform_get_drvdata(pdev);
-
-	for (i = 0; i < CORGI_KEY_SENSE_NUM; i++)
-		free_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd);
-
-	del_timer_sync(&corgikbd->htimer);
-	del_timer_sync(&corgikbd->timer);
-
-	input_unregister_device(corgikbd->input);
-
-	kfree(corgikbd);
-
-	return 0;
-}
-
-static struct platform_driver corgikbd_driver = {
-	.probe		= corgikbd_probe,
-	.remove		= __devexit_p(corgikbd_remove),
-	.suspend	= corgikbd_suspend,
-	.resume		= corgikbd_resume,
-	.driver		= {
-		.name	= "corgi-keyboard",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init corgikbd_init(void)
-{
-	return platform_driver_register(&corgikbd_driver);
-}
-
-static void __exit corgikbd_exit(void)
-{
-	platform_driver_unregister(&corgikbd_driver);
-}
-
-module_init(corgikbd_init);
-module_exit(corgikbd_exit);
-
-MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
-MODULE_DESCRIPTION("Corgi Keyboard Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:corgi-keyboard");
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
deleted file mode 100644
index 1396742..0000000
--- a/drivers/input/keyboard/spitzkbd.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- *  Keyboard driver for Sharp Spitz, Borzoi and Akita (SL-Cxx00 series)
- *
- *  Copyright (c) 2005 Richard Purdie
- *
- *  Based on corgikbd.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/delay.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/jiffies.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <mach/spitz.h>
-#include <mach/pxa2xx-gpio.h>
-
-#define KB_ROWS			7
-#define KB_COLS			11
-#define KB_ROWMASK(r)		(1 << (r))
-#define SCANCODE(r,c)		(((r)<<4) + (c) + 1)
-#define	NR_SCANCODES		((KB_ROWS<<4) + 1)
-
-#define SCAN_INTERVAL		(50) /* ms */
-#define HINGE_SCAN_INTERVAL	(150) /* ms */
-
-#define SPITZ_KEY_CALENDER	KEY_F1
-#define SPITZ_KEY_ADDRESS	KEY_F2
-#define SPITZ_KEY_FN		KEY_F3
-#define SPITZ_KEY_CANCEL	KEY_F4
-#define SPITZ_KEY_EXOK		KEY_F5
-#define SPITZ_KEY_EXCANCEL	KEY_F6
-#define SPITZ_KEY_EXJOGDOWN	KEY_F7
-#define SPITZ_KEY_EXJOGUP	KEY_F8
-#define SPITZ_KEY_JAP1		KEY_LEFTALT
-#define SPITZ_KEY_JAP2		KEY_RIGHTCTRL
-#define SPITZ_KEY_SYNC		KEY_F9
-#define SPITZ_KEY_MAIL		KEY_F10
-#define SPITZ_KEY_OK		KEY_F11
-#define SPITZ_KEY_MENU		KEY_F12
-
-static unsigned char spitzkbd_keycode[NR_SCANCODES] = {
-	0,                                                                                                                /* 0 */
-	KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0,  /* 1-16 */
-	0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */
-	KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0,                                 /* 33-48 */
-	SPITZ_KEY_ADDRESS, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,         /* 49-64 */
-	SPITZ_KEY_CALENDER, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0,	  /* 65-80 */
-	SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0,      /* 81-96 */
-	KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0  /* 97-112 */
-};
-
-static int spitz_strobes[] = {
-	SPITZ_GPIO_KEY_STROBE0,
-	SPITZ_GPIO_KEY_STROBE1,
-	SPITZ_GPIO_KEY_STROBE2,
-	SPITZ_GPIO_KEY_STROBE3,
-	SPITZ_GPIO_KEY_STROBE4,
-	SPITZ_GPIO_KEY_STROBE5,
-	SPITZ_GPIO_KEY_STROBE6,
-	SPITZ_GPIO_KEY_STROBE7,
-	SPITZ_GPIO_KEY_STROBE8,
-	SPITZ_GPIO_KEY_STROBE9,
-	SPITZ_GPIO_KEY_STROBE10,
-};
-
-static int spitz_senses[] = {
-	SPITZ_GPIO_KEY_SENSE0,
-	SPITZ_GPIO_KEY_SENSE1,
-	SPITZ_GPIO_KEY_SENSE2,
-	SPITZ_GPIO_KEY_SENSE3,
-	SPITZ_GPIO_KEY_SENSE4,
-	SPITZ_GPIO_KEY_SENSE5,
-	SPITZ_GPIO_KEY_SENSE6,
-};
-
-struct spitzkbd {
-	unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)];
-	struct input_dev *input;
-	char phys[32];
-
-	spinlock_t lock;
-	struct timer_list timer;
-	struct timer_list htimer;
-
-	unsigned int suspended;
-	unsigned long suspend_jiffies;
-};
-
-#define KB_DISCHARGE_DELAY	10
-#define KB_ACTIVATE_DELAY	10
-
-/* Helper functions for reading the keyboard matrix
- * Note: We should really be using the generic gpio functions to alter
- *       GPDR but it requires a function call per GPIO bit which is
- *       excessive when we need to access 11 bits at once, multiple times.
- * These functions must be called within local_irq_save()/local_irq_restore()
- * or similar.
- */
-static inline void spitzkbd_discharge_all(void)
-{
-	/* STROBE All HiZ */
-	GPCR0  =  SPITZ_GPIO_G0_STROBE_BIT;
-	GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
-	GPCR1  =  SPITZ_GPIO_G1_STROBE_BIT;
-	GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
-	GPCR2  =  SPITZ_GPIO_G2_STROBE_BIT;
-	GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
-	GPCR3  =  SPITZ_GPIO_G3_STROBE_BIT;
-	GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
-}
-
-static inline void spitzkbd_activate_all(void)
-{
-	/* STROBE ALL -> High */
-	GPSR0  =  SPITZ_GPIO_G0_STROBE_BIT;
-	GPDR0 |=  SPITZ_GPIO_G0_STROBE_BIT;
-	GPSR1  =  SPITZ_GPIO_G1_STROBE_BIT;
-	GPDR1 |=  SPITZ_GPIO_G1_STROBE_BIT;
-	GPSR2  =  SPITZ_GPIO_G2_STROBE_BIT;
-	GPDR2 |=  SPITZ_GPIO_G2_STROBE_BIT;
-	GPSR3  =  SPITZ_GPIO_G3_STROBE_BIT;
-	GPDR3 |=  SPITZ_GPIO_G3_STROBE_BIT;
-
-	udelay(KB_DISCHARGE_DELAY);
-
-	/* Clear any interrupts we may have triggered when altering the GPIO lines */
-	GEDR0 = SPITZ_GPIO_G0_SENSE_BIT;
-	GEDR1 = SPITZ_GPIO_G1_SENSE_BIT;
-	GEDR2 = SPITZ_GPIO_G2_SENSE_BIT;
-	GEDR3 = SPITZ_GPIO_G3_SENSE_BIT;
-}
-
-static inline void spitzkbd_activate_col(int col)
-{
-	int gpio = spitz_strobes[col];
-	GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
-	GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
-	GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
-	GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
-	GPSR(gpio) = GPIO_bit(gpio);
-	GPDR(gpio) |= GPIO_bit(gpio);
-}
-
-static inline void spitzkbd_reset_col(int col)
-{
-	int gpio = spitz_strobes[col];
-	GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
-	GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
-	GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
-	GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
-	GPCR(gpio) = GPIO_bit(gpio);
-	GPDR(gpio) |= GPIO_bit(gpio);
-}
-
-static inline int spitzkbd_get_row_status(int col)
-{
-	return ((GPLR0 >> 12) & 0x01) | ((GPLR0 >> 16) & 0x02)
-		| ((GPLR2 >> 25) & 0x04) | ((GPLR1 << 1) & 0x08)
-		| ((GPLR1 >> 0) & 0x10) | ((GPLR1 >> 1) & 0x60);
-}
-
-/*
- * The spitz keyboard only generates interrupts when a key is pressed.
- * When a key is pressed, we enable a timer which then scans the
- * keyboard to detect when the key is released.
- */
-
-/* Scan the hardware keyboard and push any changes up through the input layer */
-static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data)
-{
-	unsigned int row, col, rowd;
-	unsigned long flags;
-	unsigned int num_pressed, pwrkey = ((GPLR(SPITZ_GPIO_ON_KEY) & GPIO_bit(SPITZ_GPIO_ON_KEY)) != 0);
-
-	if (spitzkbd_data->suspended)
-		return;
-
-	spin_lock_irqsave(&spitzkbd_data->lock, flags);
-
-	num_pressed = 0;
-	for (col = 0; col < KB_COLS; col++) {
-		/*
-		 * Discharge the output driver capacitatance
-		 * in the keyboard matrix. (Yes it is significant..)
-		 */
-
-		spitzkbd_discharge_all();
-		udelay(KB_DISCHARGE_DELAY);
-
-		spitzkbd_activate_col(col);
-		udelay(KB_ACTIVATE_DELAY);
-
-		rowd = spitzkbd_get_row_status(col);
-		for (row = 0; row < KB_ROWS; row++) {
-			unsigned int scancode, pressed;
-
-			scancode = SCANCODE(row, col);
-			pressed = rowd & KB_ROWMASK(row);
-
-			input_report_key(spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
-
-			if (pressed)
-				num_pressed++;
-		}
-		spitzkbd_reset_col(col);
-	}
-
-	spitzkbd_activate_all();
-
-	input_report_key(spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
-	input_report_key(spitzkbd_data->input, KEY_SUSPEND, pwrkey);
-
-	if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) {
-		input_event(spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
-		spitzkbd_data->suspend_jiffies = jiffies;
-	}
-
-	input_sync(spitzkbd_data->input);
-
-	/* if any keys are pressed, enable the timer */
-	if (num_pressed)
-		mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL));
-
-	spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
-}
-
-/*
- * spitz keyboard interrupt handler.
- */
-static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id)
-{
-	struct spitzkbd *spitzkbd_data = dev_id;
-
-	if (!timer_pending(&spitzkbd_data->timer)) {
-		/** wait chattering delay **/
-		udelay(20);
-		spitzkbd_scankeyboard(spitzkbd_data);
-	}
-
-	return IRQ_HANDLED;
-}
-
-/*
- * spitz timer checking for released keys
- */
-static void spitzkbd_timer_callback(unsigned long data)
-{
-	struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
-
-	spitzkbd_scankeyboard(spitzkbd_data);
-}
-
-/*
- * The hinge switches generate an interrupt.
- * We debounce the switches and pass them to the input system.
- */
-
-static irqreturn_t spitzkbd_hinge_isr(int irq, void *dev_id)
-{
-	struct spitzkbd *spitzkbd_data = dev_id;
-
-	if (!timer_pending(&spitzkbd_data->htimer))
-		mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-
-	return IRQ_HANDLED;
-}
-
-#define HINGE_STABLE_COUNT 2
-static int sharpsl_hinge_state;
-static int hinge_count;
-
-static void spitzkbd_hinge_timer(unsigned long data)
-{
-	struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
-	unsigned long state;
-	unsigned long flags;
-
-	state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB));
-	state |= (GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT));
-	if (state != sharpsl_hinge_state) {
-		hinge_count = 0;
-		sharpsl_hinge_state = state;
-	} else if (hinge_count < HINGE_STABLE_COUNT) {
-		hinge_count++;
-	}
-
-	if (hinge_count >= HINGE_STABLE_COUNT) {
-		spin_lock_irqsave(&spitzkbd_data->lock, flags);
-
-		input_report_switch(spitzkbd_data->input, SW_LID, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
-		input_report_switch(spitzkbd_data->input, SW_TABLET_MODE, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
-		input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0));
-		input_sync(spitzkbd_data->input);
-
-		spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
-	} else {
-		mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-	}
-}
-
-#ifdef CONFIG_PM
-static int spitzkbd_suspend(struct platform_device *dev, pm_message_t state)
-{
-	int i;
-	struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
-	spitzkbd->suspended = 1;
-
-	/* Set Strobe lines as inputs - *except* strobe line 0 leave this
-	   enabled so we can detect a power button press for resume */
-	for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
-		pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
-
-	return 0;
-}
-
-static int spitzkbd_resume(struct platform_device *dev)
-{
-	int i;
-	struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
-
-	for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
-		pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
-
-	/* Upon resume, ignore the suspend key for a short while */
-	spitzkbd->suspend_jiffies = jiffies;
-	spitzkbd->suspended = 0;
-
-	return 0;
-}
-#else
-#define spitzkbd_suspend	NULL
-#define spitzkbd_resume		NULL
-#endif
-
-static int __devinit spitzkbd_probe(struct platform_device *dev)
-{
-	struct spitzkbd *spitzkbd;
-	struct input_dev *input_dev;
-	int i, err = -ENOMEM;
-
-	spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!spitzkbd || !input_dev)
-		goto fail;
-
-	platform_set_drvdata(dev, spitzkbd);
-	strcpy(spitzkbd->phys, "spitzkbd/input0");
-
-	spin_lock_init(&spitzkbd->lock);
-
-	/* Init Keyboard rescan timer */
-	init_timer(&spitzkbd->timer);
-	spitzkbd->timer.function = spitzkbd_timer_callback;
-	spitzkbd->timer.data = (unsigned long) spitzkbd;
-
-	/* Init Hinge Timer */
-	init_timer(&spitzkbd->htimer);
-	spitzkbd->htimer.function = spitzkbd_hinge_timer;
-	spitzkbd->htimer.data = (unsigned long) spitzkbd;
-
-	spitzkbd->suspend_jiffies = jiffies;
-
-	spitzkbd->input = input_dev;
-
-	input_dev->name = "Spitz Keyboard";
-	input_dev->phys = spitzkbd->phys;
-	input_dev->dev.parent = &dev->dev;
-
-	input_dev->id.bustype = BUS_HOST;
-	input_dev->id.vendor = 0x0001;
-	input_dev->id.product = 0x0001;
-	input_dev->id.version = 0x0100;
-
-	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
-		BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
-	input_dev->keycode = spitzkbd->keycode;
-	input_dev->keycodesize = sizeof(unsigned char);
-	input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode);
-
-	memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode));
-	for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++)
-		set_bit(spitzkbd->keycode[i], input_dev->keybit);
-	clear_bit(0, input_dev->keybit);
-	set_bit(KEY_SUSPEND, input_dev->keybit);
-	set_bit(SW_LID, input_dev->swbit);
-	set_bit(SW_TABLET_MODE, input_dev->swbit);
-	set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
-
-	err = input_register_device(input_dev);
-	if (err)
-		goto fail;
-
-	mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-
-	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
-	for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) {
-		pxa_gpio_mode(spitz_senses[i] | GPIO_IN);
-		if (request_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd_interrupt,
-				IRQF_DISABLED|IRQF_TRIGGER_RISING,
-				"Spitzkbd Sense", spitzkbd))
-			printk(KERN_WARNING "spitzkbd: Can't get Sense IRQ: %d!\n", i);
-	}
-
-	/* Set Strobe lines as outputs - set high */
-	for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
-		pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
-
-	pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
-	pxa_gpio_mode(SPITZ_GPIO_ON_KEY | GPIO_IN);
-	pxa_gpio_mode(SPITZ_GPIO_SWA | GPIO_IN);
-	pxa_gpio_mode(SPITZ_GPIO_SWB | GPIO_IN);
-
-	request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt,
-		    IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-		    "Spitzkbd Sync", spitzkbd);
-	request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt,
-		    IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-		    "Spitzkbd PwrOn", spitzkbd);
-	request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr,
-		    IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-		    "Spitzkbd SWA", spitzkbd);
-	request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr,
-		    IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-		    "Spitzkbd SWB", spitzkbd);
-	request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr,
-		    IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-		    "Spitzkbd HP", spitzkbd);
-
-	return 0;
-
- fail:	input_free_device(input_dev);
-	kfree(spitzkbd);
-	return err;
-}
-
-static int __devexit spitzkbd_remove(struct platform_device *dev)
-{
-	int i;
-	struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
-
-	for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++)
-		free_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd);
-
-	free_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd);
-	free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd);
-	free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd);
-	free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd);
-	free_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd);
-
-	del_timer_sync(&spitzkbd->htimer);
-	del_timer_sync(&spitzkbd->timer);
-
-	input_unregister_device(spitzkbd->input);
-
-	kfree(spitzkbd);
-
-	return 0;
-}
-
-static struct platform_driver spitzkbd_driver = {
-	.probe		= spitzkbd_probe,
-	.remove		= __devexit_p(spitzkbd_remove),
-	.suspend	= spitzkbd_suspend,
-	.resume		= spitzkbd_resume,
-	.driver		= {
-		.name	= "spitz-keyboard",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init spitzkbd_init(void)
-{
-	return platform_driver_register(&spitzkbd_driver);
-}
-
-static void __exit spitzkbd_exit(void)
-{
-	platform_driver_unregister(&spitzkbd_driver);
-}
-
-module_init(spitzkbd_init);
-module_exit(spitzkbd_exit);
-
-MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
-MODULE_DESCRIPTION("Spitz Keyboard Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:spitz-keyboard");
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c
deleted file mode 100644
index 3910f26..0000000
--- a/drivers/input/keyboard/tosakbd.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- *  Keyboard driver for Sharp Tosa models (SL-6000x)
- *
- *  Copyright (c) 2005 Dirk Opfer
- *  Copyright (c) 2007 Dmitry Baryshkov
- *
- *  Based on xtkbd.c/locomkbd.c/corgikbd.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/module.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-#include <mach/gpio.h>
-#include <mach/tosa.h>
-
-#define KB_ROWMASK(r)		(1 << (r))
-#define SCANCODE(r, c)		(((r)<<4) + (c) + 1)
-#define NR_SCANCODES		SCANCODE(TOSA_KEY_SENSE_NUM - 1, TOSA_KEY_STROBE_NUM - 1) + 1
-
-#define SCAN_INTERVAL		(HZ/10)
-
-#define KB_DISCHARGE_DELAY	10
-#define KB_ACTIVATE_DELAY	10
-
-static unsigned short tosakbd_keycode[NR_SCANCODES] = {
-0,
-0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P,
-0, 0, 0, 0, 0, 0, 0, 0,
-KEY_Q, KEY_E, KEY_T, KEY_Y, 0, KEY_O, KEY_I, KEY_COMMA,
-0, 0, 0, 0, 0, 0, 0, 0,
-KEY_A, KEY_D, KEY_G, KEY_U, 0, KEY_L, KEY_ENTER, KEY_DOT,
-0, 0, 0, 0, 0, 0, 0, 0,
-KEY_Z, KEY_C, KEY_V, KEY_J, TOSA_KEY_ADDRESSBOOK, TOSA_KEY_CANCEL, TOSA_KEY_CENTER, TOSA_KEY_OK,
-KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, 0,
-KEY_S, KEY_R, KEY_B, KEY_N, TOSA_KEY_CALENDAR, TOSA_KEY_HOMEPAGE, KEY_LEFTCTRL, TOSA_KEY_LIGHT,
-0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,
-KEY_TAB, KEY_SLASH, KEY_H, KEY_M, TOSA_KEY_MENU, 0, KEY_UP, 0,
-0, 0, TOSA_KEY_FN, 0, 0, 0, 0, 0,
-KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_RIGHT,
-0, 0, 0,
-};
-
-struct tosakbd {
-	unsigned short keycode[ARRAY_SIZE(tosakbd_keycode)];
-	struct input_dev *input;
-	bool suspended;
-	spinlock_t lock; /* protect kbd scanning */
-	struct timer_list timer;
-};
-
-
-/* Helper functions for reading the keyboard matrix
- * Note: We should really be using the generic gpio functions to alter
- *       GPDR but it requires a function call per GPIO bit which is
- *       excessive when we need to access 12 bits at once, multiple times.
- * These functions must be called within local_irq_save()/local_irq_restore()
- * or similar.
- */
-#define GET_ROWS_STATUS(c)	((GPLR2 & TOSA_GPIO_ALL_SENSE_BIT) >> TOSA_GPIO_ALL_SENSE_RSHIFT)
-
-static inline void tosakbd_discharge_all(void)
-{
-	/* STROBE All HiZ */
-	GPCR1  = TOSA_GPIO_HIGH_STROBE_BIT;
-	GPDR1 &= ~TOSA_GPIO_HIGH_STROBE_BIT;
-	GPCR2  = TOSA_GPIO_LOW_STROBE_BIT;
-	GPDR2 &= ~TOSA_GPIO_LOW_STROBE_BIT;
-}
-
-static inline void tosakbd_activate_all(void)
-{
-	/* STROBE ALL -> High */
-	GPSR1  = TOSA_GPIO_HIGH_STROBE_BIT;
-	GPDR1 |= TOSA_GPIO_HIGH_STROBE_BIT;
-	GPSR2  = TOSA_GPIO_LOW_STROBE_BIT;
-	GPDR2 |= TOSA_GPIO_LOW_STROBE_BIT;
-
-	udelay(KB_DISCHARGE_DELAY);
-
-	/* STATE CLEAR */
-	GEDR2 |= TOSA_GPIO_ALL_SENSE_BIT;
-}
-
-static inline void tosakbd_activate_col(int col)
-{
-	if (col <= 5) {
-		/* STROBE col -> High, not col -> HiZ */
-		GPSR1 = TOSA_GPIO_STROBE_BIT(col);
-		GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
-	} else {
-		/* STROBE col -> High, not col -> HiZ */
-		GPSR2 = TOSA_GPIO_STROBE_BIT(col);
-		GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
-	}
-}
-
-static inline void tosakbd_reset_col(int col)
-{
-	if (col <= 5) {
-		/* STROBE col -> Low */
-		GPCR1 = TOSA_GPIO_STROBE_BIT(col);
-		/* STROBE col -> out, not col -> HiZ */
-		GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
-	} else {
-		/* STROBE col -> Low */
-		GPCR2 = TOSA_GPIO_STROBE_BIT(col);
-		/* STROBE col -> out, not col -> HiZ */
-		GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
-	}
-}
-/*
- * The tosa keyboard only generates interrupts when a key is pressed.
- * So when a key is pressed, we enable a timer.  This timer scans the
- * keyboard, and this is how we detect when the key is released.
- */
-
-/* Scan the hardware keyboard and push any changes up through the input layer */
-static void tosakbd_scankeyboard(struct platform_device *dev)
-{
-	struct tosakbd *tosakbd = platform_get_drvdata(dev);
-	unsigned int row, col, rowd;
-	unsigned long flags;
-	unsigned int num_pressed = 0;
-
-	spin_lock_irqsave(&tosakbd->lock, flags);
-
-	if (tosakbd->suspended)
-		goto out;
-
-	for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) {
-		/*
-		 * Discharge the output driver capacitatance
-		 * in the keyboard matrix. (Yes it is significant..)
-		 */
-		tosakbd_discharge_all();
-		udelay(KB_DISCHARGE_DELAY);
-
-		tosakbd_activate_col(col);
-		udelay(KB_ACTIVATE_DELAY);
-
-		rowd = GET_ROWS_STATUS(col);
-
-		for (row = 0; row < TOSA_KEY_SENSE_NUM; row++) {
-			unsigned int scancode, pressed;
-			scancode = SCANCODE(row, col);
-			pressed = rowd & KB_ROWMASK(row);
-
-			if (pressed && !tosakbd->keycode[scancode])
-				dev_warn(&dev->dev,
-						"unhandled scancode: 0x%02x\n",
-						scancode);
-
-			input_report_key(tosakbd->input,
-					tosakbd->keycode[scancode],
-					pressed);
-			if (pressed)
-				num_pressed++;
-		}
-
-		tosakbd_reset_col(col);
-	}
-
-	tosakbd_activate_all();
-
-	input_sync(tosakbd->input);
-
-	/* if any keys are pressed, enable the timer */
-	if (num_pressed)
-		mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL);
-
- out:
-	spin_unlock_irqrestore(&tosakbd->lock, flags);
-}
-
-/*
- * tosa keyboard interrupt handler.
- */
-static irqreturn_t tosakbd_interrupt(int irq, void *__dev)
-{
-	struct platform_device *dev = __dev;
-	struct tosakbd *tosakbd = platform_get_drvdata(dev);
-
-	if (!timer_pending(&tosakbd->timer)) {
-		/** wait chattering delay **/
-		udelay(20);
-		tosakbd_scankeyboard(dev);
-	}
-
-	return IRQ_HANDLED;
-}
-
-/*
- * tosa timer checking for released keys
- */
-static void tosakbd_timer_callback(unsigned long __dev)
-{
-	struct platform_device *dev = (struct platform_device *)__dev;
-
-	tosakbd_scankeyboard(dev);
-}
-
-#ifdef CONFIG_PM
-static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
-{
-	struct tosakbd *tosakbd = platform_get_drvdata(dev);
-	unsigned long flags;
-
-	spin_lock_irqsave(&tosakbd->lock, flags);
-	tosakbd->suspended = true;
-	spin_unlock_irqrestore(&tosakbd->lock, flags);
-
-	del_timer_sync(&tosakbd->timer);
-
-	return 0;
-}
-
-static int tosakbd_resume(struct platform_device *dev)
-{
-	struct tosakbd *tosakbd = platform_get_drvdata(dev);
-
-	tosakbd->suspended = false;
-	tosakbd_scankeyboard(dev);
-
-	return 0;
-}
-#else
-#define tosakbd_suspend		NULL
-#define tosakbd_resume		NULL
-#endif
-
-static int __devinit tosakbd_probe(struct platform_device *pdev) {
-
-	int i;
-	struct tosakbd *tosakbd;
-	struct input_dev *input_dev;
-	int error;
-
-	tosakbd = kzalloc(sizeof(struct tosakbd), GFP_KERNEL);
-	if (!tosakbd)
-		return -ENOMEM;
-
-	input_dev = input_allocate_device();
-	if (!input_dev) {
-		kfree(tosakbd);
-		return -ENOMEM;
-	}
-
-	platform_set_drvdata(pdev, tosakbd);
-
-	spin_lock_init(&tosakbd->lock);
-
-	/* Init Keyboard rescan timer */
-	init_timer(&tosakbd->timer);
-	tosakbd->timer.function = tosakbd_timer_callback;
-	tosakbd->timer.data = (unsigned long) pdev;
-
-	tosakbd->input = input_dev;
-
-	input_set_drvdata(input_dev, tosakbd);
-	input_dev->name = "Tosa Keyboard";
-	input_dev->phys = "tosakbd/input0";
-	input_dev->dev.parent = &pdev->dev;
-
-	input_dev->id.bustype = BUS_HOST;
-	input_dev->id.vendor = 0x0001;
-	input_dev->id.product = 0x0001;
-	input_dev->id.version = 0x0100;
-
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-	input_dev->keycode = tosakbd->keycode;
-	input_dev->keycodesize = sizeof(tosakbd->keycode[0]);
-	input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode);
-
-	memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode));
-
-	for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++)
-		__set_bit(tosakbd->keycode[i], input_dev->keybit);
-	__clear_bit(KEY_RESERVED, input_dev->keybit);
-
-	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
-	for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
-		int gpio = TOSA_GPIO_KEY_SENSE(i);
-		int irq;
-		error = gpio_request(gpio, "tosakbd");
-		if (error < 0) {
-			printk(KERN_ERR "tosakbd: failed to request GPIO %d, "
-				" error %d\n", gpio, error);
-			goto fail;
-		}
-
-		error = gpio_direction_input(TOSA_GPIO_KEY_SENSE(i));
-		if (error < 0) {
-			printk(KERN_ERR "tosakbd: failed to configure input"
-				" direction for GPIO %d, error %d\n",
-				gpio, error);
-			gpio_free(gpio);
-			goto fail;
-		}
-
-		irq = gpio_to_irq(gpio);
-		if (irq < 0) {
-			error = irq;
-			printk(KERN_ERR "gpio-keys: Unable to get irq number"
-				" for GPIO %d, error %d\n",
-				gpio, error);
-			gpio_free(gpio);
-			goto fail;
-		}
-
-		error = request_irq(irq, tosakbd_interrupt,
-					IRQF_DISABLED | IRQF_TRIGGER_RISING,
-					"tosakbd", pdev);
-
-		if (error) {
-			printk("tosakbd: Can't get IRQ: %d: error %d!\n",
-					irq, error);
-			gpio_free(gpio);
-			goto fail;
-		}
-	}
-
-	/* Set Strobe lines as outputs - set high */
-	for (i = 0; i < TOSA_KEY_STROBE_NUM; i++) {
-		int gpio = TOSA_GPIO_KEY_STROBE(i);
-		error = gpio_request(gpio, "tosakbd");
-		if (error < 0) {
-			printk(KERN_ERR "tosakbd: failed to request GPIO %d, "
-				" error %d\n", gpio, error);
-			goto fail2;
-		}
-
-		error = gpio_direction_output(gpio, 1);
-		if (error < 0) {
-			printk(KERN_ERR "tosakbd: failed to configure input"
-				" direction for GPIO %d, error %d\n",
-				gpio, error);
-			gpio_free(gpio);
-			goto fail2;
-		}
-
-	}
-
-	error = input_register_device(input_dev);
-	if (error) {
-		printk(KERN_ERR "tosakbd: Unable to register input device, "
-			"error: %d\n", error);
-		goto fail2;
-	}
-
-	printk(KERN_INFO "input: Tosa Keyboard Registered\n");
-
-	return 0;
-
-fail2:
-	while (--i >= 0)
-		gpio_free(TOSA_GPIO_KEY_STROBE(i));
-
-	i = TOSA_KEY_SENSE_NUM;
-fail:
-	while (--i >= 0) {
-		free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), pdev);
-		gpio_free(TOSA_GPIO_KEY_SENSE(i));
-	}
-
-	platform_set_drvdata(pdev, NULL);
-	input_free_device(input_dev);
-	kfree(tosakbd);
-
-	return error;
-}
-
-static int __devexit tosakbd_remove(struct platform_device *dev)
-{
-	int i;
-	struct tosakbd *tosakbd = platform_get_drvdata(dev);
-
-	for (i = 0; i < TOSA_KEY_STROBE_NUM; i++)
-		gpio_free(TOSA_GPIO_KEY_STROBE(i));
-
-	for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
-		free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), dev);
-		gpio_free(TOSA_GPIO_KEY_SENSE(i));
-	}
-
-	del_timer_sync(&tosakbd->timer);
-
-	input_unregister_device(tosakbd->input);
-
-	kfree(tosakbd);
-
-	return 0;
-}
-
-static struct platform_driver tosakbd_driver = {
-	.probe		= tosakbd_probe,
-	.remove		= __devexit_p(tosakbd_remove),
-	.suspend	= tosakbd_suspend,
-	.resume		= tosakbd_resume,
-	.driver		= {
-		.name	= "tosa-keyboard",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __devinit tosakbd_init(void)
-{
-	return platform_driver_register(&tosakbd_driver);
-}
-
-static void __exit tosakbd_exit(void)
-{
-	platform_driver_unregister(&tosakbd_driver);
-}
-
-module_init(tosakbd_init);
-module_exit(tosakbd_exit);
-
-MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
-MODULE_DESCRIPTION("Tosa Keyboard Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tosa-keyboard");
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 8a8fa4d..3d1ade2 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -99,22 +99,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called h3600_ts_input.
 
-config TOUCHSCREEN_CORGI
-	tristate "SharpSL (Corgi and Spitz series) touchscreen driver (DEPRECATED)"
-	depends on PXA_SHARPSL
-	select CORGI_SSP_DEPRECATED
-	help
-	  Say Y here to enable the driver for the touchscreen on the
-	  Sharp SL-C7xx and SL-Cxx00 series of PDAs.
-
-	  If unsure, say N.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called corgi_ts.
-
-	  NOTE: this driver is deprecated, try enable SPI and generic
-	  ADS7846-based touchscreen driver.
-
 config TOUCHSCREEN_DA9034
 	tristate "Touchscreen support for Dialog Semiconductor DA9034"
 	depends on PMIC_DA903X
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 7fef7d5..41145d0 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -12,7 +12,6 @@
 obj-$(CONFIG_TOUCHSCREEN_ADS7846)	+= ads7846.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)	+= atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)		+= h3600_ts_input.o
-obj-$(CONFIG_TOUCHSCREEN_CORGI)		+= corgi_ts.o
 obj-$(CONFIG_TOUCHSCREEN_DYNAPRO)	+= dynapro.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)		+= gunze.o
 obj-$(CONFIG_TOUCHSCREEN_EETI)		+= eeti_ts.o
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
deleted file mode 100644
index 94a1919..0000000
--- a/drivers/input/touchscreen/corgi_ts.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- *  Touchscreen driver for Sharp SL-C7xx and SL-Cxx00 models
- *
- *  Copyright (c) 2004-2005 Richard Purdie
- *
- *  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/platform_device.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-
-#include <mach/sharpsl.h>
-#include <mach/hardware.h>
-#include <mach/pxa2xx-gpio.h>
-
-
-#define PWR_MODE_ACTIVE		0
-#define PWR_MODE_SUSPEND	1
-
-#define X_AXIS_MAX		3830
-#define X_AXIS_MIN		150
-#define Y_AXIS_MAX		3830
-#define Y_AXIS_MIN		190
-#define PRESSURE_MIN		0
-#define PRESSURE_MAX		15000
-
-struct ts_event {
-	short pressure;
-	short x;
-	short y;
-};
-
-struct corgi_ts {
-	struct input_dev *input;
-	struct timer_list timer;
-	struct ts_event tc;
-	int pendown;
-	int power_mode;
-	int irq_gpio;
-	struct corgits_machinfo *machinfo;
-};
-
-#ifdef CONFIG_PXA25x
-#define CCNT(a)		asm volatile ("mrc p14, 0, %0, C1, C0, 0" : "=r"(a))
-#define PMNC_GET(x)	asm volatile ("mrc p14, 0, %0, C0, C0, 0" : "=r"(x))
-#define PMNC_SET(x)	asm volatile ("mcr p14, 0, %0, C0, C0, 0" : : "r"(x))
-#endif
-#ifdef CONFIG_PXA27x
-#define CCNT(a)		asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a))
-#define PMNC_GET(x)	asm volatile ("mrc p14, 0, %0, C0, C1, 0" : "=r"(x))
-#define PMNC_SET(x)	asm volatile ("mcr p14, 0, %0, C0, C1, 0" : : "r"(x))
-#endif
-
-/* ADS7846 Touch Screen Controller bit definitions */
-#define ADSCTRL_PD0		(1u << 0)	/* PD0 */
-#define ADSCTRL_PD1		(1u << 1)	/* PD1 */
-#define ADSCTRL_DFR		(1u << 2)	/* SER/DFR */
-#define ADSCTRL_MOD		(1u << 3)	/* Mode */
-#define ADSCTRL_ADR_SH	4	/* Address setting */
-#define ADSCTRL_STS		(1u << 7)	/* Start Bit */
-
-/* External Functions */
-extern unsigned int get_clk_frequency_khz(int info);
-
-static unsigned long calc_waittime(struct corgi_ts *corgi_ts)
-{
-	unsigned long hsync_invperiod = corgi_ts->machinfo->get_hsync_invperiod();
-
-	if (hsync_invperiod)
-		return get_clk_frequency_khz(0)*1000/hsync_invperiod;
-	else
-		return 0;
-}
-
-static int sync_receive_data_send_cmd(struct corgi_ts *corgi_ts, int doRecive, int doSend,
-		unsigned int address, unsigned long wait_time)
-{
-	unsigned long timer1 = 0, timer2, pmnc = 0;
-	int pos = 0;
-
-	if (wait_time && doSend) {
-		PMNC_GET(pmnc);
-		if (!(pmnc & 0x01))
-			PMNC_SET(0x01);
-
-		/* polling HSync */
-		corgi_ts->machinfo->wait_hsync();
-		/* get CCNT */
-		CCNT(timer1);
-	}
-
-	if (doRecive)
-		pos = corgi_ssp_ads7846_get();
-
-	if (doSend) {
-		int cmd = ADSCTRL_PD0 | ADSCTRL_PD1 | (address << ADSCTRL_ADR_SH) | ADSCTRL_STS;
-		/* dummy command */
-		corgi_ssp_ads7846_put(cmd);
-		corgi_ssp_ads7846_get();
-
-		if (wait_time) {
-			/* Wait after HSync */
-			CCNT(timer2);
-			if (timer2-timer1 > wait_time) {
-				/* too slow - timeout, try again */
-				corgi_ts->machinfo->wait_hsync();
-				/* get CCNT */
-				CCNT(timer1);
-				/* Wait after HSync */
-				CCNT(timer2);
-			}
-			while (timer2 - timer1 < wait_time)
-				CCNT(timer2);
-		}
-		corgi_ssp_ads7846_put(cmd);
-		if (wait_time && !(pmnc & 0x01))
-			PMNC_SET(pmnc);
-	}
-	return pos;
-}
-
-static int read_xydata(struct corgi_ts *corgi_ts)
-{
-	unsigned int x, y, z1, z2;
-	unsigned long flags, wait_time;
-
-	/* critical section */
-	local_irq_save(flags);
-	corgi_ssp_ads7846_lock();
-	wait_time = calc_waittime(corgi_ts);
-
-	/* Y-axis */
-	sync_receive_data_send_cmd(corgi_ts, 0, 1, 1u, wait_time);
-
-	/* Y-axis */
-	sync_receive_data_send_cmd(corgi_ts, 1, 1, 1u, wait_time);
-
-	/* X-axis */
-	y = sync_receive_data_send_cmd(corgi_ts, 1, 1, 5u, wait_time);
-
-	/* Z1 */
-	x = sync_receive_data_send_cmd(corgi_ts, 1, 1, 3u, wait_time);
-
-	/* Z2 */
-	z1 = sync_receive_data_send_cmd(corgi_ts, 1, 1, 4u, wait_time);
-	z2 = sync_receive_data_send_cmd(corgi_ts, 1, 0, 4u, wait_time);
-
-	/* Power-Down Enable */
-	corgi_ssp_ads7846_put((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-	corgi_ssp_ads7846_get();
-
-	corgi_ssp_ads7846_unlock();
-	local_irq_restore(flags);
-
-	if (x== 0 || y == 0 || z1 == 0 || (x * (z2 - z1) / z1) >= 15000) {
-		corgi_ts->tc.pressure = 0;
-		return 0;
-	}
-
-	corgi_ts->tc.x = x;
-	corgi_ts->tc.y = y;
-	corgi_ts->tc.pressure = (x * (z2 - z1)) / z1;
-	return 1;
-}
-
-static void new_data(struct corgi_ts *corgi_ts)
-{
-	struct input_dev *dev = corgi_ts->input;
-
-	if (corgi_ts->power_mode != PWR_MODE_ACTIVE)
-		return;
-
-	if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0)
-		return;
-
-	input_report_abs(dev, ABS_X, corgi_ts->tc.x);
-	input_report_abs(dev, ABS_Y, corgi_ts->tc.y);
-	input_report_abs(dev, ABS_PRESSURE, corgi_ts->tc.pressure);
-	input_report_key(dev, BTN_TOUCH, corgi_ts->pendown);
-	input_sync(dev);
-}
-
-static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer)
-{
-	if ((GPLR(IRQ_TO_GPIO(corgi_ts->irq_gpio)) & GPIO_bit(IRQ_TO_GPIO(corgi_ts->irq_gpio))) == 0) {
-		/* Disable Interrupt */
-		set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_NONE);
-		if (read_xydata(corgi_ts)) {
-			corgi_ts->pendown = 1;
-			new_data(corgi_ts);
-		}
-		mod_timer(&corgi_ts->timer, jiffies + HZ / 100);
-	} else {
-		if (corgi_ts->pendown == 1 || corgi_ts->pendown == 2) {
-			mod_timer(&corgi_ts->timer, jiffies + HZ / 100);
-			corgi_ts->pendown++;
-			return;
-		}
-
-		if (corgi_ts->pendown) {
-			corgi_ts->tc.pressure = 0;
-			new_data(corgi_ts);
-		}
-
-		/* Enable Falling Edge */
-		set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING);
-		corgi_ts->pendown = 0;
-	}
-}
-
-static void corgi_ts_timer(unsigned long data)
-{
-	struct corgi_ts *corgits_data = (struct corgi_ts *) data;
-
-	ts_interrupt_main(corgits_data, 1);
-}
-
-static irqreturn_t ts_interrupt(int irq, void *dev_id)
-{
-	struct corgi_ts *corgits_data = dev_id;
-
-	ts_interrupt_main(corgits_data, 0);
-	return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_PM
-static int corgits_suspend(struct platform_device *dev, pm_message_t state)
-{
-	struct corgi_ts *corgi_ts = platform_get_drvdata(dev);
-
-	if (corgi_ts->pendown) {
-		del_timer_sync(&corgi_ts->timer);
-		corgi_ts->tc.pressure = 0;
-		new_data(corgi_ts);
-		corgi_ts->pendown = 0;
-	}
-	corgi_ts->power_mode = PWR_MODE_SUSPEND;
-
-	corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-
-	return 0;
-}
-
-static int corgits_resume(struct platform_device *dev)
-{
-	struct corgi_ts *corgi_ts = platform_get_drvdata(dev);
-
-	corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-	/* Enable Falling Edge */
-	set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING);
-	corgi_ts->power_mode = PWR_MODE_ACTIVE;
-
-	return 0;
-}
-#else
-#define corgits_suspend		NULL
-#define corgits_resume		NULL
-#endif
-
-static int __devinit corgits_probe(struct platform_device *pdev)
-{
-	struct corgi_ts *corgi_ts;
-	struct input_dev *input_dev;
-	int err = -ENOMEM;
-
-	corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!corgi_ts || !input_dev)
-		goto fail1;
-
-	platform_set_drvdata(pdev, corgi_ts);
-
-	corgi_ts->machinfo = pdev->dev.platform_data;
-	corgi_ts->irq_gpio = platform_get_irq(pdev, 0);
-
-	if (corgi_ts->irq_gpio < 0) {
-		err = -ENODEV;
-		goto fail1;
-	}
-
-	corgi_ts->input = input_dev;
-
-	init_timer(&corgi_ts->timer);
-	corgi_ts->timer.data = (unsigned long) corgi_ts;
-	corgi_ts->timer.function = corgi_ts_timer;
-
-	input_dev->name = "Corgi Touchscreen";
-	input_dev->phys = "corgits/input0";
-	input_dev->id.bustype = BUS_HOST;
-	input_dev->id.vendor = 0x0001;
-	input_dev->id.product = 0x0002;
-	input_dev->id.version = 0x0100;
-	input_dev->dev.parent = &pdev->dev;
-
-	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-	input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
-	input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
-	input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
-
-	pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN);
-
-	/* Initiaize ADS7846 Difference Reference mode */
-	corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-	mdelay(5);
-	corgi_ssp_ads7846_putget((3u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-	mdelay(5);
-	corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-	mdelay(5);
-	corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-	mdelay(5);
-
-	if (request_irq(corgi_ts->irq_gpio, ts_interrupt, IRQF_DISABLED, "ts", corgi_ts)) {
-		err = -EBUSY;
-		goto fail1;
-	}
-
-	err = input_register_device(corgi_ts->input);
-	if (err)
-		goto fail2;
-
-	corgi_ts->power_mode = PWR_MODE_ACTIVE;
-
-	/* Enable Falling Edge */
-	set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING);
-
-	return 0;
-
- fail2:	free_irq(corgi_ts->irq_gpio, corgi_ts);
- fail1:	input_free_device(input_dev);
-	kfree(corgi_ts);
-	return err;
-}
-
-static int __devexit corgits_remove(struct platform_device *pdev)
-{
-	struct corgi_ts *corgi_ts = platform_get_drvdata(pdev);
-
-	free_irq(corgi_ts->irq_gpio, corgi_ts);
-	del_timer_sync(&corgi_ts->timer);
-	corgi_ts->machinfo->put_hsync();
-	input_unregister_device(corgi_ts->input);
-	kfree(corgi_ts);
-
-	return 0;
-}
-
-static struct platform_driver corgits_driver = {
-	.probe		= corgits_probe,
-	.remove		= __devexit_p(corgits_remove),
-	.suspend	= corgits_suspend,
-	.resume		= corgits_resume,
-	.driver		= {
-		.name	= "corgi-ts",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init corgits_init(void)
-{
-	return platform_driver_register(&corgits_driver);
-}
-
-static void __exit corgits_exit(void)
-{
-	platform_driver_unregister(&corgits_driver);
-}
-
-module_init(corgits_init);
-module_exit(corgits_exit);
-
-MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
-MODULE_DESCRIPTION("Corgi TouchScreen Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:corgi-ts");
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 84c103a..ff115d9 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -55,14 +55,16 @@
 			host->cclk = host->mclk / (2 * (clk + 1));
 		}
 		if (host->hw_designer == AMBA_VENDOR_ST)
-			clk |= MCI_FCEN; /* Bug fix in ST IP block */
+			clk |= MCI_ST_FCEN; /* Bug fix in ST IP block */
 		clk |= MCI_CLK_ENABLE;
 		/* This hasn't proven to be worthwhile */
 		/* clk |= MCI_CLK_PWRSAVE; */
 	}
 
 	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
-		clk |= MCI_WIDE_BUS;
+		clk |= MCI_4BIT_BUS;
+	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
+		clk |= MCI_ST_8BIT_BUS;
 
 	writel(clk, host->base + MMCICLOCK);
 }
@@ -629,7 +631,18 @@
 
 	mmc->ops = &mmci_ops;
 	mmc->f_min = (host->mclk + 511) / 512;
-	mmc->f_max = min(host->mclk, fmax);
+	/*
+	 * If the platform data supplies a maximum operating
+	 * frequency, this takes precedence. Else, we fall back
+	 * to using the module parameter, which has a (low)
+	 * default value in case it is not specified. Either
+	 * value must not exceed the clock rate into the block,
+	 * of course.
+	 */
+	if (plat->f_max)
+		mmc->f_max = min(host->mclk, plat->f_max);
+	else
+		mmc->f_max = min(host->mclk, fmax);
 	dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
 
 #ifdef CONFIG_REGULATOR
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 1ceb9a9..d77062e 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -25,9 +25,11 @@
 #define MCI_CLK_ENABLE		(1 << 8)
 #define MCI_CLK_PWRSAVE		(1 << 9)
 #define MCI_CLK_BYPASS		(1 << 10)
-#define MCI_WIDE_BUS		(1 << 11)
+#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_FCEN		(1 << 13)
+#define MCI_ST_FCEN		(1 << 13)
 
 #define MMCIARGUMENT		0x008
 #define MMCICOMMAND		0x00c
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 0ed4895..e4f00e7 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -544,7 +544,7 @@
 {
 	struct pxamci_host *host = mmc_priv(devid);
 
-	mmc_detect_change(devid, host->pdata->detect_delay);
+	mmc_detect_change(devid, msecs_to_jiffies(host->pdata->detect_delay_ms));
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index d189e47..a44733d 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -234,7 +234,8 @@
 	depends on ARM && ARCH_PXA && PCMCIA
 	depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
 		    || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
-		    || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2)
+		    || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
+		    || MACH_VPAC270)
 	select PCMCIA_SOC_COMMON
 	help
 	  Say Y here to include support for the PXA2xx PCMCIA controller
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 381b031..4dae361 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -66,6 +66,7 @@
 pxa2xx-obj-$(CONFIG_MACH_PALMLD)		+= pxa2xx_palmld.o
 pxa2xx-obj-$(CONFIG_MACH_E740)			+= pxa2xx_e740.o
 pxa2xx-obj-$(CONFIG_MACH_STARGATE2)		+= pxa2xx_stargate2.o
+pxa2xx-obj-$(CONFIG_MACH_VPAC270)		+= pxa2xx_vpac270.o
 
 obj-$(CONFIG_PCMCIA_PXA2XX)			+= pxa2xx_base.o $(pxa2xx-obj-y)
 
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c
new file mode 100644
index 0000000..55627ec
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_vpac270.c
@@ -0,0 +1,229 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_vpac270.c
+ *
+ * Driver for Voipac PXA270 PCMCIA and CF sockets
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.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/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/gpio.h>
+#include <mach/vpac270.h>
+
+#include "soc_common.h"
+
+static struct pcmcia_irqs cd_irqs[] = {
+	{
+		.sock = 0,
+		.irq  = IRQ_GPIO(GPIO84_VPAC270_PCMCIA_CD),
+		.str  = "PCMCIA CD"
+	},
+	{
+		.sock = 1,
+		.irq  = IRQ_GPIO(GPIO17_VPAC270_CF_CD),
+		.str  = "CF CD"
+	},
+};
+
+static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	int ret;
+
+	if (skt->nr == 0) {
+		ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD");
+		if (ret)
+			goto err1;
+		ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD);
+		if (ret)
+			goto err2;
+
+		ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY");
+		if (ret)
+			goto err2;
+		ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY);
+		if (ret)
+			goto err3;
+
+		ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN");
+		if (ret)
+			goto err3;
+		ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0);
+		if (ret)
+			goto err4;
+
+		ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET");
+		if (ret)
+			goto err4;
+		ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0);
+		if (ret)
+			goto err5;
+
+		skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
+
+		return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
+
+err5:
+		gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
+err4:
+		gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
+err3:
+		gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
+err2:
+		gpio_free(GPIO84_VPAC270_PCMCIA_CD);
+err1:
+		return ret;
+
+	} else {
+		ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD");
+		if (ret)
+			goto err6;
+		ret = gpio_direction_input(GPIO17_VPAC270_CF_CD);
+		if (ret)
+			goto err7;
+
+		ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY");
+		if (ret)
+			goto err7;
+		ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY);
+		if (ret)
+			goto err8;
+
+		ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET");
+		if (ret)
+			goto err8;
+		ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0);
+		if (ret)
+			goto err9;
+
+		skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
+
+		return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
+
+err9:
+		gpio_free(GPIO16_VPAC270_CF_RESET);
+err8:
+		gpio_free(GPIO12_VPAC270_CF_RDY);
+err7:
+		gpio_free(GPIO17_VPAC270_CF_CD);
+err6:
+		return ret;
+
+	}
+}
+
+static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+	gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
+	gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
+	gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
+	gpio_free(GPIO84_VPAC270_PCMCIA_CD);
+	gpio_free(GPIO16_VPAC270_CF_RESET);
+	gpio_free(GPIO12_VPAC270_CF_RDY);
+	gpio_free(GPIO17_VPAC270_CF_CD);
+}
+
+static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+					struct pcmcia_state *state)
+{
+	if (skt->nr == 0) {
+		state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD);
+		state->ready  = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY);
+	} else {
+		state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD);
+		state->ready  = !!gpio_get_value(GPIO12_VPAC270_CF_RDY);
+	}
+	state->bvd1   = 1;
+	state->bvd2   = 1;
+	state->wrprot = 0;
+	state->vs_3v  = 1;
+	state->vs_Xv  = 0;
+}
+
+static int
+vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+				const socket_state_t *state)
+{
+	if (skt->nr == 0) {
+		gpio_set_value(GPIO11_VPAC270_PCMCIA_RESET,
+			(state->flags & SS_RESET));
+		gpio_set_value(GPIO107_VPAC270_PCMCIA_PPEN,
+			!(state->Vcc == 33 || state->Vcc == 50));
+	} else {
+		gpio_set_value(GPIO16_VPAC270_CF_RESET,
+			(state->flags & SS_RESET));
+	}
+
+	return 0;
+}
+
+static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level vpac270_pcmcia_ops = {
+	.owner			= THIS_MODULE,
+
+	.first			= 0,
+	.nr			= 2,
+
+	.hw_init		= vpac270_pcmcia_hw_init,
+	.hw_shutdown		= vpac270_pcmcia_hw_shutdown,
+
+	.socket_state		= vpac270_pcmcia_socket_state,
+	.configure_socket	= vpac270_pcmcia_configure_socket,
+
+	.socket_init		= vpac270_pcmcia_socket_init,
+	.socket_suspend		= vpac270_pcmcia_socket_suspend,
+};
+
+static struct platform_device *vpac270_pcmcia_device;
+
+static int __init vpac270_pcmcia_init(void)
+{
+	int ret;
+
+	if (!machine_is_vpac270())
+		return -ENODEV;
+
+	vpac270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+	if (!vpac270_pcmcia_device)
+		return -ENOMEM;
+
+	ret = platform_device_add_data(vpac270_pcmcia_device,
+		&vpac270_pcmcia_ops, sizeof(vpac270_pcmcia_ops));
+
+	if (!ret)
+		ret = platform_device_add(vpac270_pcmcia_device);
+
+	if (ret)
+		platform_device_put(vpac270_pcmcia_device);
+
+	return ret;
+}
+
+static void __exit vpac270_pcmcia_exit(void)
+{
+	platform_device_unregister(vpac270_pcmcia_device);
+}
+
+module_init(vpac270_pcmcia_init);
+module_exit(vpac270_pcmcia_exit);
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("PCMCIA support for Voipac PXA270");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index f55c494..5f3f03d 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -518,12 +518,13 @@
 	  Serial port support for the Samsung S3C2412 and S3C2413 SoC
 
 config SERIAL_S3C2440
-	tristate "Samsung S3C2440/S3C2442 Serial port support"
-	depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442)
+	tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support"
+	depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416)
 	default y if CPU_S3C2440
 	default y if CPU_S3C2442
+	select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416
 	help
-	  Serial port support for the Samsung S3C2440 and S3C2442 SoC
+	  Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC
 
 config SERIAL_S3C24A0
 	tristate "Samsung S3C24A0 Serial port support"
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 2c9bf9b..eed3c2d 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -38,6 +38,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/atmel_pdc.h>
 #include <linux/atmel_serial.h>
+#include <linux/uaccess.h>
 
 #include <asm/io.h>
 
@@ -59,6 +60,9 @@
 
 #include <linux/serial_core.h>
 
+static void atmel_start_rx(struct uart_port *port);
+static void atmel_stop_rx(struct uart_port *port);
+
 #ifdef CONFIG_SERIAL_ATMEL_TTYAT
 
 /* Use device name ttyAT, major 204 and minor 154-169.  This is necessary if we
@@ -93,6 +97,7 @@
 #define UART_GET_BRGR(port)	__raw_readl((port)->membase + ATMEL_US_BRGR)
 #define UART_PUT_BRGR(port,v)	__raw_writel(v, (port)->membase + ATMEL_US_BRGR)
 #define UART_PUT_RTOR(port,v)	__raw_writel(v, (port)->membase + ATMEL_US_RTOR)
+#define UART_PUT_TTGR(port, v)	__raw_writel(v, (port)->membase + ATMEL_US_TTGR)
 
  /* PDC registers */
 #define UART_PUT_PTCR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_PTCR)
@@ -147,6 +152,9 @@
 	unsigned int		irq_status_prev;
 
 	struct circ_buf		rx_ring;
+
+	struct serial_rs485	rs485;		/* rs485 settings */
+	unsigned int		tx_done_mask;
 };
 
 static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
@@ -187,6 +195,46 @@
 }
 #endif
 
+/* Enable or disable the rs485 support */
+void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
+{
+	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+	unsigned int mode;
+
+	spin_lock(&port->lock);
+
+	/* Disable interrupts */
+	UART_PUT_IDR(port, atmel_port->tx_done_mask);
+
+	mode = UART_GET_MR(port);
+
+	/* Resetting serial mode to RS232 (0x0) */
+	mode &= ~ATMEL_US_USMODE;
+
+	atmel_port->rs485 = *rs485conf;
+
+	if (rs485conf->flags & SER_RS485_ENABLED) {
+		dev_dbg(port->dev, "Setting UART to RS485\n");
+		atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
+		UART_PUT_TTGR(port, rs485conf->delay_rts_before_send);
+		mode |= ATMEL_US_USMODE_RS485;
+	} else {
+		dev_dbg(port->dev, "Setting UART to RS232\n");
+		if (atmel_use_dma_tx(port))
+			atmel_port->tx_done_mask = ATMEL_US_ENDTX |
+				ATMEL_US_TXBUFE;
+		else
+			atmel_port->tx_done_mask = ATMEL_US_TXRDY;
+	}
+	UART_PUT_MR(port, mode);
+
+	/* Enable interrupts */
+	UART_PUT_IER(port, atmel_port->tx_done_mask);
+
+	spin_unlock(&port->lock);
+
+}
+
 /*
  * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
  */
@@ -202,6 +250,7 @@
 {
 	unsigned int control = 0;
 	unsigned int mode;
+	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
 #ifdef CONFIG_ARCH_AT91RM9200
 	if (cpu_is_at91rm9200()) {
@@ -236,6 +285,17 @@
 		mode |= ATMEL_US_CHMODE_LOC_LOOP;
 	else
 		mode |= ATMEL_US_CHMODE_NORMAL;
+
+	/* Resetting serial mode to RS232 (0x0) */
+	mode &= ~ATMEL_US_USMODE;
+
+	if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
+		dev_dbg(port->dev, "Setting UART to RS485\n");
+		UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);
+		mode |= ATMEL_US_USMODE_RS485;
+	} else {
+		dev_dbg(port->dev, "Setting UART to RS232\n");
+	}
 	UART_PUT_MR(port, mode);
 }
 
@@ -268,12 +328,17 @@
  */
 static void atmel_stop_tx(struct uart_port *port)
 {
+	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
 	if (atmel_use_dma_tx(port)) {
 		/* disable PDC transmit */
 		UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS);
-		UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
-	} else
-		UART_PUT_IDR(port, ATMEL_US_TXRDY);
+	}
+	/* Disable interrupts */
+	UART_PUT_IDR(port, atmel_port->tx_done_mask);
+
+	if (atmel_port->rs485.flags & SER_RS485_ENABLED)
+		atmel_start_rx(port);
 }
 
 /*
@@ -281,17 +346,39 @@
  */
 static void atmel_start_tx(struct uart_port *port)
 {
+	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
 	if (atmel_use_dma_tx(port)) {
 		if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN)
 			/* The transmitter is already running.  Yes, we
 			   really need this.*/
 			return;
 
-		UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
+		if (atmel_port->rs485.flags & SER_RS485_ENABLED)
+			atmel_stop_rx(port);
+
 		/* re-enable PDC transmit */
 		UART_PUT_PTCR(port, ATMEL_PDC_TXTEN);
-	} else
-		UART_PUT_IER(port, ATMEL_US_TXRDY);
+	}
+	/* Enable interrupts */
+	UART_PUT_IER(port, atmel_port->tx_done_mask);
+}
+
+/*
+ * start receiving - port is in process of being opened.
+ */
+static void atmel_start_rx(struct uart_port *port)
+{
+	UART_PUT_CR(port, ATMEL_US_RSTSTA);  /* reset status and receiver */
+
+	if (atmel_use_dma_rx(port)) {
+		/* enable PDC controller */
+		UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
+			port->read_status_mask);
+		UART_PUT_PTCR(port, ATMEL_PDC_RXTEN);
+	} else {
+		UART_PUT_IER(port, ATMEL_US_RXRDY);
+	}
 }
 
 /*
@@ -302,9 +389,11 @@
 	if (atmel_use_dma_rx(port)) {
 		/* disable PDC receive */
 		UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS);
-		UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);
-	} else
+		UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
+			port->read_status_mask);
+	} else {
 		UART_PUT_IDR(port, ATMEL_US_RXRDY);
+	}
 }
 
 /*
@@ -428,8 +517,9 @@
 static void atmel_tx_chars(struct uart_port *port)
 {
 	struct circ_buf *xmit = &port->state->xmit;
+	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-	if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) {
+	if (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) {
 		UART_PUT_CHAR(port, port->x_char);
 		port->icount.tx++;
 		port->x_char = 0;
@@ -437,7 +527,7 @@
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
 		return;
 
-	while (UART_GET_CSR(port) & ATMEL_US_TXRDY) {
+	while (UART_GET_CSR(port) & atmel_port->tx_done_mask) {
 		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 		port->icount.tx++;
@@ -449,7 +539,8 @@
 		uart_write_wakeup(port);
 
 	if (!uart_circ_empty(xmit))
-		UART_PUT_IER(port, ATMEL_US_TXRDY);
+		/* Enable interrupts */
+		UART_PUT_IER(port, atmel_port->tx_done_mask);
 }
 
 /*
@@ -501,18 +592,10 @@
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-	if (atmel_use_dma_tx(port)) {
-		/* PDC transmit */
-		if (pending & (ATMEL_US_ENDTX | ATMEL_US_TXBUFE)) {
-			UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
-			tasklet_schedule(&atmel_port->tasklet);
-		}
-	} else {
-		/* Interrupt transmit */
-		if (pending & ATMEL_US_TXRDY) {
-			UART_PUT_IDR(port, ATMEL_US_TXRDY);
-			tasklet_schedule(&atmel_port->tasklet);
-		}
+	if (pending & atmel_port->tx_done_mask) {
+		/* Either PDC or interrupt transmission */
+		UART_PUT_IDR(port, atmel_port->tx_done_mask);
+		tasklet_schedule(&atmel_port->tasklet);
 	}
 }
 
@@ -590,9 +673,15 @@
 
 		UART_PUT_TPR(port, pdc->dma_addr + xmit->tail);
 		UART_PUT_TCR(port, count);
-		/* re-enable PDC transmit and interrupts */
+		/* re-enable PDC transmit */
 		UART_PUT_PTCR(port, ATMEL_PDC_TXTEN);
-		UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
+		/* Enable interrupts */
+		UART_PUT_IER(port, atmel_port->tx_done_mask);
+	} else {
+		if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
+			/* DMA done, stop TX, start RX for RS485 */
+			atmel_start_rx(port);
+		}
 	}
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
@@ -1017,6 +1106,7 @@
 {
 	unsigned long flags;
 	unsigned int mode, imr, quot, baud;
+	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
 	/* Get current mode register */
 	mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL
@@ -1115,6 +1205,17 @@
 	/* disable receiver and transmitter */
 	UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS);
 
+	/* Resetting serial mode to RS232 (0x0) */
+	mode &= ~ATMEL_US_USMODE;
+
+	if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
+		dev_dbg(port->dev, "Setting UART to RS485\n");
+		UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);
+		mode |= ATMEL_US_USMODE_RS485;
+	} else {
+		dev_dbg(port->dev, "Setting UART to RS232\n");
+	}
+
 	/* set the parity, stop bits and data size */
 	UART_PUT_MR(port, mode);
 
@@ -1231,6 +1332,35 @@
 }
 #endif
 
+static int
+atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg)
+{
+	struct serial_rs485 rs485conf;
+
+	switch (cmd) {
+	case TIOCSRS485:
+		if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg,
+					sizeof(rs485conf)))
+			return -EFAULT;
+
+		atmel_config_rs485(port, &rs485conf);
+		break;
+
+	case TIOCGRS485:
+		if (copy_to_user((struct serial_rs485 *) arg,
+					&(to_atmel_uart_port(port)->rs485),
+					sizeof(rs485conf)))
+			return -EFAULT;
+		break;
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+
+
 static struct uart_ops atmel_pops = {
 	.tx_empty	= atmel_tx_empty,
 	.set_mctrl	= atmel_set_mctrl,
@@ -1250,6 +1380,7 @@
 	.config_port	= atmel_config_port,
 	.verify_port	= atmel_verify_port,
 	.pm		= atmel_serial_pm,
+	.ioctl		= atmel_ioctl,
 #ifdef CONFIG_CONSOLE_POLL
 	.poll_get_char	= atmel_poll_get_char,
 	.poll_put_char	= atmel_poll_put_char,
@@ -1265,13 +1396,12 @@
 	struct uart_port *port = &atmel_port->uart;
 	struct atmel_uart_data *data = pdev->dev.platform_data;
 
-	port->iotype	= UPIO_MEM;
-	port->flags	= UPF_BOOT_AUTOCONF;
-	port->ops	= &atmel_pops;
-	port->fifosize	= 1;
-	port->line	= pdev->id;
-	port->dev	= &pdev->dev;
-
+	port->iotype		= UPIO_MEM;
+	port->flags		= UPF_BOOT_AUTOCONF;
+	port->ops		= &atmel_pops;
+	port->fifosize		= 1;
+	port->line		= pdev->id;
+	port->dev		= &pdev->dev;
 	port->mapbase	= pdev->resource[0].start;
 	port->irq	= pdev->resource[1].start;
 
@@ -1299,8 +1429,16 @@
 
 	atmel_port->use_dma_rx = data->use_dma_rx;
 	atmel_port->use_dma_tx = data->use_dma_tx;
-	if (atmel_use_dma_tx(port))
+	atmel_port->rs485	= data->rs485;
+	/* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
+	if (atmel_port->rs485.flags & SER_RS485_ENABLED)
+		atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
+	else if (atmel_use_dma_tx(port)) {
 		port->fifosize = PDC_BUFFER_SIZE;
+		atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE;
+	} else {
+		atmel_port->tx_done_mask = ATMEL_US_TXRDY;
+	}
 }
 
 /*
@@ -1334,6 +1472,7 @@
 static void atmel_console_write(struct console *co, const char *s, u_int count)
 {
 	struct uart_port *port = &atmel_ports[co->index].uart;
+	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 	unsigned int status, imr;
 	unsigned int pdc_tx;
 
@@ -1341,7 +1480,7 @@
 	 * First, save IMR and then disable interrupts
 	 */
 	imr = UART_GET_IMR(port);
-	UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY);
+	UART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask);
 
 	/* Store PDC transmit status and disable it */
 	pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN;
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 3682835..e76b1af 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -36,8 +36,7 @@
 #include <asm/delay.h>
 
 #include <mach/dma.h>
-#include <mach/regs-ssp.h>
-#include <mach/ssp.h>
+#include <plat/ssp.h>
 #include <mach/pxa2xx_spi.h>
 
 MODULE_AUTHOR("Stephen Street");
@@ -1318,14 +1317,14 @@
 	/* NOTE:  PXA25x_SSP _could_ use external clocking ... */
 	if (drv_data->ssp_type != PXA25x_SSP)
 		dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
-				clk_get_rate(ssp->clk)
-					/ (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-				chip->enable_dma ? "DMA" : "PIO");
+			clk_get_rate(ssp->clk)
+				/ (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)),
+			chip->enable_dma ? "DMA" : "PIO");
 	else
 		dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
-				clk_get_rate(ssp->clk) / 2
-					/ (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-				chip->enable_dma ? "DMA" : "PIO");
+			clk_get_rate(ssp->clk) / 2
+				/ (1 + ((chip->cr0 & SSCR0_SCR(0x0ff)) >> 8)),
+			chip->enable_dma ? "DMA" : "PIO");
 
 	if (spi->bits_per_word <= 8) {
 		chip->n_bytes = 1;
@@ -1466,7 +1465,7 @@
 
 	platform_info = dev->platform_data;
 
-	ssp = ssp_request(pdev->id, pdev->name);
+	ssp = pxa_ssp_request(pdev->id, pdev->name);
 	if (ssp == NULL) {
 		dev_err(&pdev->dev, "failed to request SSP%d\n", pdev->id);
 		return -ENODEV;
@@ -1476,7 +1475,7 @@
 	master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
 	if (!master) {
 		dev_err(&pdev->dev, "cannot alloc spi_master\n");
-		ssp_free(ssp);
+		pxa_ssp_free(ssp);
 		return -ENOMEM;
 	}
 	drv_data = spi_master_get_devdata(master);
@@ -1558,7 +1557,7 @@
 	write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) |
 				SSCR1_TxTresh(TX_THRESH_DFLT),
 				drv_data->ioaddr);
-	write_SSCR0(SSCR0_SerClkDiv(2)
+	write_SSCR0(SSCR0_SCR(2)
 			| SSCR0_Motorola
 			| SSCR0_DataSize(8),
 			drv_data->ioaddr);
@@ -1605,7 +1604,7 @@
 
 out_error_master_alloc:
 	spi_master_put(master);
-	ssp_free(ssp);
+	pxa_ssp_free(ssp);
 	return status;
 }
 
@@ -1649,7 +1648,7 @@
 	free_irq(ssp->irq, drv_data);
 
 	/* Release SSP */
-	ssp_free(ssp);
+	pxa_ssp_free(ssp);
 
 	/* Disconnect from the SPI framework */
 	spi_unregister_master(drv_data->master);
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index df1bae9..eaa79c8 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -366,6 +366,13 @@
 	if (is_done)
 		done(ep, req, 0);
 	else if (ep->is_pingpong) {
+		/*
+		 * One dummy read to delay the code because of a HW glitch:
+		 * CSR returns bad RXCOUNT when read too soon after updating
+		 * RX_DATA_BK flags.
+		 */
+		csr = __raw_readl(creg);
+
 		bufferspace -= count;
 		buf += count;
 		goto rescan;
diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h
index 6b42417..7e466fe 100644
--- a/include/linux/amba/mmci.h
+++ b/include/linux/amba/mmci.h
@@ -6,8 +6,29 @@
 
 #include <linux/mmc/host.h>
 
+/**
+ * struct mmci_platform_data - platform configuration for the MMCI
+ * (also known as PL180) block.
+ * @f_max: the maximum operational frequency for this host in this
+ * platform configuration. When this is specified it takes precedence
+ * over the module parameter for the same frequency.
+ * @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
+ * @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
+ * @gpio_wp: read this GPIO pin to see if the card is write protected
+ * @gpio_cd: read this GPIO pin to detect card insertion
+ * @capabilities: the capabilities of the block as implemented in
+ * this platform, signify anything MMC_CAP_* from mmc/host.h
+ */
 struct mmci_platform_data {
-	unsigned int ocr_mask;			/* available voltages */
+	unsigned int f_max;
+	unsigned int ocr_mask;
 	u32 (*translate_vdd)(struct device *, unsigned int);
 	unsigned int (*status)(struct device *);
 	int	gpio_wp;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 376e14a..78e6121 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -23,6 +23,7 @@
 
 config SND_PXA_SOC_SSP
 	tristate
+	select PXA_SSP
 
 config SND_PXA2XX_SOC_CORGI
 	tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 544fd95..a1fd23e 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -32,9 +32,8 @@
 
 #include <mach/hardware.h>
 #include <mach/dma.h>
-#include <mach/regs-ssp.h>
 #include <mach/audio.h>
-#include <mach/ssp.h>
+#include <plat/ssp.h>
 
 #include "pxa2xx-pcm.h"
 #include "pxa-ssp.h"
@@ -57,15 +56,15 @@
 static void dump_registers(struct ssp_device *ssp)
 {
 	dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
-		 ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1),
-		 ssp_read_reg(ssp, SSTO));
+		 pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1),
+		 pxa_ssp_read_reg(ssp, SSTO));
 
 	dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
-		 ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR),
-		 ssp_read_reg(ssp, SSACD));
+		 pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR),
+		 pxa_ssp_read_reg(ssp, SSACD));
 }
 
-static void ssp_enable(struct ssp_device *ssp)
+static void pxa_ssp_enable(struct ssp_device *ssp)
 {
 	uint32_t sscr0;
 
@@ -73,7 +72,7 @@
 	__raw_writel(sscr0, ssp->mmio_base + SSCR0);
 }
 
-static void ssp_disable(struct ssp_device *ssp)
+static void pxa_ssp_disable(struct ssp_device *ssp)
 {
 	uint32_t sscr0;
 
@@ -87,7 +86,7 @@
 };
 
 static struct pxa2xx_pcm_dma_params *
-ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
+pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
 {
 	struct pxa2xx_pcm_dma_data *dma;
 
@@ -119,7 +118,7 @@
 
 	if (!cpu_dai->active) {
 		clk_enable(ssp->clk);
-		ssp_disable(ssp);
+		pxa_ssp_disable(ssp);
 	}
 
 	kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
@@ -137,7 +136,7 @@
 	struct ssp_device *ssp = priv->ssp;
 
 	if (!cpu_dai->active) {
-		ssp_disable(ssp);
+		pxa_ssp_disable(ssp);
 		clk_disable(ssp->clk);
 	}
 
@@ -160,7 +159,7 @@
 	priv->to  = __raw_readl(ssp->mmio_base + SSTO);
 	priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
 
-	ssp_disable(ssp);
+	pxa_ssp_disable(ssp);
 	clk_disable(ssp->clk);
 	return 0;
 }
@@ -180,7 +179,7 @@
 	__raw_writel(priv->psp, ssp->mmio_base + SSPSP);
 
 	if (cpu_dai->active)
-		ssp_enable(ssp);
+		pxa_ssp_enable(ssp);
 	else
 		clk_disable(ssp->clk);
 
@@ -196,9 +195,9 @@
  * ssp_set_clkdiv - set SSP clock divider
  * @div: serial clock rate divider
  */
-static void ssp_set_scr(struct ssp_device *ssp, u32 div)
+static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
 {
-	u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+	u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
 
 	if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
 		sscr0 &= ~0x0000ff00;
@@ -207,15 +206,15 @@
 		sscr0 &= ~0x000fff00;
 		sscr0 |= (div - 1) << 8;     /* 1..4096 */
 	}
-	ssp_write_reg(ssp, SSCR0, sscr0);
+	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
 }
 
 /**
- * ssp_get_clkdiv - get SSP clock divider
+ * pxa_ssp_get_clkdiv - get SSP clock divider
  */
-static u32 ssp_get_scr(struct ssp_device *ssp)
+static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
 {
-	u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+	u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
 	u32 div;
 
 	if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
@@ -235,7 +234,7 @@
 	struct ssp_device *ssp = priv->ssp;
 	int val;
 
-	u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
+	u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
 		~(SSCR0_ECS |  SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
 
 	dev_dbg(&ssp->pdev->dev,
@@ -263,7 +262,7 @@
 		break;
 	case PXA_SSP_CLK_AUDIO:
 		priv->sysclk = 0;
-		ssp_set_scr(ssp, 1);
+		pxa_ssp_set_scr(ssp, 1);
 		sscr0 |= SSCR0_ACS;
 		break;
 	default:
@@ -274,8 +273,8 @@
 	 * on PXA2xx.  On PXA3xx it must be enabled when doing so. */
 	if (!cpu_is_pxa3xx())
 		clk_disable(ssp->clk);
-	val = ssp_read_reg(ssp, SSCR0) | sscr0;
-	ssp_write_reg(ssp, SSCR0, val);
+	val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
+	pxa_ssp_write_reg(ssp, SSCR0, val);
 	if (!cpu_is_pxa3xx())
 		clk_enable(ssp->clk);
 
@@ -294,11 +293,11 @@
 
 	switch (div_id) {
 	case PXA_SSP_AUDIO_DIV_ACDS:
-		val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
-		ssp_write_reg(ssp, SSACD, val);
+		val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
+		pxa_ssp_write_reg(ssp, SSACD, val);
 		break;
 	case PXA_SSP_AUDIO_DIV_SCDB:
-		val = ssp_read_reg(ssp, SSACD);
+		val = pxa_ssp_read_reg(ssp, SSACD);
 		val &= ~SSACD_SCDB;
 #if defined(CONFIG_PXA3xx)
 		if (cpu_is_pxa3xx())
@@ -321,10 +320,10 @@
 		default:
 			return -EINVAL;
 		}
-		ssp_write_reg(ssp, SSACD, val);
+		pxa_ssp_write_reg(ssp, SSACD, val);
 		break;
 	case PXA_SSP_DIV_SCR:
-		ssp_set_scr(ssp, div);
+		pxa_ssp_set_scr(ssp, div);
 		break;
 	default:
 		return -ENODEV;
@@ -341,11 +340,11 @@
 {
 	struct ssp_priv *priv = cpu_dai->private_data;
 	struct ssp_device *ssp = priv->ssp;
-	u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
+	u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
 
 #if defined(CONFIG_PXA3xx)
 	if (cpu_is_pxa3xx())
-		ssp_write_reg(ssp, SSACDD, 0);
+		pxa_ssp_write_reg(ssp, SSACDD, 0);
 #endif
 
 	switch (freq_out) {
@@ -383,7 +382,7 @@
 			val = tmp;
 
 			val = (val << 16) | 64;
-			ssp_write_reg(ssp, SSACDD, val);
+			pxa_ssp_write_reg(ssp, SSACDD, val);
 
 			ssacd |= (0x6 << 4);
 
@@ -397,7 +396,7 @@
 		return -EINVAL;
 	}
 
-	ssp_write_reg(ssp, SSACD, ssacd);
+	pxa_ssp_write_reg(ssp, SSACD, ssacd);
 
 	return 0;
 }
@@ -412,7 +411,7 @@
 	struct ssp_device *ssp = priv->ssp;
 	u32 sscr0;
 
-	sscr0 = ssp_read_reg(ssp, SSCR0);
+	sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
 	sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
 
 	/* set slot width */
@@ -429,10 +428,10 @@
 		sscr0 |= SSCR0_SlotsPerFrm(slots);
 
 		/* set active slot mask */
-		ssp_write_reg(ssp, SSTSA, tx_mask);
-		ssp_write_reg(ssp, SSRSA, rx_mask);
+		pxa_ssp_write_reg(ssp, SSTSA, tx_mask);
+		pxa_ssp_write_reg(ssp, SSRSA, rx_mask);
 	}
-	ssp_write_reg(ssp, SSCR0, sscr0);
+	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
 
 	return 0;
 }
@@ -447,12 +446,12 @@
 	struct ssp_device *ssp = priv->ssp;
 	u32 sscr1;
 
-	sscr1 = ssp_read_reg(ssp, SSCR1);
+	sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
 	if (tristate)
 		sscr1 &= ~SSCR1_TTE;
 	else
 		sscr1 |= SSCR1_TTE;
-	ssp_write_reg(ssp, SSCR1, sscr1);
+	pxa_ssp_write_reg(ssp, SSCR1, sscr1);
 
 	return 0;
 }
@@ -476,14 +475,14 @@
 		return 0;
 
 	/* we can only change the settings if the port is not in use */
-	if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
+	if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
 		dev_err(&ssp->pdev->dev,
 			"can't change hardware dai format: stream is in use");
 		return -EINVAL;
 	}
 
 	/* reset port settings */
-	sscr0 = ssp_read_reg(ssp, SSCR0) &
+	sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
 		(SSCR0_ECS |  SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
 	sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
 	sspsp = 0;
@@ -535,9 +534,9 @@
 		return -EINVAL;
 	}
 
-	ssp_write_reg(ssp, SSCR0, sscr0);
-	ssp_write_reg(ssp, SSCR1, sscr1);
-	ssp_write_reg(ssp, SSPSP, sspsp);
+	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+	pxa_ssp_write_reg(ssp, SSCR1, sscr1);
+	pxa_ssp_write_reg(ssp, SSPSP, sspsp);
 
 	dump_registers(ssp);
 
@@ -566,7 +565,7 @@
 	u32 sscr0;
 	u32 sspsp;
 	int width = snd_pcm_format_physical_width(params_format(params));
-	int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
+	int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
 	struct pxa2xx_pcm_dma_params *dma_data;
 
 	dma_data = snd_soc_dai_get_dma_data(dai, substream);
@@ -578,22 +577,22 @@
 	 * to force 16-bit frame width on the wire (for S16_LE), even
 	 * with two channels. Use 16-bit DMA transfers for this case.
 	 */
-	dma_data = ssp_get_dma_params(ssp,
+	dma_data = pxa_ssp_get_dma_params(ssp,
 			((chn == 2) && (ttsa != 1)) || (width == 32),
 			substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 
 	snd_soc_dai_set_dma_data(dai, substream, dma_data);
 
 	/* we can only change the settings if the port is not in use */
-	if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
+	if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
 		return 0;
 
 	/* clear selected SSP bits */
-	sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
-	ssp_write_reg(ssp, SSCR0, sscr0);
+	sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
+	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
 
 	/* bit size */
-	sscr0 = ssp_read_reg(ssp, SSCR0);
+	sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
 #ifdef CONFIG_PXA3xx
@@ -609,13 +608,13 @@
 		sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
 		break;
 	}
-	ssp_write_reg(ssp, SSCR0, sscr0);
+	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
 
 	switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_I2S:
-	       sspsp = ssp_read_reg(ssp, SSPSP);
+	       sspsp = pxa_ssp_read_reg(ssp, SSPSP);
 
-		if ((ssp_get_scr(ssp) == 4) && (width == 16)) {
+		if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) {
 			/* This is a special case where the bitclk is 64fs
 			* and we're not dealing with 2*32 bits of audio
 			* samples.
@@ -649,7 +648,7 @@
 			sspsp |= SSPSP_DMYSTRT(1);
 		}
 
-		ssp_write_reg(ssp, SSPSP, sspsp);
+		pxa_ssp_write_reg(ssp, SSPSP, sspsp);
 		break;
 	default:
 		break;
@@ -680,45 +679,45 @@
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_RESUME:
-		ssp_enable(ssp);
+		pxa_ssp_enable(ssp);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		val = ssp_read_reg(ssp, SSCR1);
+		val = pxa_ssp_read_reg(ssp, SSCR1);
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			val |= SSCR1_TSRE;
 		else
 			val |= SSCR1_RSRE;
-		ssp_write_reg(ssp, SSCR1, val);
-		val = ssp_read_reg(ssp, SSSR);
-		ssp_write_reg(ssp, SSSR, val);
+		pxa_ssp_write_reg(ssp, SSCR1, val);
+		val = pxa_ssp_read_reg(ssp, SSSR);
+		pxa_ssp_write_reg(ssp, SSSR, val);
 		break;
 	case SNDRV_PCM_TRIGGER_START:
-		val = ssp_read_reg(ssp, SSCR1);
+		val = pxa_ssp_read_reg(ssp, SSCR1);
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			val |= SSCR1_TSRE;
 		else
 			val |= SSCR1_RSRE;
-		ssp_write_reg(ssp, SSCR1, val);
-		ssp_enable(ssp);
+		pxa_ssp_write_reg(ssp, SSCR1, val);
+		pxa_ssp_enable(ssp);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
-		val = ssp_read_reg(ssp, SSCR1);
+		val = pxa_ssp_read_reg(ssp, SSCR1);
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			val &= ~SSCR1_TSRE;
 		else
 			val &= ~SSCR1_RSRE;
-		ssp_write_reg(ssp, SSCR1, val);
+		pxa_ssp_write_reg(ssp, SSCR1, val);
 		break;
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-		ssp_disable(ssp);
+		pxa_ssp_disable(ssp);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		val = ssp_read_reg(ssp, SSCR1);
+		val = pxa_ssp_read_reg(ssp, SSCR1);
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			val &= ~SSCR1_TSRE;
 		else
 			val &= ~SSCR1_RSRE;
-		ssp_write_reg(ssp, SSCR1, val);
+		pxa_ssp_write_reg(ssp, SSCR1, val);
 		break;
 
 	default:
@@ -740,7 +739,7 @@
 	if (!priv)
 		return -ENOMEM;
 
-	priv->ssp = ssp_request(dai->id + 1, "SoC audio");
+	priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
 	if (priv->ssp == NULL) {
 		ret = -ENODEV;
 		goto err_priv;
@@ -760,7 +759,7 @@
 			      struct snd_soc_dai *dai)
 {
 	struct ssp_priv *priv = dai->private_data;
-	ssp_free(priv->ssp);
+	pxa_ssp_free(priv->ssp);
 }
 
 #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\