Merge branches 'depends/pinctrl/devel' and 'depends/rmk/clkdev' into spear/pinctrl

The spear/pinctrl branch has hard dependencies on both the
pinctrl branch and the clkdev branch. We merge those here
to fix it up without having to rebase a branch that has
been pulled into other stable branches already.

Conflicts:
	Documentation/driver-model/devres.txt

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/Documentation/arm/SPEAr/overview.txt b/Documentation/arm/SPEAr/overview.txt
index 253a35c..28a9af9 100644
--- a/Documentation/arm/SPEAr/overview.txt
+++ b/Documentation/arm/SPEAr/overview.txt
@@ -17,14 +17,14 @@
   SPEAr (Platform)
 	- SPEAr3XX (3XX SOC series, based on ARM9)
 		- SPEAr300 (SOC)
-			- SPEAr300_EVB (Evaluation Board)
+			- SPEAr300 Evaluation Board
 		- SPEAr310 (SOC)
-			- SPEAr310_EVB (Evaluation Board)
+			- SPEAr310 Evaluation Board
 		- SPEAr320 (SOC)
-			- SPEAr320_EVB (Evaluation Board)
+			- SPEAr320 Evaluation Board
 	- SPEAr6XX (6XX SOC series, based on ARM9)
 		- SPEAr600 (SOC)
-			- SPEAr600_EVB (Evaluation Board)
+			- SPEAr600 Evaluation Board
 	- SPEAr13XX (13XX SOC series, based on ARM CORTEXA9)
 		- SPEAr1300 (SOC)
 
@@ -51,10 +51,11 @@
   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.
+  mach-spear* doesn't contains board specific files as they fully support
+  Flattened Device Tree.
 
 
   Document Author
   ---------------
 
-  Viresh Kumar, (c) 2010 ST Microelectronics
+  Viresh Kumar <viresh.kumar@st.com>, (c) 2010-2012 ST Microelectronics
diff --git a/Documentation/devicetree/bindings/arm/spear.txt b/Documentation/devicetree/bindings/arm/spear.txt
index f8e54f0..aa5f355 100644
--- a/Documentation/devicetree/bindings/arm/spear.txt
+++ b/Documentation/devicetree/bindings/arm/spear.txt
@@ -6,3 +6,21 @@
 Required root node property:
 
 compatible = "st,spear600";
+
+Boards with the ST SPEAr300 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "st,spear300";
+
+Boards with the ST SPEAr310 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "st,spear310";
+
+Boards with the ST SPEAr320 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "st,spear320";
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt
new file mode 100644
index 0000000..3664d37
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt
@@ -0,0 +1,108 @@
+ST Microelectronics, SPEAr pinmux controller
+
+Required properties:
+- compatible	: "st,spear300-pinmux"
+		: "st,spear310-pinmux"
+		: "st,spear320-pinmux"
+- reg		: Address range of the pinctrl registers
+- st,pinmux-mode: Mandatory for SPEAr300 and SPEAr320 and invalid for others.
+	- Its values for SPEAr300:
+		- NAND_MODE		: <0>
+		- NOR_MODE		: <1>
+		- PHOTO_FRAME_MODE	: <2>
+		- LEND_IP_PHONE_MODE	: <3>
+		- HEND_IP_PHONE_MODE	: <4>
+		- LEND_WIFI_PHONE_MODE	: <5>
+		- HEND_WIFI_PHONE_MODE	: <6>
+		- ATA_PABX_WI2S_MODE	: <7>
+		- ATA_PABX_I2S_MODE	: <8>
+		- CAML_LCDW_MODE	: <9>
+		- CAMU_LCD_MODE		: <10>
+		- CAMU_WLCD_MODE	: <11>
+		- CAML_LCD_MODE		: <12>
+	- Its values for SPEAr320:
+		- AUTO_NET_SMII_MODE	: <0>
+		- AUTO_NET_MII_MODE	: <1>
+		- AUTO_EXP_MODE		: <2>
+		- SMALL_PRINTERS_MODE	: <3>
+		- EXTENDED_MODE		: <4>
+
+Please refer to pinctrl-bindings.txt in this directory for details of the common
+pinctrl bindings used by client devices.
+
+SPEAr's pinmux nodes act as a container for an abitrary number of subnodes. Each
+of these subnodes represents muxing for a pin, a group, or a list of pins or
+groups.
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Required subnode-properties:
+- st,pins : An array of strings. Each string contains the name of a pin or
+  group.
+- st,function: A string containing the name of the function to mux to the pin or
+  group. See the SPEAr's TRM to determine which are valid for each pin or group.
+
+  Valid values for group and function names can be found from looking at the
+  group and function arrays in driver files:
+  drivers/pinctrl/spear/pinctrl-spear3*0.c
+
+Valid values for group names are:
+For All SPEAr3xx machines:
+	"firda_grp", "i2c0_grp", "ssp_cs_grp", "ssp0_grp", "mii0_grp",
+	"gpio0_pin0_grp", "gpio0_pin1_grp", "gpio0_pin2_grp", "gpio0_pin3_grp",
+	"gpio0_pin4_grp", "gpio0_pin5_grp", "uart0_ext_grp", "uart0_grp",
+	"timer_0_1_grp", timer_0_1_pins, "timer_2_3_grp"
+
+For SPEAr300 machines:
+	"fsmc_2chips_grp", "fsmc_4chips_grp", "clcd_lcdmode_grp",
+	"clcd_pfmode_grp", "tdm_grp", "i2c_clk_grp_grp", "caml_grp", "camu_grp",
+	"dac_grp", "i2s_grp", "sdhci_4bit_grp", "sdhci_8bit_grp",
+	"gpio1_0_to_3_grp", "gpio1_4_to_7_grp"
+
+For SPEAr310 machines:
+	"emi_cs_0_to_5_grp", "uart1_grp", "uart2_grp", "uart3_grp", "uart4_grp",
+	"uart5_grp", "fsmc_grp", "rs485_0_grp", "rs485_1_grp", "tdm_grp"
+
+For SPEAr320 machines:
+	"clcd_grp", "emi_grp", "fsmc_8bit_grp", "fsmc_16bit_grp", "spp_grp",
+	"sdhci_led_grp", "sdhci_cd_12_grp", "sdhci_cd_51_grp", "i2s_grp",
+	"uart1_grp", "uart1_modem_2_to_7_grp", "uart1_modem_31_to_36_grp",
+	"uart1_modem_34_to_45_grp", "uart1_modem_80_to_85_grp", "uart2_grp",
+	"uart3_8_9_grp", "uart3_15_16_grp", "uart3_41_42_grp",
+	"uart3_52_53_grp", "uart3_73_74_grp", "uart3_94_95_grp",
+	"uart3_98_99_grp", "uart4_6_7_grp", "uart4_13_14_grp",
+	"uart4_39_40_grp", "uart4_71_72_grp", "uart4_92_93_grp",
+	"uart4_100_101_grp", "uart5_4_5_grp", "uart5_37_38_grp",
+	"uart5_69_70_grp", "uart5_90_91_grp", "uart6_2_3_grp",
+	"uart6_88_89_grp", "rs485_grp", "touchscreen_grp", "can0_grp",
+	"can1_grp", "pwm0_1_pin_8_9_grp", "pwm0_1_pin_14_15_grp",
+	"pwm0_1_pin_30_31_grp", "pwm0_1_pin_37_38_grp", "pwm0_1_pin_42_43_grp",
+	"pwm0_1_pin_59_60_grp", "pwm0_1_pin_88_89_grp", "pwm2_pin_7_grp",
+	"pwm2_pin_13_grp", "pwm2_pin_29_grp", "pwm2_pin_34_grp",
+	"pwm2_pin_41_grp", "pwm2_pin_58_grp", "pwm2_pin_87_grp",
+	"pwm3_pin_6_grp", "pwm3_pin_12_grp", "pwm3_pin_28_grp",
+	"pwm3_pin_40_grp", "pwm3_pin_57_grp", "pwm3_pin_86_grp",
+	"ssp1_17_20_grp", "ssp1_36_39_grp", "ssp1_48_51_grp", "ssp1_65_68_grp",
+	"ssp1_94_97_grp", "ssp2_13_16_grp", "ssp2_32_35_grp", "ssp2_44_47_grp",
+	"ssp2_61_64_grp", "ssp2_90_93_grp", "mii2_grp", "smii0_1_grp",
+	"rmii0_1_grp", "i2c1_8_9_grp", "i2c1_98_99_grp", "i2c2_0_1_grp",
+	"i2c2_2_3_grp", "i2c2_19_20_grp", "i2c2_75_76_grp", "i2c2_96_97_grp"
+
+Valid values for function names are:
+For All SPEAr3xx machines:
+	"firda", "i2c0", "ssp_cs", "ssp0", "mii0", "gpio0", "uart0_ext",
+	"uart0", "timer_0_1", "timer_2_3"
+
+For SPEAr300 machines:
+	"fsmc", "clcd", "tdm", "i2c1", "cam", "dac", "i2s", "sdhci", "gpio1"
+
+For SPEAr310 machines:
+	"emi", "uart1", "uart2", "uart3", "uart4", "uart5", "fsmc", "rs485_0",
+	"rs485_1", "tdm"
+
+For SPEAr320 machines:
+	"clcd", "emi", "fsmc", "spp", "sdhci", "i2s", "uart1", "uart1_modem",
+	"uart2", "uart3", "uart4", "uart5", "uart6", "rs485", "touchscreen",
+	"can0", "can1", "pwm0_1", "pwm2", "pwm3", "ssp1", "ssp2", "mii2",
+	"mii0_1", "i2c1", "i2c2"
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index ef4fa7b..950856b 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -277,6 +277,10 @@
   devm_regulator_put()
   devm_regulator_bulk_get()
 
+CLOCK
+  devm_clk_get()
+  devm_clk_put()
+
 PINCTRL
   devm_pinctrl_get()
   devm_pinctrl_put()
diff --git a/MAINTAINERS b/MAINTAINERS
index b0f1073..cf900fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5234,6 +5234,14 @@
 S:	Maintained
 F:	drivers/pinctrl/
 
+PIN CONTROLLER - ST SPEAR
+M:	Viresh Kumar <viresh.kumar@st.com>
+L:	spear-devel@list.st.com
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+W:	http://www.st.com/spear
+S:	Maintained
+F:	driver/pinctrl/spear/
+
 PKTCDVD DRIVER
 M:	Peter Osterlund <petero2@telia.com>
 S:	Maintained
@@ -6330,21 +6338,6 @@
 F:	arch/arm/plat-spear/clock.c
 F:	arch/arm/plat-spear/include/plat/clock.h
 
-SPEAR PAD MULTIPLEXING SUPPORT
-M:	Viresh Kumar <viresh.kumar@st.com>
-L:	spear-devel@list.st.com
-L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-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
-
 SPI SUBSYSTEM
 M:	Grant Likely <grant.likely@secretlab.ca>
 L:	spi-devel-general@lists.sourceforge.net
diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts
new file mode 100644
index 0000000..402ca0d
--- /dev/null
+++ b/arch/arm/boot/dts/spear300-evb.dts
@@ -0,0 +1,221 @@
+/*
+ * DTS file for SPEAr300 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "spear300.dtsi"
+
+/ {
+	model = "ST SPEAr300 Evaluation Board";
+	compatible = "st,spear300-evb", "st,spear300";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	memory {
+		reg = <0 0x40000000>;
+	};
+
+	ahb {
+		pinmux@99000000 {
+			st,pinmux-mode = <2>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&state_default>;
+
+			state_default: pinmux {
+				i2c0 {
+					st,pins = "i2c0_grp";
+					st,function = "i2c0";
+				};
+				ssp0 {
+					st,pins = "ssp0_grp";
+					st,function = "ssp0";
+				};
+				mii0 {
+					st,pins = "mii0_grp";
+					st,function = "mii0";
+				};
+				uart0 {
+					st,pins = "uart0_grp";
+					st,function = "uart0";
+				};
+				clcd {
+					st,pins = "clcd_pfmode_grp";
+					st,function = "clcd";
+				};
+				sdhci {
+					st,pins = "sdhci_4bit_grp";
+					st,function = "sdhci";
+				};
+				gpio1 {
+					st,pins = "gpio1_4_to_7_grp",
+						"gpio1_0_to_3_grp";
+					st,function = "gpio1";
+				};
+			};
+		};
+
+		clcd@60000000 {
+			status = "okay";
+		};
+
+		dma@fc400000 {
+			status = "okay";
+		};
+
+		fsmc: flash@94000000 {
+			status = "okay";
+		};
+
+		gmac: eth@e0800000 {
+			status = "okay";
+		};
+
+		sdhci@70000000 {
+			int-gpio = <&gpio1 0 0>;
+			power-gpio = <&gpio1 2 1>;
+			status = "okay";
+		};
+
+		smi: flash@fc000000 {
+			status = "okay";
+		};
+
+		spi0: spi@d0100000 {
+			status = "okay";
+		};
+
+		ehci@e1800000 {
+			status = "okay";
+		};
+
+		ohci@e1900000 {
+			status = "okay";
+		};
+
+		ohci@e2100000 {
+			status = "okay";
+		};
+
+		apb {
+			gpio0: gpio@fc980000 {
+			       status = "okay";
+			};
+
+			gpio1: gpio@a9000000 {
+			       status = "okay";
+			};
+
+			i2c0: i2c@d0180000 {
+			       status = "okay";
+			};
+
+			kbd@a0000000 {
+				linux,keymap = < 0x00010000
+						 0x00020100
+						 0x00030200
+						 0x00040300
+						 0x00050400
+						 0x00060500
+						 0x00070600
+						 0x00080700
+						 0x00090800
+						 0x000a0001
+						 0x000c0101
+						 0x000d0201
+						 0x000e0301
+						 0x000f0401
+						 0x00100501
+						 0x00110601
+						 0x00120701
+						 0x00130801
+						 0x00140002
+						 0x00150102
+						 0x00160202
+						 0x00170302
+						 0x00180402
+						 0x00190502
+						 0x001a0602
+						 0x001b0702
+						 0x001c0802
+						 0x001d0003
+						 0x001e0103
+						 0x001f0203
+						 0x00200303
+						 0x00210403
+						 0x00220503
+						 0x00230603
+						 0x00240703
+						 0x00250803
+						 0x00260004
+						 0x00270104
+						 0x00280204
+						 0x00290304
+						 0x002a0404
+						 0x002b0504
+						 0x002c0604
+						 0x002d0704
+						 0x002e0804
+						 0x002f0005
+						 0x00300105
+						 0x00310205
+						 0x00320305
+						 0x00330405
+						 0x00340505
+						 0x00350605
+						 0x00360705
+						 0x00370805
+						 0x00380006
+						 0x00390106
+						 0x003a0206
+						 0x003b0306
+						 0x003c0406
+						 0x003d0506
+						 0x003e0606
+						 0x003f0706
+						 0x00400806
+						 0x00410007
+						 0x00420107
+						 0x00430207
+						 0x00440307
+						 0x00450407
+						 0x00460507
+						 0x00470607
+						 0x00480707
+						 0x00490807
+						 0x004a0008
+						 0x004b0108
+						 0x004c0208
+						 0x004d0308
+						 0x004e0408
+						 0x004f0508
+						 0x00500608
+						 0x00510708
+						 0x00520808 >;
+			       autorepeat;
+			       st,mode = <0>;
+			       status = "okay";
+			};
+
+			rtc@fc900000 {
+			       status = "okay";
+			};
+
+			serial@d0000000 {
+			       status = "okay";
+			};
+
+			wdt@fc880000 {
+			       status = "okay";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi
new file mode 100644
index 0000000..01c5e35
--- /dev/null
+++ b/arch/arm/boot/dts/spear300.dtsi
@@ -0,0 +1,77 @@
+/*
+ * DTS file for SPEAr300 SoC
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "spear3xx.dtsi"
+
+/ {
+	ahb {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges = <0x60000000 0x60000000 0x50000000
+			  0xd0000000 0xd0000000 0x30000000>;
+
+		pinmux@99000000 {
+			compatible = "st,spear300-pinmux";
+			reg = <0x99000000 0x1000>;
+		};
+
+		clcd@60000000 {
+			compatible = "arm,clcd-pl110", "arm,primecell";
+			reg = <0x60000000 0x1000>;
+			interrupts = <30>;
+			status = "disabled";
+		};
+
+		fsmc: flash@94000000 {
+			compatible = "st,spear600-fsmc-nand";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x94000000 0x1000	/* FSMC Register */
+			       0x80000000 0x0010>;	/* NAND Base */
+			reg-names = "fsmc_regs", "nand_data";
+			st,ale-off = <0x20000>;
+			st,cle-off = <0x10000>;
+			status = "disabled";
+		};
+
+		sdhci@70000000 {
+			compatible = "st,sdhci-spear";
+			reg = <0x70000000 0x100>;
+			interrupts = <1>;
+			status = "disabled";
+		};
+
+		apb {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			ranges = <0xa0000000 0xa0000000 0x10000000
+				  0xd0000000 0xd0000000 0x30000000>;
+
+			gpio1: gpio@a9000000 {
+				#gpio-cells = <2>;
+				compatible = "arm,pl061", "arm,primecell";
+				gpio-controller;
+				reg = <0xa9000000 0x1000>;
+				status = "disabled";
+			};
+
+			kbd@a0000000 {
+				compatible = "st,spear300-kbd";
+				reg = <0xa0000000 0x1000>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts
new file mode 100644
index 0000000..6d95317
--- /dev/null
+++ b/arch/arm/boot/dts/spear310-evb.dts
@@ -0,0 +1,172 @@
+/*
+ * DTS file for SPEAr310 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "spear310.dtsi"
+
+/ {
+	model = "ST SPEAr310 Evaluation Board";
+	compatible = "st,spear310-evb", "st,spear310";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	memory {
+		reg = <0 0x40000000>;
+	};
+
+	ahb {
+		pinmux@b4000000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&state_default>;
+
+			state_default: pinmux {
+				gpio0 {
+					st,pins = "gpio0_pin0_grp",
+						"gpio0_pin1_grp",
+						"gpio0_pin2_grp",
+						"gpio0_pin3_grp",
+						"gpio0_pin4_grp",
+						"gpio0_pin5_grp";
+					st,function = "gpio0";
+				};
+				i2c0 {
+					st,pins = "i2c0_grp";
+					st,function = "i2c0";
+				};
+				mii0 {
+					st,pins = "mii0_grp";
+					st,function = "mii0";
+				};
+				ssp0 {
+					st,pins = "ssp0_grp";
+					st,function = "ssp0";
+				};
+				uart0 {
+					st,pins = "uart0_grp";
+					st,function = "uart0";
+				};
+				emi {
+					st,pins = "emi_cs_0_to_5_grp";
+					st,function = "emi";
+				};
+				fsmc {
+					st,pins = "fsmc_grp";
+					st,function = "fsmc";
+				};
+				uart1 {
+					st,pins = "uart1_grp";
+					st,function = "uart1";
+				};
+				uart2 {
+					st,pins = "uart2_grp";
+					st,function = "uart2";
+				};
+				uart3 {
+					st,pins = "uart3_grp";
+					st,function = "uart3";
+				};
+				uart4 {
+					st,pins = "uart4_grp";
+					st,function = "uart4";
+				};
+				uart5 {
+					st,pins = "uart5_grp";
+					st,function = "uart5";
+				};
+			};
+		};
+
+		dma@fc400000 {
+			status = "okay";
+		};
+
+		fsmc: flash@44000000 {
+			status = "okay";
+		};
+
+		gmac: eth@e0800000 {
+			status = "okay";
+		};
+
+		smi: flash@fc000000 {
+			status = "okay";
+			clock-rate=<50000000>;
+
+			flash@f8000000 {
+				label = "m25p64";
+				reg = <0xf8000000 0x800000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				st,smi-fast-mode;
+			};
+		};
+
+		spi0: spi@d0100000 {
+			status = "okay";
+		};
+
+		ehci@e1800000 {
+			status = "okay";
+		};
+
+		ohci@e1900000 {
+			status = "okay";
+		};
+
+		ohci@e2100000 {
+			status = "okay";
+		};
+
+		apb {
+			gpio0: gpio@fc980000 {
+			       status = "okay";
+			};
+
+			i2c0: i2c@d0180000 {
+			       status = "okay";
+			};
+
+			rtc@fc900000 {
+			       status = "okay";
+			};
+
+			serial@d0000000 {
+			       status = "okay";
+			};
+
+			serial@b2000000 {
+			       status = "okay";
+			};
+
+			serial@b2080000 {
+			       status = "okay";
+			};
+
+			serial@b2100000 {
+			       status = "okay";
+			};
+
+			serial@b2180000 {
+			       status = "okay";
+			};
+
+			serial@b2200000 {
+			       status = "okay";
+			};
+
+			wdt@fc880000 {
+			       status = "okay";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
new file mode 100644
index 0000000..e47081c
--- /dev/null
+++ b/arch/arm/boot/dts/spear310.dtsi
@@ -0,0 +1,80 @@
+/*
+ * DTS file for SPEAr310 SoC
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "spear3xx.dtsi"
+
+/ {
+	ahb {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges = <0x40000000 0x40000000 0x10000000
+			  0xb0000000 0xb0000000 0x10000000
+			  0xd0000000 0xd0000000 0x30000000>;
+
+		pinmux@b4000000 {
+			compatible = "st,spear310-pinmux";
+			reg = <0xb4000000 0x1000>;
+		};
+
+		fsmc: flash@44000000 {
+			compatible = "st,spear600-fsmc-nand";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x44000000 0x1000	/* FSMC Register */
+			       0x40000000 0x0010>;	/* NAND Base */
+			reg-names = "fsmc_regs", "nand_data";
+			st,ale-off = <0x10000>;
+			st,cle-off = <0x20000>;
+			status = "disabled";
+		};
+
+		apb {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			ranges = <0xb0000000 0xb0000000 0x10000000
+				  0xd0000000 0xd0000000 0x30000000>;
+
+			serial@b2000000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0xb2000000 0x1000>;
+				status = "disabled";
+			};
+
+			serial@b2080000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0xb2080000 0x1000>;
+				status = "disabled";
+			};
+
+			serial@b2100000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0xb2100000 0x1000>;
+				status = "disabled";
+			};
+
+			serial@b2180000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0xb2180000 0x1000>;
+				status = "disabled";
+			};
+
+			serial@b2200000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0xb2200000 0x1000>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
new file mode 100644
index 0000000..0c6463b
--- /dev/null
+++ b/arch/arm/boot/dts/spear320-evb.dts
@@ -0,0 +1,173 @@
+/*
+ * DTS file for SPEAr320 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "spear320.dtsi"
+
+/ {
+	model = "ST SPEAr300 Evaluation Board";
+	compatible = "st,spear300-evb", "st,spear300";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	memory {
+		reg = <0 0x40000000>;
+	};
+
+	ahb {
+		pinmux@b3000000 {
+			st,pinmux-mode = <3>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&state_default>;
+
+			state_default: pinmux {
+				i2c0 {
+					st,pins = "i2c0_grp";
+					st,function = "i2c0";
+				};
+				mii0 {
+					st,pins = "mii0_grp";
+					st,function = "mii0";
+				};
+				ssp0 {
+					st,pins = "ssp0_grp";
+					st,function = "ssp0";
+				};
+				uart0 {
+					st,pins = "uart0_grp";
+					st,function = "uart0";
+				};
+				sdhci {
+					st,pins = "sdhci_cd_51_grp";
+					st,function = "sdhci";
+				};
+				i2s {
+					st,pins = "i2s_grp";
+					st,function = "i2s";
+				};
+				uart1 {
+					st,pins = "uart1_grp";
+					st,function = "uart1";
+				};
+				uart2 {
+					st,pins = "uart2_grp";
+					st,function = "uart2";
+				};
+				can0 {
+					st,pins = "can0_grp";
+					st,function = "can0";
+				};
+				can1 {
+					st,pins = "can1_grp";
+					st,function = "can1";
+				};
+				mii2 {
+					st,pins = "mii2_grp";
+					st,function = "mii2";
+				};
+				pwm0_1 {
+					st,pins = "pwm0_1_pin_14_15_grp";
+					st,function = "pwm0_1";
+				};
+				pwm2 {
+					st,pins = "pwm2_pin_13_grp";
+					st,function = "pwm2";
+				};
+			};
+		};
+
+		clcd@90000000 {
+			status = "okay";
+		};
+
+		dma@fc400000 {
+			status = "okay";
+		};
+
+		fsmc: flash@4c000000 {
+			status = "okay";
+		};
+
+		gmac: eth@e0800000 {
+			status = "okay";
+		};
+
+		sdhci@70000000 {
+			power-gpio = <&gpio0 2 1>;
+			power_always_enb;
+			status = "okay";
+		};
+
+		smi: flash@fc000000 {
+			status = "okay";
+		};
+
+		spi0: spi@d0100000 {
+			status = "okay";
+		};
+
+		spi1: spi@a5000000 {
+			status = "okay";
+		};
+
+		spi2: spi@a6000000 {
+			status = "okay";
+		};
+
+		ehci@e1800000 {
+			status = "okay";
+		};
+
+		ohci@e1900000 {
+			status = "okay";
+		};
+
+		ohci@e2100000 {
+			status = "okay";
+		};
+
+		apb {
+			gpio0: gpio@fc980000 {
+			       status = "okay";
+			};
+
+			i2c0: i2c@d0180000 {
+			       status = "okay";
+			};
+
+			i2c1: i2c@a7000000 {
+			       status = "okay";
+			};
+
+			rtc@fc900000 {
+			       status = "okay";
+			};
+
+			serial@d0000000 {
+			       status = "okay";
+			};
+
+			serial@a3000000 {
+			       status = "okay";
+			};
+
+			serial@a4000000 {
+			       status = "okay";
+			};
+
+			wdt@fc880000 {
+			       status = "okay";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
new file mode 100644
index 0000000..5372ca3
--- /dev/null
+++ b/arch/arm/boot/dts/spear320.dtsi
@@ -0,0 +1,95 @@
+/*
+ * DTS file for SPEAr320 SoC
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "spear3xx.dtsi"
+
+/ {
+	ahb {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges = <0x40000000 0x40000000 0x80000000
+			  0xd0000000 0xd0000000 0x30000000>;
+
+		pinmux@b3000000 {
+			compatible = "st,spear320-pinmux";
+			reg = <0xb3000000 0x1000>;
+		};
+
+		clcd@90000000 {
+			compatible = "arm,clcd-pl110", "arm,primecell";
+			reg = <0x90000000 0x1000>;
+			interrupts = <33>;
+			status = "disabled";
+		};
+
+		fsmc: flash@4c000000 {
+			compatible = "st,spear600-fsmc-nand";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x4c000000 0x1000	/* FSMC Register */
+			       0x50000000 0x0010>;	/* NAND Base */
+			reg-names = "fsmc_regs", "nand_data";
+			st,ale-off = <0x20000>;
+			st,cle-off = <0x10000>;
+			status = "disabled";
+		};
+
+		sdhci@70000000 {
+			compatible = "st,sdhci-spear";
+			reg = <0x70000000 0x100>;
+			interrupts = <29>;
+			status = "disabled";
+		};
+
+		spi1: spi@a5000000 {
+			compatible = "arm,pl022", "arm,primecell";
+			reg = <0xa5000000 0x1000>;
+			status = "disabled";
+		};
+
+		spi2: spi@a6000000 {
+			compatible = "arm,pl022", "arm,primecell";
+			reg = <0xa6000000 0x1000>;
+			status = "disabled";
+		};
+
+		apb {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			ranges = <0xa0000000 0xa0000000 0x10000000
+				  0xd0000000 0xd0000000 0x30000000>;
+
+			i2c1: i2c@a7000000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "snps,designware-i2c";
+				reg = <0xa7000000 0x1000>;
+				status = "disabled";
+			};
+
+			serial@a3000000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0xa3000000 0x1000>;
+				status = "disabled";
+			};
+
+			serial@a4000000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0xa4000000 0x1000>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/spear3xx.dtsi b/arch/arm/boot/dts/spear3xx.dtsi
new file mode 100644
index 0000000..0ae7c8e
--- /dev/null
+++ b/arch/arm/boot/dts/spear3xx.dtsi
@@ -0,0 +1,144 @@
+/*
+ * DTS file for all SPEAr3xx SoCs
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	interrupt-parent = <&vic>;
+
+	cpus {
+		cpu@0 {
+			compatible = "arm,arm926ejs";
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x40000000>;
+	};
+
+	ahb {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+		vic: interrupt-controller@f1100000 {
+			compatible = "arm,pl190-vic";
+			interrupt-controller;
+			reg = <0xf1100000 0x1000>;
+			#interrupt-cells = <1>;
+		};
+
+		dma@fc400000 {
+			compatible = "arm,pl080", "arm,primecell";
+			reg = <0xfc400000 0x1000>;
+			interrupt-parent = <&vic>;
+			interrupts = <8>;
+			status = "disabled";
+		};
+
+		gmac: eth@e0800000 {
+			compatible = "st,spear600-gmac";
+			reg = <0xe0800000 0x8000>;
+			interrupts = <23 22>;
+			interrupt-names = "macirq", "eth_wake_irq";
+			status = "disabled";
+		};
+
+		smi: flash@fc000000 {
+			compatible = "st,spear600-smi";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0xfc000000 0x1000>;
+			interrupts = <9>;
+			status = "disabled";
+		};
+
+		spi0: spi@d0100000 {
+			compatible = "arm,pl022", "arm,primecell";
+			reg = <0xd0100000 0x1000>;
+			interrupts = <20>;
+			status = "disabled";
+		};
+
+		ehci@e1800000 {
+			compatible = "st,spear600-ehci", "usb-ehci";
+			reg = <0xe1800000 0x1000>;
+			interrupts = <26>;
+			status = "disabled";
+		};
+
+		ohci@e1900000 {
+			compatible = "st,spear600-ohci", "usb-ohci";
+			reg = <0xe1900000 0x1000>;
+			interrupts = <25>;
+			status = "disabled";
+		};
+
+		ohci@e2100000 {
+			compatible = "st,spear600-ohci", "usb-ohci";
+			reg = <0xe2100000 0x1000>;
+			interrupts = <27>;
+			status = "disabled";
+		};
+
+		apb {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+			gpio0: gpio@fc980000 {
+				compatible = "arm,pl061", "arm,primecell";
+				reg = <0xfc980000 0x1000>;
+				interrupts = <11>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				status = "disabled";
+			};
+
+			i2c0: i2c@d0180000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "snps,designware-i2c";
+				reg = <0xd0180000 0x1000>;
+				interrupts = <21>;
+				status = "disabled";
+			};
+
+			rtc@fc900000 {
+				compatible = "st,spear-rtc";
+				reg = <0xfc900000 0x1000>;
+				interrupts = <10>;
+				status = "disabled";
+			};
+
+			serial@d0000000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0xd0000000 0x1000>;
+				interrupts = <19>;
+				status = "disabled";
+			};
+
+			wdt@fc880000 {
+				compatible = "arm,sp805", "arm,primecell";
+				reg = <0xfc880000 0x1000>;
+				interrupts = <12>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/spear600-evb.dts b/arch/arm/boot/dts/spear600-evb.dts
index 636292e..790a7a8 100644
--- a/arch/arm/boot/dts/spear600-evb.dts
+++ b/arch/arm/boot/dts/spear600-evb.dts
@@ -24,6 +24,10 @@
 	};
 
 	ahb {
+		dma@fc400000 {
+			status = "okay";
+		};
+
 		gmac: ethernet@e0800000 {
 			phy-mode = "gmii";
 			status = "okay";
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
index ebe0885..d777e3a 100644
--- a/arch/arm/boot/dts/spear600.dtsi
+++ b/arch/arm/boot/dts/spear600.dtsi
@@ -45,6 +45,14 @@
 			#interrupt-cells = <1>;
 		};
 
+		dma@fc400000 {
+			compatible = "arm,pl080", "arm,primecell";
+			reg = <0xfc400000 0x1000>;
+			interrupt-parent = <&vic1>;
+			interrupts = <10>;
+			status = "disabled";
+		};
+
 		gmac: ethernet@e0800000 {
 			compatible = "st,spear600-gmac";
 			reg = <0xe0800000 0x8000>;
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig
index fea7e1f..7ed4291 100644
--- a/arch/arm/configs/spear3xx_defconfig
+++ b/arch/arm/configs/spear3xx_defconfig
@@ -2,33 +2,67 @@
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_PLAT_SPEAR=y
-CONFIG_BOARD_SPEAR300_EVB=y
-CONFIG_BOARD_SPEAR310_EVB=y
-CONFIG_BOARD_SPEAR320_EVB=y
+CONFIG_MACH_SPEAR300=y
+CONFIG_MACH_SPEAR310=y
+CONFIG_MACH_SPEAR320=y
 CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_SPEAR=y
 # CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
+CONFIG_DMATEST=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_SECURITY=y
@@ -39,8 +73,6 @@
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=m
@@ -48,6 +80,4 @@
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig
index cef2e83..cf94bc7 100644
--- a/arch/arm/configs/spear6xx_defconfig
+++ b/arch/arm/configs/spear6xx_defconfig
@@ -2,29 +2,58 @@
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_PLAT_SPEAR=y
 CONFIG_ARCH_SPEAR6XX=y
-CONFIG_BOARD_SPEAR600_EVB=y
+CONFIG_BOARD_SPEAR600_DT=y
 CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
+CONFIG_DMATEST=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_SECURITY=y
@@ -35,8 +64,6 @@
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=m
@@ -44,6 +71,4 @@
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/mach-spear3xx/Kconfig b/arch/arm/mach-spear3xx/Kconfig
index 2cee6b0..8bd3729 100644
--- a/arch/arm/mach-spear3xx/Kconfig
+++ b/arch/arm/mach-spear3xx/Kconfig
@@ -5,39 +5,22 @@
 if ARCH_SPEAR3XX
 
 menu "SPEAr3xx Implementations"
-config BOARD_SPEAR300_EVB
-	bool "SPEAr300 Evaluation Board"
-	select MACH_SPEAR300
-	help
-	  Supports ST SPEAr300 Evaluation Board
-
-config BOARD_SPEAR310_EVB
-	bool "SPEAr310 Evaluation Board"
-	select MACH_SPEAR310
-	help
-	  Supports ST SPEAr310 Evaluation Board
-
-config BOARD_SPEAR320_EVB
-	bool "SPEAr320 Evaluation Board"
-	select MACH_SPEAR320
-	help
-	  Supports ST SPEAr320 Evaluation Board
-
-endmenu
-
 config MACH_SPEAR300
-	bool "SPEAr300"
+	bool "SPEAr300 Machine support with Device Tree"
+	select PINCTRL_SPEAR300
 	help
-	  Supports ST SPEAr300 Machine
+	  Supports ST SPEAr300 machine configured via the device-tree
 
 config MACH_SPEAR310
-	bool "SPEAr310"
+	bool "SPEAr310 Machine support with Device Tree"
+	select PINCTRL_SPEAR310
 	help
-	  Supports ST SPEAr310 Machine
+	  Supports ST SPEAr310 machine configured via the device-tree
 
 config MACH_SPEAR320
-	bool "SPEAr320"
+	bool "SPEAr320 Machine support with Device Tree"
+	select PINCTRL_SPEAR320
 	help
-	  Supports ST SPEAr320 Machine
-
+	  Supports ST SPEAr320 machine configured via the device-tree
+endmenu
 endif #ARCH_SPEAR3XX
diff --git a/arch/arm/mach-spear3xx/Makefile b/arch/arm/mach-spear3xx/Makefile
index b248624..17b5d83 100644
--- a/arch/arm/mach-spear3xx/Makefile
+++ b/arch/arm/mach-spear3xx/Makefile
@@ -3,24 +3,13 @@
 #
 
 # common files
-obj-y	+= spear3xx.o clock.o
+obj-$(CONFIG_ARCH_SPEAR3XX)	+= 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
index 4674a4c..d93e217 100644
--- a/arch/arm/mach-spear3xx/Makefile.boot
+++ b/arch/arm/mach-spear3xx/Makefile.boot
@@ -1,3 +1,7 @@
 zreladdr-y	+= 0x00008000
 params_phys-y	:= 0x00000100
 initrd_phys-y	:= 0x00800000
+
+dtb-$(CONFIG_MACH_SPEAR300)	+= spear300-evb.dtb
+dtb-$(CONFIG_MACH_SPEAR310)	+= spear310-evb.dtb
+dtb-$(CONFIG_MACH_SPEAR320)	+= spear320-evb.dtb
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 6c4841f..eeafe38 100644
--- a/arch/arm/mach-spear3xx/clock.c
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -11,9 +11,11 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clkdev.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/of_platform.h>
 #include <asm/mach-types.h>
 #include <plat/clock.h>
 #include <mach/misc_regs.h>
@@ -411,6 +413,21 @@
 	.recalc = &follow_parent,
 };
 
+/* clock derived from usbh clk */
+/* usbh0 clock */
+static struct clk usbh0_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &usbh_clk,
+	.recalc = &follow_parent,
+};
+
+/* usbh1 clock */
+static struct clk usbh1_clk = {
+	.flags = ALWAYS_ENABLED,
+	.pclk = &usbh_clk,
+	.recalc = &follow_parent,
+};
+
 /* clock derived from ahb clk */
 /* apb masks structure */
 static struct bus_clk_masks apb_masks = {
@@ -652,109 +669,126 @@
 
 /* array of all spear 3xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
-	{ .con_id = "apb_pclk",		.clk = &dummy_apb_pclk},
+	CLKDEV_INIT(NULL, "apb_pclk", &dummy_apb_pclk),
 	/* root clks */
-	{ .con_id = "osc_32k_clk",	.clk = &osc_32k_clk},
-	{ .con_id = "osc_24m_clk",	.clk = &osc_24m_clk},
+	CLKDEV_INIT(NULL, "osc_32k_clk", &osc_32k_clk),
+	CLKDEV_INIT(NULL, "osc_24m_clk", &osc_24m_clk),
 	/* clock derived from 32 KHz osc clk */
-	{ .dev_id = "rtc-spear",	.clk = &rtc_clk},
+	CLKDEV_INIT("fc900000.rtc", NULL, &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},
+	CLKDEV_INIT(NULL, "pll1_clk", &pll1_clk),
+	CLKDEV_INIT(NULL, "pll3_48m_clk", &pll3_48m_clk),
+	CLKDEV_INIT("fc880000.wdt", NULL, &wdt_clk),
 	/* clock derived from pll1 clk */
-	{ .con_id = "cpu_clk",		.clk = &cpu_clk},
-	{ .con_id = "ahb_clk",		.clk = &ahb_clk},
-	{ .con_id = "uart_synth_clk",	.clk = &uart_synth_clk},
-	{ .con_id = "firda_synth_clk",	.clk = &firda_synth_clk},
-	{ .con_id = "gpt0_synth_clk",	.clk = &gpt0_synth_clk},
-	{ .con_id = "gpt1_synth_clk",	.clk = &gpt1_synth_clk},
-	{ .con_id = "gpt2_synth_clk",	.clk = &gpt2_synth_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},
+	CLKDEV_INIT(NULL, "cpu_clk", &cpu_clk),
+	CLKDEV_INIT(NULL, "ahb_clk", &ahb_clk),
+	CLKDEV_INIT(NULL, "uart_synth_clk", &uart_synth_clk),
+	CLKDEV_INIT(NULL, "firda_synth_clk", &firda_synth_clk),
+	CLKDEV_INIT(NULL, "gpt0_synth_clk", &gpt0_synth_clk),
+	CLKDEV_INIT(NULL, "gpt1_synth_clk", &gpt1_synth_clk),
+	CLKDEV_INIT(NULL, "gpt2_synth_clk", &gpt2_synth_clk),
+	CLKDEV_INIT("d0000000.serial", NULL, &uart_clk),
+	CLKDEV_INIT("firda", NULL, &firda_clk),
+	CLKDEV_INIT("gpt0", NULL, &gpt0_clk),
+	CLKDEV_INIT("gpt1", NULL, &gpt1_clk),
+	CLKDEV_INIT("gpt2", NULL, &gpt2_clk),
 	/* clock derived from pll3 clk */
-	{ .dev_id = "designware_udc",   .clk = &usbd_clk},
-	{ .con_id = "usbh_clk",		.clk = &usbh_clk},
+	CLKDEV_INIT("designware_udc", NULL, &usbd_clk),
+	CLKDEV_INIT(NULL, "usbh_clk", &usbh_clk),
+	/* clock derived from usbh clk */
+	CLKDEV_INIT(NULL, "usbh.0_clk", &usbh0_clk),
+	CLKDEV_INIT(NULL, "usbh.1_clk", &usbh1_clk),
 	/* clock derived from ahb clk */
-	{ .con_id = "apb_clk",		.clk = &apb_clk},
-	{ .dev_id = "i2c_designware.0",	.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},
+	CLKDEV_INIT(NULL, "apb_clk", &apb_clk),
+	CLKDEV_INIT("d0180000.i2c", NULL, &i2c_clk),
+	CLKDEV_INIT("fc400000.dma", NULL, &dma_clk),
+	CLKDEV_INIT("jpeg", NULL, &jpeg_clk),
+	CLKDEV_INIT("e0800000.eth", NULL, &gmac_clk),
+	CLKDEV_INIT("fc000000.flash", NULL, &smi_clk),
+	CLKDEV_INIT("c3", NULL, &c3_clk),
 	/* clock derived from apb clk */
-	{ .dev_id = "adc",		.clk = &adc_clk},
-	{ .dev_id = "ssp-pl022.0",	.clk = &ssp0_clk},
-	{ .dev_id = "gpio",		.clk = &gpio_clk},
+	CLKDEV_INIT("adc", NULL, &adc_clk),
+	CLKDEV_INIT("d0100000.spi", NULL, &ssp0_clk),
+	CLKDEV_INIT("fc980000.gpio", NULL, &gpio_clk),
 };
 
 /* array of all spear 300 clock lookups */
 #ifdef CONFIG_MACH_SPEAR300
 static struct clk_lookup spear300_clk_lookups[] = {
-	{ .dev_id = "clcd",		.clk = &clcd_clk},
-	{ .con_id = "fsmc",		.clk = &fsmc_clk},
-	{ .dev_id = "gpio1",		.clk = &gpio1_clk},
-	{ .dev_id = "keyboard",		.clk = &kbd_clk},
-	{ .dev_id = "sdhci",		.clk = &sdhci_clk},
+	CLKDEV_INIT("60000000.clcd", NULL, &clcd_clk),
+	CLKDEV_INIT("94000000.flash", NULL, &fsmc_clk),
+	CLKDEV_INIT("a9000000.gpio", NULL, &gpio1_clk),
+	CLKDEV_INIT("a0000000.kbd", NULL, &kbd_clk),
+	CLKDEV_INIT("70000000.sdhci", NULL, &sdhci_clk),
 };
+
+void __init spear300_clk_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+		clk_register(&spear_clk_lookups[i]);
+
+	for (i = 0; i < ARRAY_SIZE(spear300_clk_lookups); i++)
+		clk_register(&spear300_clk_lookups[i]);
+
+	clk_init();
+}
 #endif
 
 /* array of all spear 310 clock lookups */
 #ifdef CONFIG_MACH_SPEAR310
 static struct clk_lookup spear310_clk_lookups[] = {
-	{ .con_id = "fsmc",		.clk = &fsmc_clk},
-	{ .con_id = "emi",		.clk = &emi_clk},
-	{ .dev_id = "uart1",		.clk = &uart1_clk},
-	{ .dev_id = "uart2",		.clk = &uart2_clk},
-	{ .dev_id = "uart3",		.clk = &uart3_clk},
-	{ .dev_id = "uart4",		.clk = &uart4_clk},
-	{ .dev_id = "uart5",		.clk = &uart5_clk},
+	CLKDEV_INIT("44000000.flash", NULL, &fsmc_clk),
+	CLKDEV_INIT(NULL, "emi", &emi_clk),
+	CLKDEV_INIT("b2000000.serial", NULL, &uart1_clk),
+	CLKDEV_INIT("b2080000.serial", NULL, &uart2_clk),
+	CLKDEV_INIT("b2100000.serial", NULL, &uart3_clk),
+	CLKDEV_INIT("b2180000.serial", NULL, &uart4_clk),
+	CLKDEV_INIT("b2200000.serial", NULL, &uart5_clk),
 };
+
+void __init spear310_clk_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+		clk_register(&spear_clk_lookups[i]);
+
+	for (i = 0; i < ARRAY_SIZE(spear310_clk_lookups); i++)
+		clk_register(&spear310_clk_lookups[i]);
+
+	clk_init();
+}
 #endif
 
 /* array of all spear 320 clock lookups */
 #ifdef CONFIG_MACH_SPEAR320
 static struct clk_lookup spear320_clk_lookups[] = {
-	{ .dev_id = "clcd",		.clk = &clcd_clk},
-	{ .con_id = "fsmc",		.clk = &fsmc_clk},
-	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
-	{ .con_id = "emi",		.clk = &emi_clk},
-	{ .dev_id = "pwm",		.clk = &pwm_clk},
-	{ .dev_id = "sdhci",		.clk = &sdhci_clk},
-	{ .dev_id = "c_can_platform.0",	.clk = &can0_clk},
-	{ .dev_id = "c_can_platform.1",	.clk = &can1_clk},
-	{ .dev_id = "ssp-pl022.1",	.clk = &ssp1_clk},
-	{ .dev_id = "ssp-pl022.2",	.clk = &ssp2_clk},
-	{ .dev_id = "uart1",		.clk = &uart1_clk},
-	{ .dev_id = "uart2",		.clk = &uart2_clk},
+	CLKDEV_INIT("90000000.clcd", NULL, &clcd_clk),
+	CLKDEV_INIT("4c000000.flash", NULL, &fsmc_clk),
+	CLKDEV_INIT("a7000000.i2c", NULL, &i2c1_clk),
+	CLKDEV_INIT(NULL, "emi", &emi_clk),
+	CLKDEV_INIT("pwm", NULL, &pwm_clk),
+	CLKDEV_INIT("70000000.sdhci", NULL, &sdhci_clk),
+	CLKDEV_INIT("c_can_platform.0", NULL, &can0_clk),
+	CLKDEV_INIT("c_can_platform.1", NULL, &can1_clk),
+	CLKDEV_INIT("a5000000.spi", NULL, &ssp1_clk),
+	CLKDEV_INIT("a6000000.spi", NULL, &ssp2_clk),
+	CLKDEV_INIT("a3000000.serial", NULL, &uart1_clk),
+	CLKDEV_INIT("a4000000.serial", NULL, &uart2_clk),
 };
-#endif
 
-void __init spear3xx_clk_init(void)
+void __init spear320_clk_init(void)
 {
-	int i, cnt;
-	struct clk_lookup *lookups;
-
-	if (machine_is_spear300()) {
-		cnt = ARRAY_SIZE(spear300_clk_lookups);
-		lookups = spear300_clk_lookups;
-	} else if (machine_is_spear310()) {
-		cnt = ARRAY_SIZE(spear310_clk_lookups);
-		lookups = spear310_clk_lookups;
-	} else {
-		cnt = ARRAY_SIZE(spear320_clk_lookups);
-		lookups = spear320_clk_lookups;
-	}
+	int i;
 
 	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
 		clk_register(&spear_clk_lookups[i]);
 
-	for (i = 0; i < cnt; i++)
-		clk_register(&lookups[i]);
+	for (i = 0; i < ARRAY_SIZE(spear320_clk_lookups); i++)
+		clk_register(&spear320_clk_lookups[i]);
 
 	clk_init();
 }
+#endif
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index 14276e5..9603bf4 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -14,12 +14,12 @@
 #ifndef __MACH_GENERIC_H
 #define __MACH_GENERIC_H
 
+#include <linux/amba/pl08x.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <plat/padmux.h>
 
 /* spear3xx declarations */
 /*
@@ -31,171 +31,32 @@
 #define SPEAR_GPT0_CHAN1_IRQ	SPEAR3XX_IRQ_CPU_GPT1_2
 
 /* Add spear3xx family device structure declarations here */
-extern struct amba_device spear3xx_gpio_device;
-extern struct amba_device spear3xx_uart_device;
 extern struct sys_timer spear3xx_timer;
+extern struct pl022_ssp_controller pl022_plat_data;
+extern struct pl08x_platform_data pl080_plat_data;
 
 /* Add spear3xx family function declarations here */
-void __init spear3xx_clk_init(void);
 void __init spear_setup_timer(void);
 void __init spear3xx_map_io(void);
-void __init spear3xx_init_irq(void);
-void __init spear3xx_init(void);
+void __init spear3xx_dt_init_irq(void);
 
 void spear_restart(char, const char *);
 
-/* 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 spear3xx_pmx_firda;
-extern struct pmx_dev spear3xx_pmx_i2c;
-extern struct pmx_dev spear3xx_pmx_ssp_cs;
-extern struct pmx_dev spear3xx_pmx_ssp;
-extern struct pmx_dev spear3xx_pmx_mii;
-extern struct pmx_dev spear3xx_pmx_gpio_pin0;
-extern struct pmx_dev spear3xx_pmx_gpio_pin1;
-extern struct pmx_dev spear3xx_pmx_gpio_pin2;
-extern struct pmx_dev spear3xx_pmx_gpio_pin3;
-extern struct pmx_dev spear3xx_pmx_gpio_pin4;
-extern struct pmx_dev spear3xx_pmx_gpio_pin5;
-extern struct pmx_dev spear3xx_pmx_uart0_modem;
-extern struct pmx_dev spear3xx_pmx_uart0;
-extern struct pmx_dev spear3xx_pmx_timer_3_4;
-extern struct pmx_dev spear3xx_pmx_timer_1_2;
-
-#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-/* padmux plgpio devices */
-extern struct pmx_dev spear3xx_pmx_plgpio_0_1;
-extern struct pmx_dev spear3xx_pmx_plgpio_2_3;
-extern struct pmx_dev spear3xx_pmx_plgpio_4_5;
-extern struct pmx_dev spear3xx_pmx_plgpio_6_9;
-extern struct pmx_dev spear3xx_pmx_plgpio_10_27;
-extern struct pmx_dev spear3xx_pmx_plgpio_28;
-extern struct pmx_dev spear3xx_pmx_plgpio_29;
-extern struct pmx_dev spear3xx_pmx_plgpio_30;
-extern struct pmx_dev spear3xx_pmx_plgpio_31;
-extern struct pmx_dev spear3xx_pmx_plgpio_32;
-extern struct pmx_dev spear3xx_pmx_plgpio_33;
-extern struct pmx_dev spear3xx_pmx_plgpio_34_36;
-extern struct pmx_dev spear3xx_pmx_plgpio_37_42;
-extern struct pmx_dev spear3xx_pmx_plgpio_43_44_47_48;
-extern struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50;
-#endif
-
 /* spear300 declarations */
 #ifdef CONFIG_MACH_SPEAR300
-/* Add spear300 machine device structure declarations here */
-extern struct amba_device spear300_gpio1_device;
-
-/* pad mux modes */
-extern struct pmx_mode spear300_nand_mode;
-extern struct pmx_mode spear300_nor_mode;
-extern struct pmx_mode spear300_photo_frame_mode;
-extern struct pmx_mode spear300_lend_ip_phone_mode;
-extern struct pmx_mode spear300_hend_ip_phone_mode;
-extern struct pmx_mode spear300_lend_wifi_phone_mode;
-extern struct pmx_mode spear300_hend_wifi_phone_mode;
-extern struct pmx_mode spear300_ata_pabx_wi2s_mode;
-extern struct pmx_mode spear300_ata_pabx_i2s_mode;
-extern struct pmx_mode spear300_caml_lcdw_mode;
-extern struct pmx_mode spear300_camu_lcd_mode;
-extern struct pmx_mode spear300_camu_wlcd_mode;
-extern struct pmx_mode spear300_caml_lcd_mode;
-
-/* pad mux devices */
-extern struct pmx_dev spear300_pmx_fsmc_2_chips;
-extern struct pmx_dev spear300_pmx_fsmc_4_chips;
-extern struct pmx_dev spear300_pmx_keyboard;
-extern struct pmx_dev spear300_pmx_clcd;
-extern struct pmx_dev spear300_pmx_telecom_gpio;
-extern struct pmx_dev spear300_pmx_telecom_tdm;
-extern struct pmx_dev spear300_pmx_telecom_spi_cs_i2c_clk;
-extern struct pmx_dev spear300_pmx_telecom_camera;
-extern struct pmx_dev spear300_pmx_telecom_dac;
-extern struct pmx_dev spear300_pmx_telecom_i2s;
-extern struct pmx_dev spear300_pmx_telecom_boot_pins;
-extern struct pmx_dev spear300_pmx_telecom_sdhci_4bit;
-extern struct pmx_dev spear300_pmx_telecom_sdhci_8bit;
-extern struct pmx_dev spear300_pmx_gpio1;
-
-/* Add spear300 machine function declarations here */
-void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-		u8 pmx_dev_count);
+void __init spear300_clk_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 spear310_pmx_emi_cs_0_1_4_5;
-extern struct pmx_dev spear310_pmx_emi_cs_2_3;
-extern struct pmx_dev spear310_pmx_uart1;
-extern struct pmx_dev spear310_pmx_uart2;
-extern struct pmx_dev spear310_pmx_uart3_4_5;
-extern struct pmx_dev spear310_pmx_fsmc;
-extern struct pmx_dev spear310_pmx_rs485_0_1;
-extern struct pmx_dev spear310_pmx_tdm0;
-
-/* Add spear310 machine function declarations here */
-void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-		u8 pmx_dev_count);
+void __init spear310_clk_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 spear320_auto_net_smii_mode;
-extern struct pmx_mode spear320_auto_net_mii_mode;
-extern struct pmx_mode spear320_auto_exp_mode;
-extern struct pmx_mode spear320_small_printers_mode;
-
-/* pad mux devices */
-extern struct pmx_dev spear320_pmx_clcd;
-extern struct pmx_dev spear320_pmx_emi;
-extern struct pmx_dev spear320_pmx_fsmc;
-extern struct pmx_dev spear320_pmx_spp;
-extern struct pmx_dev spear320_pmx_sdhci;
-extern struct pmx_dev spear320_pmx_i2s;
-extern struct pmx_dev spear320_pmx_uart1;
-extern struct pmx_dev spear320_pmx_uart1_modem;
-extern struct pmx_dev spear320_pmx_uart2;
-extern struct pmx_dev spear320_pmx_touchscreen;
-extern struct pmx_dev spear320_pmx_can;
-extern struct pmx_dev spear320_pmx_sdhci_led;
-extern struct pmx_dev spear320_pmx_pwm0;
-extern struct pmx_dev spear320_pmx_pwm1;
-extern struct pmx_dev spear320_pmx_pwm2;
-extern struct pmx_dev spear320_pmx_pwm3;
-extern struct pmx_dev spear320_pmx_ssp1;
-extern struct pmx_dev spear320_pmx_ssp2;
-extern struct pmx_dev spear320_pmx_mii1;
-extern struct pmx_dev spear320_pmx_smii0;
-extern struct pmx_dev spear320_pmx_smii1;
-extern struct pmx_dev spear320_pmx_i2c1;
-
-/* Add spear320 machine function declarations here */
-void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-		u8 pmx_dev_count);
+void __init spear320_clk_init(void);
 
 #endif /* CONFIG_MACH_SPEAR320 */
 
diff --git a/arch/arm/mach-spear3xx/include/mach/hardware.h b/arch/arm/mach-spear3xx/include/mach/hardware.h
index 4660c0d..defa374 100644
--- a/arch/arm/mach-spear3xx/include/mach/hardware.h
+++ b/arch/arm/mach-spear3xx/include/mach/hardware.h
@@ -17,7 +17,4 @@
 #include <plat/hardware.h>
 #include <mach/spear.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/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h
index 63fd9835..8e3900a 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear.h
@@ -25,8 +25,9 @@
 
 /* ICM1 - Low speed connection */
 #define SPEAR3XX_ICM1_2_BASE		UL(0xD0000000)
+#define VA_SPEAR3XX_ICM1_2_BASE		UL(0xFD000000)
 #define SPEAR3XX_ICM1_UART_BASE		UL(0xD0000000)
-#define VA_SPEAR3XX_ICM1_UART_BASE	IO_ADDRESS(SPEAR3XX_ICM1_UART_BASE)
+#define VA_SPEAR3XX_ICM1_UART_BASE	(VA_SPEAR3XX_ICM1_2_BASE | SPEAR3XX_ICM1_UART_BASE)
 #define SPEAR3XX_ICM1_ADC_BASE		UL(0xD0080000)
 #define SPEAR3XX_ICM1_SSP_BASE		UL(0xD0100000)
 #define SPEAR3XX_ICM1_I2C_BASE		UL(0xD0180000)
@@ -53,11 +54,11 @@
 #define SPEAR3XX_ICM3_ML1_2_BASE	UL(0xF0000000)
 #define SPEAR3XX_ML1_TMR_BASE		UL(0xF0000000)
 #define SPEAR3XX_ML1_VIC_BASE		UL(0xF1100000)
-#define VA_SPEAR3XX_ML1_VIC_BASE	IO_ADDRESS(SPEAR3XX_ML1_VIC_BASE)
 
 /* ICM3 - Basic Subsystem */
 #define SPEAR3XX_ICM3_SMEM_BASE		UL(0xF8000000)
 #define SPEAR3XX_ICM3_SMI_CTRL_BASE	UL(0xFC000000)
+#define VA_SPEAR3XX_ICM3_SMI_CTRL_BASE	UL(0xFC000000)
 #define SPEAR3XX_ICM3_DMA_BASE		UL(0xFC400000)
 #define SPEAR3XX_ICM3_SDRAM_CTRL_BASE	UL(0xFC600000)
 #define SPEAR3XX_ICM3_TMR0_BASE		UL(0xFC800000)
@@ -65,9 +66,9 @@
 #define SPEAR3XX_ICM3_RTC_BASE		UL(0xFC900000)
 #define SPEAR3XX_ICM3_GPIO_BASE		UL(0xFC980000)
 #define SPEAR3XX_ICM3_SYS_CTRL_BASE	UL(0xFCA00000)
-#define VA_SPEAR3XX_ICM3_SYS_CTRL_BASE	IO_ADDRESS(SPEAR3XX_ICM3_SYS_CTRL_BASE)
+#define VA_SPEAR3XX_ICM3_SYS_CTRL_BASE	(VA_SPEAR3XX_ICM3_SMI_CTRL_BASE | SPEAR3XX_ICM3_SYS_CTRL_BASE)
 #define SPEAR3XX_ICM3_MISC_REG_BASE	UL(0xFCA80000)
-#define VA_SPEAR3XX_ICM3_MISC_REG_BASE	IO_ADDRESS(SPEAR3XX_ICM3_MISC_REG_BASE)
+#define VA_SPEAR3XX_ICM3_MISC_REG_BASE	(VA_SPEAR3XX_ICM3_SMI_CTRL_BASE | SPEAR3XX_ICM3_MISC_REG_BASE)
 #define SPEAR3XX_ICM3_TMR1_BASE		UL(0xFCB00000)
 
 /* Debug uart for linux, will be used for debug and uncompress messages */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index f7db668..2db0bd1 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -3,373 +3,24 @@
  *
  * SPEAr300 machine source file
  *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Copyright (C) 2009-2012 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>
+#define pr_fmt(fmt) "SPEAr300: " fmt
+
+#include <linux/amba/pl08x.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/vic.h>
+#include <asm/mach/arch.h>
 #include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/hardware.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 spear300_nand_mode = {
-	.id = NAND_MODE,
-	.name = "nand mode",
-	.mask = 0x00,
-};
-
-struct pmx_mode spear300_nor_mode = {
-	.id = NOR_MODE,
-	.name = "nor mode",
-	.mask = 0x01,
-};
-
-struct pmx_mode spear300_photo_frame_mode = {
-	.id = PHOTO_FRAME_MODE,
-	.name = "photo frame mode",
-	.mask = 0x02,
-};
-
-struct pmx_mode spear300_lend_ip_phone_mode = {
-	.id = LEND_IP_PHONE_MODE,
-	.name = "lend ip phone mode",
-	.mask = 0x03,
-};
-
-struct pmx_mode spear300_hend_ip_phone_mode = {
-	.id = HEND_IP_PHONE_MODE,
-	.name = "hend ip phone mode",
-	.mask = 0x04,
-};
-
-struct pmx_mode spear300_lend_wifi_phone_mode = {
-	.id = LEND_WIFI_PHONE_MODE,
-	.name = "lend wifi phone mode",
-	.mask = 0x05,
-};
-
-struct pmx_mode spear300_hend_wifi_phone_mode = {
-	.id = HEND_WIFI_PHONE_MODE,
-	.name = "hend wifi phone mode",
-	.mask = 0x06,
-};
-
-struct pmx_mode spear300_ata_pabx_wi2s_mode = {
-	.id = ATA_PABX_WI2S_MODE,
-	.name = "ata pabx wi2s mode",
-	.mask = 0x07,
-};
-
-struct pmx_mode spear300_ata_pabx_i2s_mode = {
-	.id = ATA_PABX_I2S_MODE,
-	.name = "ata pabx i2s mode",
-	.mask = 0x08,
-};
-
-struct pmx_mode spear300_caml_lcdw_mode = {
-	.id = CAML_LCDW_MODE,
-	.name = "caml lcdw mode",
-	.mask = 0x0C,
-};
-
-struct pmx_mode spear300_camu_lcd_mode = {
-	.id = CAMU_LCD_MODE,
-	.name = "camu lcd mode",
-	.mask = 0x0D,
-};
-
-struct pmx_mode spear300_camu_wlcd_mode = {
-	.id = CAMU_WLCD_MODE,
-	.name = "camu wlcd mode",
-	.mask = 0x0E,
-};
-
-struct pmx_mode spear300_caml_lcd_mode = {
-	.id = CAML_LCD_MODE,
-	.name = "caml lcd mode",
-	.mask = 0x0F,
-};
-
-/* devices */
-static 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 spear300_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,
-};
-
-static 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 spear300_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,
-};
-
-static 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 spear300_pmx_keyboard = {
-	.name = "keyboard",
-	.modes = pmx_keyboard_modes,
-	.mode_count = ARRAY_SIZE(pmx_keyboard_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear300_pmx_clcd = {
-	.name = "clcd",
-	.modes = pmx_clcd_modes,
-	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear300_pmx_telecom_gpio = {
-	.name = "telecom_gpio",
-	.modes = pmx_telecom_gpio_modes,
-	.mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear300_pmx_telecom_tdm = {
-	.name = "telecom_tdm",
-	.modes = pmx_telecom_tdm_modes,
-	.mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear300_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,
-};
-
-static 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 spear300_pmx_telecom_camera = {
-	.name = "telecom_camera",
-	.modes = pmx_telecom_camera_modes,
-	.mode_count = ARRAY_SIZE(pmx_telecom_camera_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear300_pmx_telecom_dac = {
-	.name = "telecom_dac",
-	.modes = pmx_telecom_dac_modes,
-	.mode_count = ARRAY_SIZE(pmx_telecom_dac_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear300_pmx_telecom_i2s = {
-	.name = "telecom_i2s",
-	.modes = pmx_telecom_i2s_modes,
-	.mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear300_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,
-};
-
-static struct pmx_dev_mode pmx_telecom_sdhci_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 spear300_pmx_telecom_sdhci_4bit = {
-	.name = "telecom_sdhci_4bit",
-	.modes = pmx_telecom_sdhci_4bit_modes,
-	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_4bit_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_sdhci_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 spear300_pmx_telecom_sdhci_8bit = {
-	.name = "telecom_sdhci_8bit",
-	.modes = pmx_telecom_sdhci_8bit_modes,
-	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_8bit_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear300_pmx_gpio1 = {
-	.name = "arm gpio1",
-	.modes = pmx_gpio1_modes,
-	.mode_count = ARRAY_SIZE(pmx_gpio1_modes),
-	.enb_on_reset = 1,
-};
-
-/* pmx driver structure */
-static struct pmx_driver pmx_driver = {
-	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f},
-	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
-};
-
 /* spear3xx shared irq */
 static struct shirq_dev_config shirq_ras1_config[] = {
 	{
@@ -423,45 +74,239 @@
 	},
 };
 
-/* Add spear300 specific devices here */
-/* arm gpio1 device registration */
-static struct pl061_platform_data gpio1_plat_data = {
-	.gpio_base	= 8,
-	.irq_base	= SPEAR300_GPIO1_INT_BASE,
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear300_dma_info[] = {
+	{
+		.bus_id = "uart0_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "irda",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "adc",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "to_jpeg",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "from_jpeg",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras0_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras0_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras1_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras1_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras2_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras2_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras3_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras3_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras4_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras4_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	},
 };
 
-AMBA_APB_DEVICE(spear300_gpio1, "gpio1", 0, SPEAR300_GPIO_BASE,
-	{SPEAR300_VIRQ_GPIO1}, &gpio1_plat_data);
+/* Add SPEAr300 auxdata to pass platform data */
+static struct of_dev_auxdata spear300_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+			&pl022_plat_data),
+	OF_DEV_AUXDATA("arm,pl080", SPEAR3XX_ICM3_DMA_BASE, NULL,
+			&pl080_plat_data),
+	{}
+};
 
-/* spear300 routines */
-void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-		u8 pmx_dev_count)
+static void __init spear300_dt_init(void)
 {
-	int ret = 0;
+	int ret;
 
-	/* call spear3xx family common init function */
-	spear3xx_init();
+	pl080_plat_data.slave_channels = spear300_dma_info;
+	pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear300_dma_info);
+
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear300_auxdata_lookup, NULL);
 
 	/* shared irq registration */
 	shirq_ras1.regs.base = ioremap(SPEAR300_TELECOM_BASE, SZ_4K);
 	if (shirq_ras1.regs.base) {
 		ret = spear_shirq_register(&shirq_ras1);
 		if (ret)
-			printk(KERN_ERR "Error registering Shared IRQ\n");
-	}
-
-	/* pmx initialization */
-	pmx_driver.mode = pmx_mode;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = pmx_dev_count;
-
-	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE, SZ_4K);
-	if (pmx_driver.base) {
-		ret = pmx_register(&pmx_driver);
-		if (ret)
-			printk(KERN_ERR "padmux: registration failed. err no"
-					": %d\n", ret);
-		/* Free Mapping, device selection already done */
-		iounmap(pmx_driver.base);
+			pr_err("Error registering Shared IRQ\n");
 	}
 }
+
+static const char * const spear300_dt_board_compat[] = {
+	"st,spear300",
+	"st,spear300-evb",
+	NULL,
+};
+
+static void __init spear300_map_io(void)
+{
+	spear3xx_map_io();
+	spear300_clk_init();
+}
+
+DT_MACHINE_START(SPEAR300_DT, "ST SPEAr300 SoC with Flattened Device Tree")
+	.map_io		=	spear300_map_io,
+	.init_irq	=	spear3xx_dt_init_irq,
+	.handle_irq	=	vic_handle_irq,
+	.timer		=	&spear3xx_timer,
+	.init_machine	=	spear300_dt_init,
+	.restart	=	spear_restart,
+	.dt_compat	=	spear300_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
deleted file mode 100644
index 3462ab9..0000000
--- a/arch/arm/mach-spear3xx/spear300_evb.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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/hardware/vic.h>
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <mach/generic.h>
-#include <mach/hardware.h>
-
-/* padmux devices to enable */
-static struct pmx_dev *pmx_devs[] = {
-	/* spear3xx specific devices */
-	&spear3xx_pmx_i2c,
-	&spear3xx_pmx_ssp_cs,
-	&spear3xx_pmx_ssp,
-	&spear3xx_pmx_mii,
-	&spear3xx_pmx_uart0,
-
-	/* spear300 specific devices */
-	&spear300_pmx_fsmc_2_chips,
-	&spear300_pmx_clcd,
-	&spear300_pmx_telecom_sdhci_4bit,
-	&spear300_pmx_gpio1,
-};
-
-static struct amba_device *amba_devs[] __initdata = {
-	/* spear3xx specific devices */
-	&spear3xx_gpio_device,
-	&spear3xx_uart_device,
-
-	/* spear300 specific devices */
-	&spear300_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(&spear300_photo_frame_mode, pmx_devs,
-			ARRAY_SIZE(pmx_devs));
-
-	/* 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")
-	.atag_offset	=	0x100,
-	.map_io		=	spear3xx_map_io,
-	.init_irq	=	spear3xx_init_irq,
-	.handle_irq	=	vic_handle_irq,
-	.timer		=	&spear3xx_timer,
-	.init_machine	=	spear300_evb_init,
-	.restart	=	spear_restart,
-MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index febaa6f..aec07c9 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -3,142 +3,25 @@
  *
  * SPEAr310 machine source file
  *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Copyright (C) 2009-2012 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>
+#define pr_fmt(fmt) "SPEAr310: " fmt
+
+#include <linux/amba/pl08x.h>
+#include <linux/amba/serial.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/vic.h>
+#include <asm/mach/arch.h>
 #include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
-/* pad multiplexing support */
-/* muxing registers */
-#define PAD_MUX_CONFIG_REG	0x08
-
-/* devices */
-static struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_TIMER_3_4_MASK,
-	},
-};
-
-struct pmx_dev spear310_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,
-};
-
-static struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_TIMER_1_2_MASK,
-	},
-};
-
-struct pmx_dev spear310_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,
-};
-
-static struct pmx_dev_mode pmx_uart1_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_FIRDA_MASK,
-	},
-};
-
-struct pmx_dev spear310_pmx_uart1 = {
-	.name = "uart1",
-	.modes = pmx_uart1_modes,
-	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart2_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_TIMER_1_2_MASK,
-	},
-};
-
-struct pmx_dev spear310_pmx_uart2 = {
-	.name = "uart2",
-	.modes = pmx_uart2_modes,
-	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_UART0_MODEM_MASK,
-	},
-};
-
-struct pmx_dev spear310_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,
-};
-
-static struct pmx_dev_mode pmx_fsmc_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_SSP_CS_MASK,
-	},
-};
-
-struct pmx_dev spear310_pmx_fsmc = {
-	.name = "fsmc",
-	.modes = pmx_fsmc_modes,
-	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_MII_MASK,
-	},
-};
-
-struct pmx_dev spear310_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,
-};
-
-static struct pmx_dev_mode pmx_tdm0_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_MII_MASK,
-	},
-};
-
-struct pmx_dev spear310_pmx_tdm0 = {
-	.name = "tdm0",
-	.modes = pmx_tdm0_modes,
-	.mode_count = ARRAY_SIZE(pmx_tdm0_modes),
-	.enb_on_reset = 1,
-};
-
-/* pmx driver structure */
-static struct pmx_driver pmx_driver = {
-	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
-};
-
 /* spear3xx shared irq */
 static struct shirq_dev_config shirq_ras1_config[] = {
 	{
@@ -255,17 +138,247 @@
 	},
 };
 
-/* Add spear310 specific devices here */
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear310_dma_info[] = {
+	{
+		.bus_id = "uart0_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "irda",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "adc",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "to_jpeg",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "from_jpeg",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart1_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart1_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart2_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart2_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart3_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart3_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart4_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart4_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart5_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart5_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	},
+};
 
-/* spear310 routines */
-void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-		u8 pmx_dev_count)
+/* uart devices plat data */
+static struct amba_pl011_data spear310_uart_data[] = {
+	{
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart1_tx",
+		.dma_rx_param = "uart1_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart2_tx",
+		.dma_rx_param = "uart2_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart3_tx",
+		.dma_rx_param = "uart3_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart4_tx",
+		.dma_rx_param = "uart4_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart5_tx",
+		.dma_rx_param = "uart5_rx",
+	},
+};
+
+/* Add SPEAr310 auxdata to pass platform data */
+static struct of_dev_auxdata spear310_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+			&pl022_plat_data),
+	OF_DEV_AUXDATA("arm,pl080", SPEAR3XX_ICM3_DMA_BASE, NULL,
+			&pl080_plat_data),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART1_BASE, NULL,
+			&spear310_uart_data[0]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART2_BASE, NULL,
+			&spear310_uart_data[1]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART3_BASE, NULL,
+			&spear310_uart_data[2]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART4_BASE, NULL,
+			&spear310_uart_data[3]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART5_BASE, NULL,
+			&spear310_uart_data[4]),
+	{}
+};
+
+static void __init spear310_dt_init(void)
 {
 	void __iomem *base;
-	int ret = 0;
+	int ret;
 
-	/* call spear3xx family common init function */
-	spear3xx_init();
+	pl080_plat_data.slave_channels = spear310_dma_info;
+	pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear310_dma_info);
+
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear310_auxdata_lookup, NULL);
 
 	/* shared irq registration */
 	base = ioremap(SPEAR310_SOC_CONFIG_BASE, SZ_4K);
@@ -274,35 +387,46 @@
 		shirq_ras1.regs.base = base;
 		ret = spear_shirq_register(&shirq_ras1);
 		if (ret)
-			printk(KERN_ERR "Error registering Shared IRQ 1\n");
+			pr_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");
+			pr_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");
+			pr_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");
+			pr_err("Error registering Shared IRQ 4\n");
 	}
-
-	/* pmx initialization */
-	pmx_driver.base = base;
-	pmx_driver.mode = pmx_mode;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = pmx_dev_count;
-
-	ret = pmx_register(&pmx_driver);
-	if (ret)
-		printk(KERN_ERR "padmux: registration failed. err no: %d\n",
-				ret);
 }
+
+static const char * const spear310_dt_board_compat[] = {
+	"st,spear310",
+	"st,spear310-evb",
+	NULL,
+};
+
+static void __init spear310_map_io(void)
+{
+	spear3xx_map_io();
+	spear310_clk_init();
+}
+
+DT_MACHINE_START(SPEAR310_DT, "ST SPEAr310 SoC with Flattened Device Tree")
+	.map_io		=	spear310_map_io,
+	.init_irq	=	spear3xx_dt_init_irq,
+	.handle_irq	=	vic_handle_irq,
+	.timer		=	&spear3xx_timer,
+	.init_machine	=	spear310_dt_init,
+	.restart	=	spear_restart,
+	.dt_compat	=	spear310_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
deleted file mode 100644
index f92c499..0000000
--- a/arch/arm/mach-spear3xx/spear310_evb.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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/hardware/vic.h>
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <mach/generic.h>
-#include <mach/hardware.h>
-
-/* padmux devices to enable */
-static struct pmx_dev *pmx_devs[] = {
-	/* spear3xx specific devices */
-	&spear3xx_pmx_i2c,
-	&spear3xx_pmx_ssp,
-	&spear3xx_pmx_gpio_pin0,
-	&spear3xx_pmx_gpio_pin1,
-	&spear3xx_pmx_gpio_pin2,
-	&spear3xx_pmx_gpio_pin3,
-	&spear3xx_pmx_gpio_pin4,
-	&spear3xx_pmx_gpio_pin5,
-	&spear3xx_pmx_uart0,
-
-	/* spear310 specific devices */
-	&spear310_pmx_emi_cs_0_1_4_5,
-	&spear310_pmx_emi_cs_2_3,
-	&spear310_pmx_uart1,
-	&spear310_pmx_uart2,
-	&spear310_pmx_uart3_4_5,
-	&spear310_pmx_fsmc,
-	&spear310_pmx_rs485_0_1,
-	&spear310_pmx_tdm0,
-};
-
-static struct amba_device *amba_devs[] __initdata = {
-	/* spear3xx specific devices */
-	&spear3xx_gpio_device,
-	&spear3xx_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(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
-
-	/* 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")
-	.atag_offset	=	0x100,
-	.map_io		=	spear3xx_map_io,
-	.init_irq	=	spear3xx_init_irq,
-	.handle_irq	=	vic_handle_irq,
-	.timer		=	&spear3xx_timer,
-	.init_machine	=	spear310_evb_init,
-	.restart	=	spear_restart,
-MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index deaaf19..4812c69 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -3,387 +3,26 @@
  *
  * SPEAr320 machine source file
  *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Copyright (C) 2009-2012 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>
+#define pr_fmt(fmt) "SPEAr320: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/amba/pl08x.h>
+#include <linux/amba/serial.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/vic.h>
+#include <asm/mach/arch.h>
 #include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/hardware.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 spear320_auto_net_smii_mode = {
-	.id = AUTO_NET_SMII_MODE,
-	.name = "Automation Networking SMII Mode",
-	.mask = 0x00,
-};
-
-struct pmx_mode spear320_auto_net_mii_mode = {
-	.id = AUTO_NET_MII_MODE,
-	.name = "Automation Networking MII Mode",
-	.mask = 0x01,
-};
-
-struct pmx_mode spear320_auto_exp_mode = {
-	.id = AUTO_EXP_MODE,
-	.name = "Automation Expanded Mode",
-	.mask = 0x02,
-};
-
-struct pmx_mode spear320_small_printers_mode = {
-	.id = SMALL_PRINTERS_MODE,
-	.name = "Small Printers Mode",
-	.mask = 0x03,
-};
-
-/* devices */
-static struct pmx_dev_mode pmx_clcd_modes[] = {
-	{
-		.ids = AUTO_NET_SMII_MODE,
-		.mask = 0x0,
-	},
-};
-
-struct pmx_dev spear320_pmx_clcd = {
-	.name = "clcd",
-	.modes = pmx_clcd_modes,
-	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear320_pmx_emi = {
-	.name = "emi",
-	.modes = pmx_emi_modes,
-	.mode_count = ARRAY_SIZE(pmx_emi_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_fsmc_modes[] = {
-	{
-		.ids = ALL_MODES,
-		.mask = 0x0,
-	},
-};
-
-struct pmx_dev spear320_pmx_fsmc = {
-	.name = "fsmc",
-	.modes = pmx_fsmc_modes,
-	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_spp_modes[] = {
-	{
-		.ids = SMALL_PRINTERS_MODE,
-		.mask = 0x0,
-	},
-};
-
-struct pmx_dev spear320_pmx_spp = {
-	.name = "spp",
-	.modes = pmx_spp_modes,
-	.mode_count = ARRAY_SIZE(pmx_spp_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_sdhci_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 spear320_pmx_sdhci = {
-	.name = "sdhci",
-	.modes = pmx_sdhci_modes,
-	.mode_count = ARRAY_SIZE(pmx_sdhci_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_i2s_modes[] = {
-	{
-		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
-		.mask = PMX_UART0_MODEM_MASK,
-	},
-};
-
-struct pmx_dev spear320_pmx_i2s = {
-	.name = "i2s",
-	.modes = pmx_i2s_modes,
-	.mode_count = ARRAY_SIZE(pmx_i2s_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart1_modes[] = {
-	{
-		.ids = ALL_MODES,
-		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
-	},
-};
-
-struct pmx_dev spear320_pmx_uart1 = {
-	.name = "uart1",
-	.modes = pmx_uart1_modes,
-	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear320_pmx_uart1_modem = {
-	.name = "uart1_modem",
-	.modes = pmx_uart1_modem_modes,
-	.mode_count = ARRAY_SIZE(pmx_uart1_modem_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart2_modes[] = {
-	{
-		.ids = ALL_MODES,
-		.mask = PMX_FIRDA_MASK,
-	},
-};
-
-struct pmx_dev spear320_pmx_uart2 = {
-	.name = "uart2",
-	.modes = pmx_uart2_modes,
-	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_touchscreen_modes[] = {
-	{
-		.ids = AUTO_NET_SMII_MODE,
-		.mask = PMX_SSP_CS_MASK,
-	},
-};
-
-struct pmx_dev spear320_pmx_touchscreen = {
-	.name = "touchscreen",
-	.modes = pmx_touchscreen_modes,
-	.mode_count = ARRAY_SIZE(pmx_touchscreen_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear320_pmx_can = {
-	.name = "can",
-	.modes = pmx_can_modes,
-	.mode_count = ARRAY_SIZE(pmx_can_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_sdhci_led_modes[] = {
-	{
-		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
-		.mask = PMX_SSP_CS_MASK,
-	},
-};
-
-struct pmx_dev spear320_pmx_sdhci_led = {
-	.name = "sdhci_led",
-	.modes = pmx_sdhci_led_modes,
-	.mode_count = ARRAY_SIZE(pmx_sdhci_led_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear320_pmx_pwm0 = {
-	.name = "pwm0",
-	.modes = pmx_pwm0_modes,
-	.mode_count = ARRAY_SIZE(pmx_pwm0_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear320_pmx_pwm1 = {
-	.name = "pwm1",
-	.modes = pmx_pwm1_modes,
-	.mode_count = ARRAY_SIZE(pmx_pwm1_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear320_pmx_pwm2 = {
-	.name = "pwm2",
-	.modes = pmx_pwm2_modes,
-	.mode_count = ARRAY_SIZE(pmx_pwm2_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear320_pmx_pwm3 = {
-	.name = "pwm3",
-	.modes = pmx_pwm3_modes,
-	.mode_count = ARRAY_SIZE(pmx_pwm3_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_ssp1_modes[] = {
-	{
-		.ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
-		.mask = PMX_MII_MASK,
-	},
-};
-
-struct pmx_dev spear320_pmx_ssp1 = {
-	.name = "ssp1",
-	.modes = pmx_ssp1_modes,
-	.mode_count = ARRAY_SIZE(pmx_ssp1_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_ssp2_modes[] = {
-	{
-		.ids = AUTO_NET_SMII_MODE,
-		.mask = PMX_MII_MASK,
-	},
-};
-
-struct pmx_dev spear320_pmx_ssp2 = {
-	.name = "ssp2",
-	.modes = pmx_ssp2_modes,
-	.mode_count = ARRAY_SIZE(pmx_ssp2_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_mii1_modes[] = {
-	{
-		.ids = AUTO_NET_MII_MODE,
-		.mask = 0x0,
-	},
-};
-
-struct pmx_dev spear320_pmx_mii1 = {
-	.name = "mii1",
-	.modes = pmx_mii1_modes,
-	.mode_count = ARRAY_SIZE(pmx_mii1_modes),
-	.enb_on_reset = 1,
-};
-
-static 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 spear320_pmx_smii0 = {
-	.name = "smii0",
-	.modes = pmx_smii0_modes,
-	.mode_count = ARRAY_SIZE(pmx_smii0_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_smii1_modes[] = {
-	{
-		.ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE,
-		.mask = PMX_MII_MASK,
-	},
-};
-
-struct pmx_dev spear320_pmx_smii1 = {
-	.name = "smii1",
-	.modes = pmx_smii1_modes,
-	.mode_count = ARRAY_SIZE(pmx_smii1_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_i2c1_modes[] = {
-	{
-		.ids = AUTO_EXP_MODE,
-		.mask = 0x0,
-	},
-};
-
-struct pmx_dev spear320_pmx_i2c1 = {
-	.name = "i2c1",
-	.modes = pmx_i2c1_modes,
-	.mode_count = ARRAY_SIZE(pmx_i2c1_modes),
-	.enb_on_reset = 1,
-};
-
-/* pmx driver structure */
-static struct pmx_driver pmx_driver = {
-	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007},
-	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
-};
-
 /* spear3xx shared irq */
 static struct shirq_dev_config shirq_ras1_config[] = {
 	{
@@ -508,17 +147,250 @@
 	},
 };
 
-/* Add spear320 specific devices here */
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear320_dma_info[] = {
+	{
+		.bus_id = "uart0_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c0_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c0_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "irda",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "adc",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "to_jpeg",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "from_jpeg",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp1_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp1_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp2_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp2_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "uart1_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "uart1_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "uart2_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "uart2_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2c1_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2c1_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2c2_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2c2_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2s_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "i2s_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "rs485_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "rs485_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	},
+};
 
-/* spear320 routines */
-void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-		u8 pmx_dev_count)
+static struct pl022_ssp_controller spear320_ssp_data[] = {
+	{
+		.bus_id = 1,
+		.enable_dma = 1,
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "ssp1_tx",
+		.dma_rx_param = "ssp1_rx",
+		.num_chipselect = 2,
+	}, {
+		.bus_id = 2,
+		.enable_dma = 1,
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "ssp2_tx",
+		.dma_rx_param = "ssp2_rx",
+		.num_chipselect = 2,
+	}
+};
+
+static struct amba_pl011_data spear320_uart_data[] = {
+	{
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart1_tx",
+		.dma_rx_param = "uart1_rx",
+	}, {
+		.dma_filter = pl08x_filter_id,
+		.dma_tx_param = "uart2_tx",
+		.dma_rx_param = "uart2_rx",
+	},
+};
+
+/* Add SPEAr310 auxdata to pass platform data */
+static struct of_dev_auxdata spear320_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+			&pl022_plat_data),
+	OF_DEV_AUXDATA("arm,pl080", SPEAR3XX_ICM3_DMA_BASE, NULL,
+			&pl080_plat_data),
+	OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP0_BASE, NULL,
+			&spear320_ssp_data[0]),
+	OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP1_BASE, NULL,
+			&spear320_ssp_data[1]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART1_BASE, NULL,
+			&spear320_uart_data[0]),
+	OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART2_BASE, NULL,
+			&spear320_uart_data[1]),
+	{}
+};
+
+static void __init spear320_dt_init(void)
 {
 	void __iomem *base;
-	int ret = 0;
+	int ret;
 
-	/* call spear3xx family common init function */
-	spear3xx_init();
+	pl080_plat_data.slave_channels = spear320_dma_info;
+	pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear320_dma_info);
+
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear320_auxdata_lookup, NULL);
 
 	/* shared irq registration */
 	base = ioremap(SPEAR320_SOC_CONFIG_BASE, SZ_4K);
@@ -527,29 +399,40 @@
 		shirq_ras1.regs.base = base;
 		ret = spear_shirq_register(&shirq_ras1);
 		if (ret)
-			printk(KERN_ERR "Error registering Shared IRQ 1\n");
+			pr_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");
+			pr_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");
+			pr_err("Error registering Shared IRQ 4\n");
 	}
-
-	/* pmx initialization */
-	pmx_driver.base = base;
-	pmx_driver.mode = pmx_mode;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = pmx_dev_count;
-
-	ret = pmx_register(&pmx_driver);
-	if (ret)
-		printk(KERN_ERR "padmux: registration failed. err no: %d\n",
-				ret);
 }
+
+static const char * const spear320_dt_board_compat[] = {
+	"st,spear320",
+	"st,spear320-evb",
+	NULL,
+};
+
+static void __init spear320_map_io(void)
+{
+	spear3xx_map_io();
+	spear320_clk_init();
+}
+
+DT_MACHINE_START(SPEAR320_DT, "ST SPEAr320 SoC with Flattened Device Tree")
+	.map_io		=	spear320_map_io,
+	.init_irq	=	spear3xx_dt_init_irq,
+	.handle_irq	=	vic_handle_irq,
+	.timer		=	&spear3xx_timer,
+	.init_machine	=	spear320_dt_init,
+	.restart	=	spear_restart,
+	.dt_compat	=	spear320_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
deleted file mode 100644
index 105334a..0000000
--- a/arch/arm/mach-spear3xx/spear320_evb.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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/hardware/vic.h>
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <mach/generic.h>
-#include <mach/hardware.h>
-
-/* padmux devices to enable */
-static struct pmx_dev *pmx_devs[] = {
-	/* spear3xx specific devices */
-	&spear3xx_pmx_i2c,
-	&spear3xx_pmx_ssp,
-	&spear3xx_pmx_mii,
-	&spear3xx_pmx_uart0,
-
-	/* spear320 specific devices */
-	&spear320_pmx_fsmc,
-	&spear320_pmx_sdhci,
-	&spear320_pmx_i2s,
-	&spear320_pmx_uart1,
-	&spear320_pmx_uart2,
-	&spear320_pmx_can,
-	&spear320_pmx_pwm0,
-	&spear320_pmx_pwm1,
-	&spear320_pmx_pwm2,
-	&spear320_pmx_mii1,
-};
-
-static struct amba_device *amba_devs[] __initdata = {
-	/* spear3xx specific devices */
-	&spear3xx_gpio_device,
-	&spear3xx_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(&spear320_auto_net_mii_mode, pmx_devs,
-			ARRAY_SIZE(pmx_devs));
-
-	/* 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")
-	.atag_offset	=	0x100,
-	.map_io		=	spear3xx_map_io,
-	.init_irq	=	spear3xx_init_irq,
-	.handle_irq	=	vic_handle_irq,
-	.timer		=	&spear3xx_timer,
-	.init_machine	=	spear320_evb_init,
-	.restart	=	spear_restart,
-MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index b1733c3..12bf879 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -3,71 +3,78 @@
  *
  * SPEAr3XX machines common source file
  *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Copyright (C) 2009-2012 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>
+#define pr_fmt(fmt) "SPEAr3xx: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/amba/pl08x.h>
+#include <linux/of_irq.h>
 #include <linux/io.h>
+#include <asm/hardware/pl080.h>
 #include <asm/hardware/vic.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
+#include <plat/pl080.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
-/* Add spear3xx machines common devices here */
-/* gpio device registration */
-static struct pl061_platform_data gpio_plat_data = {
-	.gpio_base	= 0,
-	.irq_base	= SPEAR3XX_GPIO_INT_BASE,
+/* ssp device registration */
+struct pl022_ssp_controller pl022_plat_data = {
+	.bus_id = 0,
+	.enable_dma = 1,
+	.dma_filter = pl08x_filter_id,
+	.dma_tx_param = "ssp0_tx",
+	.dma_rx_param = "ssp0_rx",
+	/*
+	 * This is number of spi devices that can be connected to spi. There are
+	 * two type of chipselects on which slave devices can work. One is chip
+	 * select provided by spi masters other is controlled through external
+	 * gpio's. We can't use chipselect provided from spi master (because as
+	 * soon as FIFO becomes empty, CS is disabled and transfer ends). So
+	 * this number now depends on number of gpios available for spi. each
+	 * slave on each master requires a separate gpio pin.
+	 */
+	.num_chipselect = 2,
 };
 
-AMBA_APB_DEVICE(spear3xx_gpio, "gpio", 0, SPEAR3XX_ICM3_GPIO_BASE,
-	{SPEAR3XX_IRQ_BASIC_GPIO}, &gpio_plat_data);
+/* dmac device registration */
+struct pl08x_platform_data pl080_plat_data = {
+	.memcpy_channel = {
+		.bus_id = "memcpy",
+		.cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+			PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
+			PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
+			PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
+			PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
+			PL080_CONTROL_PROT_SYS),
+	},
+	.lli_buses = PL08X_AHB1,
+	.mem_buses = PL08X_AHB1,
+	.get_signal = pl080_get_signal,
+	.put_signal = pl080_put_signal,
+};
 
-/* uart device registration */
-AMBA_APB_DEVICE(spear3xx_uart, "uart", 0, SPEAR3XX_ICM1_UART_BASE,
-	{SPEAR3XX_IRQ_UART}, NULL);
-
-/* 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 */
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL		VIRTUAL
+ * 0xD0000000		0xFD000000
+ * 0xFC000000		0xFC000000
+ */
 struct map_desc spear3xx_io_desc[] __initdata = {
 	{
-		.virtual	= VA_SPEAR3XX_ICM1_UART_BASE,
-		.pfn		= __phys_to_pfn(SPEAR3XX_ICM1_UART_BASE),
-		.length		= SZ_4K,
+		.virtual	= VA_SPEAR3XX_ICM1_2_BASE,
+		.pfn		= __phys_to_pfn(SPEAR3XX_ICM1_2_BASE),
+		.length		= SZ_16M,
 		.type		= MT_DEVICE
 	}, {
-		.virtual	= VA_SPEAR3XX_ML1_VIC_BASE,
-		.pfn		= __phys_to_pfn(SPEAR3XX_ML1_VIC_BASE),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= VA_SPEAR3XX_ICM3_SYS_CTRL_BASE,
-		.pfn		= __phys_to_pfn(SPEAR3XX_ICM3_SYS_CTRL_BASE),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= VA_SPEAR3XX_ICM3_MISC_REG_BASE,
-		.pfn		= __phys_to_pfn(SPEAR3XX_ICM3_MISC_REG_BASE),
-		.length		= SZ_4K,
+		.virtual	= VA_SPEAR3XX_ICM3_SMI_CTRL_BASE,
+		.pfn		= __phys_to_pfn(SPEAR3XX_ICM3_SMI_CTRL_BASE),
+		.length		= SZ_16M,
 		.type		= MT_DEVICE
 	},
 };
@@ -76,436 +83,8 @@
 void __init spear3xx_map_io(void)
 {
 	iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc));
-
-	/* This will initialize clock framework */
-	spear3xx_clk_init();
 }
 
-/* pad multiplexing support */
-/* devices */
-static struct pmx_dev_mode pmx_firda_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_FIRDA_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_firda = {
-	.name = "firda",
-	.modes = pmx_firda_modes,
-	.mode_count = ARRAY_SIZE(pmx_firda_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_i2c_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_I2C_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_i2c = {
-	.name = "i2c",
-	.modes = pmx_i2c_modes,
-	.mode_count = ARRAY_SIZE(pmx_i2c_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_ssp_cs_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_SSP_CS_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_ssp_cs = {
-	.name = "ssp_chip_selects",
-	.modes = pmx_ssp_cs_modes,
-	.mode_count = ARRAY_SIZE(pmx_ssp_cs_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_ssp_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_SSP_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_ssp = {
-	.name = "ssp",
-	.modes = pmx_ssp_modes,
-	.mode_count = ARRAY_SIZE(pmx_ssp_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_mii_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_MII_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_mii = {
-	.name = "mii",
-	.modes = pmx_mii_modes,
-	.mode_count = ARRAY_SIZE(pmx_mii_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_GPIO_PIN0_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin0 = {
-	.name = "gpio_pin0",
-	.modes = pmx_gpio_pin0_modes,
-	.mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_GPIO_PIN1_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin1 = {
-	.name = "gpio_pin1",
-	.modes = pmx_gpio_pin1_modes,
-	.mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_GPIO_PIN2_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin2 = {
-	.name = "gpio_pin2",
-	.modes = pmx_gpio_pin2_modes,
-	.mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_GPIO_PIN3_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin3 = {
-	.name = "gpio_pin3",
-	.modes = pmx_gpio_pin3_modes,
-	.mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_GPIO_PIN4_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin4 = {
-	.name = "gpio_pin4",
-	.modes = pmx_gpio_pin4_modes,
-	.mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_GPIO_PIN5_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin5 = {
-	.name = "gpio_pin5",
-	.modes = pmx_gpio_pin5_modes,
-	.mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_uart0_modem_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_UART0_MODEM_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_uart0_modem = {
-	.name = "uart0_modem",
-	.modes = pmx_uart0_modem_modes,
-	.mode_count = ARRAY_SIZE(pmx_uart0_modem_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_uart0_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_UART0_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_uart0 = {
-	.name = "uart0",
-	.modes = pmx_uart0_modes,
-	.mode_count = ARRAY_SIZE(pmx_uart0_modes),
-	.enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_timer_3_4_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_TIMER_3_4_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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,
-};
-
-static struct pmx_dev_mode pmx_timer_1_2_modes[] = {
-	{
-		.ids = 0xffffffff,
-		.mask = PMX_TIMER_1_2_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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 */
-static struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_FIRDA_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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,
-};
-
-static struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_UART0_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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,
-};
-
-static struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_I2C_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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,
-};
-
-static struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_SSP_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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,
-};
-
-static struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_MII_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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,
-};
-
-static struct pmx_dev_mode pmx_plgpio_28_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_GPIO_PIN0_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_28 = {
-	.name = "plgpio 28",
-	.modes = pmx_plgpio_28_modes,
-	.mode_count = ARRAY_SIZE(pmx_plgpio_28_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_29_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_GPIO_PIN1_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_29 = {
-	.name = "plgpio 29",
-	.modes = pmx_plgpio_29_modes,
-	.mode_count = ARRAY_SIZE(pmx_plgpio_29_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_30_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_GPIO_PIN2_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_30 = {
-	.name = "plgpio 30",
-	.modes = pmx_plgpio_30_modes,
-	.mode_count = ARRAY_SIZE(pmx_plgpio_30_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_31_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_GPIO_PIN3_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_31 = {
-	.name = "plgpio 31",
-	.modes = pmx_plgpio_31_modes,
-	.mode_count = ARRAY_SIZE(pmx_plgpio_31_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_32_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_GPIO_PIN4_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_32 = {
-	.name = "plgpio 32",
-	.modes = pmx_plgpio_32_modes,
-	.mode_count = ARRAY_SIZE(pmx_plgpio_32_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_33_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_GPIO_PIN5_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_33 = {
-	.name = "plgpio 33",
-	.modes = pmx_plgpio_33_modes,
-	.mode_count = ARRAY_SIZE(pmx_plgpio_33_modes),
-	.enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_SSP_CS_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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,
-};
-
-static struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_UART0_MODEM_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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,
-};
-
-static struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_TIMER_1_2_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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,
-};
-
-static struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
-	{
-		.ids = 0x00,
-		.mask = PMX_TIMER_3_4_MASK,
-	},
-};
-
-struct pmx_dev spear3xx_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 /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
-
 static void __init spear3xx_timer_init(void)
 {
 	char pclk_name[] = "pll3_48m_clk";
@@ -536,3 +115,13 @@
 struct sys_timer spear3xx_timer = {
 	.init = spear3xx_timer_init,
 };
+
+static const struct of_device_id vic_of_match[] __initconst = {
+	{ .compatible = "arm,pl190-vic", .data = vic_of_init, },
+	{ /* Sentinel */ }
+};
+
+void __init spear3xx_dt_init_irq(void)
+{
+	of_irq_init(vic_of_match);
+}
diff --git a/arch/arm/mach-spear6xx/Makefile.boot b/arch/arm/mach-spear6xx/Makefile.boot
index 4674a4c..af493da 100644
--- a/arch/arm/mach-spear6xx/Makefile.boot
+++ b/arch/arm/mach-spear6xx/Makefile.boot
@@ -1,3 +1,5 @@
 zreladdr-y	+= 0x00008000
 params_phys-y	:= 0x00000100
 initrd_phys-y	:= 0x00800000
+
+dtb-$(CONFIG_BOARD_SPEAR600_DT)	+= spear600-evb.dtb
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
index a86499a..adadef2 100644
--- a/arch/arm/mach-spear6xx/clock.c
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -623,53 +623,53 @@
 
 /* array of all spear 6xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
-	{ .con_id = "apb_pclk",		.clk = &dummy_apb_pclk},
+	CLKDEV_INIT(NULL, "apb_pclk", &dummy_apb_pclk),
 	/* root clks */
-	{ .con_id = "osc_32k_clk",	.clk = &osc_32k_clk},
-	{ .con_id = "osc_30m_clk",	.clk = &osc_30m_clk},
+	CLKDEV_INIT(NULL, "osc_32k_clk", &osc_32k_clk),
+	CLKDEV_INIT(NULL, "osc_30m_clk", &osc_30m_clk),
 	/* clock derived from 32 KHz os		 clk */
-	{ .dev_id = "rtc-spear",	.clk = &rtc_clk},
+	CLKDEV_INIT("rtc-spear", NULL, &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},
+	CLKDEV_INIT(NULL, "pll1_clk", &pll1_clk),
+	CLKDEV_INIT(NULL, "pll3_48m_clk", &pll3_48m_clk),
+	CLKDEV_INIT("wdt", NULL, &wdt_clk),
 	/* clock derived from pll1 clk */
-	{ .con_id = "cpu_clk",		.clk = &cpu_clk},
-	{ .con_id = "ahb_clk",		.clk = &ahb_clk},
-	{ .con_id = "uart_synth_clk",	.clk = &uart_synth_clk},
-	{ .con_id = "firda_synth_clk",	.clk = &firda_synth_clk},
-	{ .con_id = "clcd_synth_clk",	.clk = &clcd_synth_clk},
-	{ .con_id = "gpt0_synth_clk",	.clk = &gpt0_synth_clk},
-	{ .con_id = "gpt2_synth_clk",	.clk = &gpt2_synth_clk},
-	{ .con_id = "gpt3_synth_clk",	.clk = &gpt3_synth_clk},
-	{ .dev_id = "d0000000.serial",	.clk = &uart0_clk},
-	{ .dev_id = "d0080000.serial",	.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},
+	CLKDEV_INIT(NULL, "cpu_clk", &cpu_clk),
+	CLKDEV_INIT(NULL, "ahb_clk", &ahb_clk),
+	CLKDEV_INIT(NULL, "uart_synth_clk", &uart_synth_clk),
+	CLKDEV_INIT(NULL, "firda_synth_clk", &firda_synth_clk),
+	CLKDEV_INIT(NULL, "clcd_synth_clk", &clcd_synth_clk),
+	CLKDEV_INIT(NULL, "gpt0_synth_clk", &gpt0_synth_clk),
+	CLKDEV_INIT(NULL, "gpt2_synth_clk", &gpt2_synth_clk),
+	CLKDEV_INIT(NULL, "gpt3_synth_clk", &gpt3_synth_clk),
+	CLKDEV_INIT("d0000000.serial", NULL, &uart0_clk),
+	CLKDEV_INIT("d0080000.serial", NULL, &uart1_clk),
+	CLKDEV_INIT("firda", NULL, &firda_clk),
+	CLKDEV_INIT("clcd", NULL, &clcd_clk),
+	CLKDEV_INIT("gpt0", NULL, &gpt0_clk),
+	CLKDEV_INIT("gpt1", NULL, &gpt1_clk),
+	CLKDEV_INIT("gpt2", NULL, &gpt2_clk),
+	CLKDEV_INIT("gpt3", NULL, &gpt3_clk),
 	/* clock derived from pll3 clk */
-	{ .dev_id = "designware_udc",	.clk = &usbd_clk},
-	{ .con_id = "usbh.0_clk",	.clk = &usbh0_clk},
-	{ .con_id = "usbh.1_clk",	.clk = &usbh1_clk},
+	CLKDEV_INIT("designware_udc", NULL, &usbd_clk),
+	CLKDEV_INIT(NULL, "usbh.0_clk", &usbh0_clk),
+	CLKDEV_INIT(NULL, "usbh.1_clk", &usbh1_clk),
 	/* clock derived from ahb clk */
-	{ .con_id = "apb_clk",		.clk = &apb_clk},
-	{ .dev_id = "d0200000.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-nand",	.clk = &fsmc_clk},
+	CLKDEV_INIT(NULL, "apb_clk", &apb_clk),
+	CLKDEV_INIT("d0200000.i2c", NULL, &i2c_clk),
+	CLKDEV_INIT("fc400000.dma", NULL, &dma_clk),
+	CLKDEV_INIT("jpeg", NULL, &jpeg_clk),
+	CLKDEV_INIT("gmac", NULL, &gmac_clk),
+	CLKDEV_INIT("fc000000.flash", NULL, &smi_clk),
+	CLKDEV_INIT("d1800000.flash", NULL, &fsmc_clk),
 	/* clock derived from apb clk */
-	{ .dev_id = "adc",		.clk = &adc_clk},
-	{ .dev_id = "ssp-pl022.0",	.clk = &ssp0_clk},
-	{ .dev_id = "ssp-pl022.1",	.clk = &ssp1_clk},
-	{ .dev_id = "ssp-pl022.2",	.clk = &ssp2_clk},
-	{ .dev_id = "f0100000.gpio",	.clk = &gpio0_clk},
-	{ .dev_id = "fc980000.gpio",	.clk = &gpio1_clk},
-	{ .dev_id = "d8100000.gpio",	.clk = &gpio2_clk},
+	CLKDEV_INIT("adc", NULL, &adc_clk),
+	CLKDEV_INIT("ssp-pl022.0", NULL, &ssp0_clk),
+	CLKDEV_INIT("ssp-pl022.1", NULL, &ssp1_clk),
+	CLKDEV_INIT("ssp-pl022.2", NULL, &ssp2_clk),
+	CLKDEV_INIT("f0100000.gpio", NULL, &gpio0_clk),
+	CLKDEV_INIT("fc980000.gpio", NULL, &gpio1_clk),
+	CLKDEV_INIT("d8100000.gpio", NULL, &gpio2_clk),
 };
 
 void __init spear6xx_clk_init(void)
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 2ed8b14..5b9e30f 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -13,15 +13,377 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/amba/pl08x.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <asm/hardware/pl080.h>
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
+#include <plat/pl080.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
+/* dmac device registration */
+static struct pl08x_channel_data spear600_dma_info[] = {
+	{
+		.bus_id = "ssp1_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp1_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart0_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart1_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "uart1_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp2_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp2_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ssp0_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ssp0_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "i2c_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "irda",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "adc",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "to_jpeg",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "from_jpeg",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 0,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras0_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras0_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras1_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras1_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras2_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras2_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras3_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras3_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras4_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras4_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras5_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras6_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ras7_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 1,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB1,
+	}, {
+		.bus_id = "ext0_rx",
+		.min_signal = 0,
+		.max_signal = 0,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext0_tx",
+		.min_signal = 1,
+		.max_signal = 1,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext1_rx",
+		.min_signal = 2,
+		.max_signal = 2,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext1_tx",
+		.min_signal = 3,
+		.max_signal = 3,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext2_rx",
+		.min_signal = 4,
+		.max_signal = 4,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext2_tx",
+		.min_signal = 5,
+		.max_signal = 5,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext3_rx",
+		.min_signal = 6,
+		.max_signal = 6,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext3_tx",
+		.min_signal = 7,
+		.max_signal = 7,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext4_rx",
+		.min_signal = 8,
+		.max_signal = 8,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext4_tx",
+		.min_signal = 9,
+		.max_signal = 9,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext5_rx",
+		.min_signal = 10,
+		.max_signal = 10,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext5_tx",
+		.min_signal = 11,
+		.max_signal = 11,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext6_rx",
+		.min_signal = 12,
+		.max_signal = 12,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext6_tx",
+		.min_signal = 13,
+		.max_signal = 13,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext7_rx",
+		.min_signal = 14,
+		.max_signal = 14,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	}, {
+		.bus_id = "ext7_tx",
+		.min_signal = 15,
+		.max_signal = 15,
+		.muxval = 2,
+		.cctl = 0,
+		.periph_buses = PL08X_AHB2,
+	},
+};
+
+struct pl08x_platform_data pl080_plat_data = {
+	.memcpy_channel = {
+		.bus_id = "memcpy",
+		.cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+			PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
+			PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
+			PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
+			PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
+			PL080_CONTROL_PROT_SYS),
+	},
+	.lli_buses = PL08X_AHB1,
+	.mem_buses = PL08X_AHB1,
+	.get_signal = pl080_get_signal,
+	.put_signal = pl080_put_signal,
+	.slave_channels = spear600_dma_info,
+	.num_slave_channels = ARRAY_SIZE(spear600_dma_info),
+};
+
 /* Following will create static virtual/physical mappings */
 static struct map_desc spear6xx_io_desc[] __initdata = {
 	{
@@ -92,9 +454,17 @@
 	.init = spear6xx_timer_init,
 };
 
+/* Add auxdata to pass platform data */
+struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("arm,pl080", SPEAR6XX_ICM3_DMA_BASE, NULL,
+			&pl080_plat_data),
+	{}
+};
+
 static void __init spear600_dt_init(void)
 {
-	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+	of_platform_populate(NULL, of_default_bus_match_table,
+			spear6xx_auxdata_lookup, NULL);
 }
 
 static const char *spear600_dt_board_compat[] = {
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index 1bb3dbc..387655b 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -9,9 +9,11 @@
 	default ARCH_SPEAR3XX
 
 config ARCH_SPEAR3XX
-	bool "SPEAr3XX"
+	bool "ST SPEAr3xx with Device Tree"
 	select ARM_VIC
 	select CPU_ARM926T
+	select USE_OF
+	select PINCTRL
 	help
 	  Supports for ARM's SPEAR3XX family
 
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index e0f2e5b..7744802c 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -3,6 +3,6 @@
 #
 
 # Common support
-obj-y	:= clock.o restart.o time.o
+obj-y	:= clock.o restart.o time.o pl080.o
 
-obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o padmux.o
+obj-$(CONFIG_ARCH_SPEAR3XX)	+= shirq.o
diff --git a/arch/arm/plat-spear/include/plat/padmux.h b/arch/arm/plat-spear/include/plat/padmux.h
deleted file mode 100644
index 877f3adc..0000000
--- a/arch/arm/plat-spear/include/plat/padmux.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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/pl080.h b/arch/arm/plat-spear/include/plat/pl080.h
new file mode 100644
index 0000000..e14a3e4
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/pl080.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/plat-spear/include/plat/pl080.h
+ *
+ * DMAC pl080 definitions for SPEAr platform
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.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_PL080_H
+#define __PLAT_PL080_H
+
+struct pl08x_dma_chan;
+int pl080_get_signal(struct pl08x_dma_chan *ch);
+void pl080_put_signal(struct pl08x_dma_chan *ch);
+
+#endif /* __PLAT_PL080_H */
diff --git a/arch/arm/plat-spear/padmux.c b/arch/arm/plat-spear/padmux.c
deleted file mode 100644
index 555eec6..0000000
--- a/arch/arm/plat-spear/padmux.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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 enabled 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/pl080.c b/arch/arm/plat-spear/pl080.c
new file mode 100644
index 0000000..d53d75e
--- /dev/null
+++ b/arch/arm/plat-spear/pl080.c
@@ -0,0 +1,79 @@
+/*
+ * arch/arm/plat-spear/pl080.c
+ *
+ * DMAC pl080 definitions for SPEAr platform
+ *
+ * Copyright (C) 2012 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/pl08x.h>
+#include <linux/amba/bus.h>
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/spinlock_types.h>
+#include <mach/misc_regs.h>
+
+static spinlock_t lock = __SPIN_LOCK_UNLOCKED(x);
+
+struct {
+	unsigned char busy;
+	unsigned char val;
+} signals[16] = {{0, 0}, };
+
+int pl080_get_signal(struct pl08x_dma_chan *ch)
+{
+	const struct pl08x_channel_data *cd = ch->cd;
+	unsigned int signal = cd->min_signal, val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&lock, flags);
+
+	/* Return if signal is already acquired by somebody else */
+	if (signals[signal].busy &&
+			(signals[signal].val != cd->muxval)) {
+		spin_unlock_irqrestore(&lock, flags);
+		return -EBUSY;
+	}
+
+	/* If acquiring for the first time, configure it */
+	if (!signals[signal].busy) {
+		val = readl(DMA_CHN_CFG);
+
+		/*
+		 * Each request line has two bits in DMA_CHN_CFG register. To
+		 * goto the bits of current request line, do left shift of
+		 * value by 2 * signal number.
+		 */
+		val &= ~(0x3 << (signal * 2));
+		val |= cd->muxval << (signal * 2);
+		writel(val, DMA_CHN_CFG);
+	}
+
+	signals[signal].busy++;
+	signals[signal].val = cd->muxval;
+	spin_unlock_irqrestore(&lock, flags);
+
+	return signal;
+}
+
+void pl080_put_signal(struct pl08x_dma_chan *ch)
+{
+	const struct pl08x_channel_data *cd = ch->cd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&lock, flags);
+
+	/* if signal is not used */
+	if (!signals[cd->min_signal].busy)
+		BUG();
+
+	signals[cd->min_signal].busy--;
+
+	spin_unlock_irqrestore(&lock, flags);
+}
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 6db161f..c535cf8 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -35,7 +35,12 @@
 static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
 {
 	struct clk_lookup *p, *cl = NULL;
-	int match, best = 0;
+	int match, best_found = 0, best_possible = 0;
+
+	if (dev_id)
+		best_possible += 2;
+	if (con_id)
+		best_possible += 1;
 
 	list_for_each_entry(p, &clocks, node) {
 		match = 0;
@@ -50,10 +55,10 @@
 			match += 1;
 		}
 
-		if (match > best) {
+		if (match > best_found) {
 			cl = p;
-			if (match != 3)
-				best = match;
+			if (match != best_possible)
+				best_found = match;
 			else
 				break;
 		}
@@ -89,6 +94,51 @@
 }
 EXPORT_SYMBOL(clk_put);
 
+static void devm_clk_release(struct device *dev, void *res)
+{
+	clk_put(*(struct clk **)res);
+}
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+	struct clk **ptr, *clk;
+
+	ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	clk = clk_get(dev, id);
+	if (!IS_ERR(clk)) {
+		*ptr = clk;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return clk;
+}
+EXPORT_SYMBOL(devm_clk_get);
+
+static int devm_clk_match(struct device *dev, void *res, void *data)
+{
+	struct clk **c = res;
+	if (!c || !*c) {
+		WARN_ON(!c || !*c);
+		return 0;
+	}
+	return *c == data;
+}
+
+void devm_clk_put(struct device *dev, struct clk *clk)
+{
+	int ret;
+
+	ret = devres_destroy(dev, devm_clk_release, devm_clk_match, clk);
+
+	WARN_ON(ret);
+}
+EXPORT_SYMBOL(devm_clk_put);
+
 void clkdev_add(struct clk_lookup *cl)
 {
 	mutex_lock(&clocks_mutex);
@@ -116,8 +166,9 @@
 	char	con_id[MAX_CON_ID];
 };
 
-struct clk_lookup * __init_refok
-clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+static struct clk_lookup * __init_refok
+vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt,
+	va_list ap)
 {
 	struct clk_lookup_alloc *cla;
 
@@ -132,16 +183,25 @@
 	}
 
 	if (dev_fmt) {
-		va_list ap;
-
-		va_start(ap, dev_fmt);
 		vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
 		cla->cl.dev_id = cla->dev_id;
-		va_end(ap);
 	}
 
 	return &cla->cl;
 }
+
+struct clk_lookup * __init_refok
+clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	va_start(ap, dev_fmt);
+	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
+	va_end(ap);
+
+	return cl;
+}
 EXPORT_SYMBOL(clkdev_alloc);
 
 int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
@@ -173,3 +233,65 @@
 	kfree(cl);
 }
 EXPORT_SYMBOL(clkdev_drop);
+
+/**
+ * clk_register_clkdev - register one clock lookup for a struct clk
+ * @clk: struct clk to associate with all clk_lookups
+ * @con_id: connection ID string on device
+ * @dev_id: format string describing device name
+ *
+ * con_id or dev_id may be NULL as a wildcard, just as in the rest of
+ * clkdev.
+ *
+ * To make things easier for mass registration, we detect error clks
+ * from a previous clk_register() call, and return the error code for
+ * those.  This is to permit this function to be called immediately
+ * after clk_register().
+ */
+int clk_register_clkdev(struct clk *clk, const char *con_id,
+	const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	va_start(ap, dev_fmt);
+	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
+	va_end(ap);
+
+	if (!cl)
+		return -ENOMEM;
+
+	clkdev_add(cl);
+
+	return 0;
+}
+
+/**
+ * clk_register_clkdevs - register a set of clk_lookup for a struct clk
+ * @clk: struct clk to associate with all clk_lookups
+ * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
+ * @num: number of clk_lookup structures to register
+ *
+ * To make things easier for mass registration, we detect error clks
+ * from a previous clk_register() call, and return the error code for
+ * those.  This is to permit this function to be called immediately
+ * after clk_register().
+ */
+int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
+{
+	unsigned i;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	for (i = 0; i < num; i++, cl++) {
+		cl->clk = clk;
+		clkdev_add(cl);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_register_clkdevs);
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 73f2fd6..a54a931 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -111,6 +111,8 @@
 	  COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
 	  ports of 8 GPIO pins each.
 
+source "drivers/pinctrl/spear/Kconfig"
+
 endmenu
 
 endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 5f5a0a6..c9b0be5 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -24,3 +24,5 @@
 obj-$(CONFIG_PINCTRL_TEGRA30)	+= pinctrl-tegra30.o
 obj-$(CONFIG_PINCTRL_U300)	+= pinctrl-u300.o
 obj-$(CONFIG_PINCTRL_COH901)	+= pinctrl-coh901.o
+
+obj-$(CONFIG_PLAT_SPEAR)	+= spear/
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
new file mode 100644
index 0000000..6a2596b
--- /dev/null
+++ b/drivers/pinctrl/spear/Kconfig
@@ -0,0 +1,34 @@
+#
+# ST Microelectronics SPEAr PINCTRL drivers
+#
+
+if PLAT_SPEAR
+
+config PINCTRL_SPEAR
+	bool
+	depends on OF
+	select PINMUX
+	help
+	  This enables pin control drivers for SPEAr Platform
+
+config PINCTRL_SPEAR3XX
+	bool
+	depends on ARCH_SPEAR3XX
+	select PINCTRL_SPEAR
+
+config PINCTRL_SPEAR300
+	bool "ST Microelectronics SPEAr300 SoC pin controller driver"
+	depends on MACH_SPEAR300
+	select PINCTRL_SPEAR3XX
+
+config PINCTRL_SPEAR310
+	bool "ST Microelectronics SPEAr310 SoC pin controller driver"
+	depends on MACH_SPEAR310
+	select PINCTRL_SPEAR3XX
+
+config PINCTRL_SPEAR320
+	bool "ST Microelectronics SPEAr320 SoC pin controller driver"
+	depends on MACH_SPEAR320
+	select PINCTRL_SPEAR3XX
+
+endif
diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile
new file mode 100644
index 0000000..15dcb85
--- /dev/null
+++ b/drivers/pinctrl/spear/Makefile
@@ -0,0 +1,7 @@
+# SPEAr pinmux support
+
+obj-$(CONFIG_PINCTRL_SPEAR)	+= pinctrl-spear.o
+obj-$(CONFIG_PINCTRL_SPEAR3XX)	+= pinctrl-spear3xx.o
+obj-$(CONFIG_PINCTRL_SPEAR300)	+= pinctrl-spear300.o
+obj-$(CONFIG_PINCTRL_SPEAR310)	+= pinctrl-spear310.o
+obj-$(CONFIG_PINCTRL_SPEAR320)	+= pinctrl-spear320.o
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
new file mode 100644
index 0000000..5ae50aa
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -0,0 +1,354 @@
+/*
+ * Driver for the ST Microelectronics SPEAr pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * Inspired from:
+ * - U300 Pinctl drivers
+ * - Tegra Pinctl drivers
+ *
+ * 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/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "pinctrl-spear.h"
+
+#define DRIVER_NAME "spear-pinmux"
+
+static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg)
+{
+	return readl_relaxed(pmx->vbase + reg);
+}
+
+static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
+{
+	writel_relaxed(val, pmx->vbase + reg);
+}
+
+static int set_mode(struct spear_pmx *pmx, int mode)
+{
+	struct spear_pmx_mode *pmx_mode = NULL;
+	int i;
+	u32 val;
+
+	if (!pmx->machdata->pmx_modes || !pmx->machdata->npmx_modes)
+		return -EINVAL;
+
+	for (i = 0; i < pmx->machdata->npmx_modes; i++) {
+		if (pmx->machdata->pmx_modes[i]->mode == (1 << mode)) {
+			pmx_mode = pmx->machdata->pmx_modes[i];
+			break;
+		}
+	}
+
+	if (!pmx_mode)
+		return -EINVAL;
+
+	val = pmx_readl(pmx, pmx_mode->reg);
+	val &= ~pmx_mode->mask;
+	val |= pmx_mode->val;
+	pmx_writel(pmx, val, pmx_mode->reg);
+
+	pmx->machdata->mode = pmx_mode->mode;
+	dev_info(pmx->dev, "Configured Mode: %s with id: %x\n\n",
+			pmx_mode->name ? pmx_mode->name : "no_name",
+			pmx_mode->reg);
+
+	return 0;
+}
+
+void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg)
+{
+	struct spear_pingroup *pgroup;
+	struct spear_modemux *modemux;
+	int i, j, group;
+
+	for (group = 0; group < machdata->ngroups; group++) {
+		pgroup = machdata->groups[group];
+
+		for (i = 0; i < pgroup->nmodemuxs; i++) {
+			modemux = &pgroup->modemuxs[i];
+
+			for (j = 0; j < modemux->nmuxregs; j++)
+				if (modemux->muxregs[j].reg == 0xFFFF)
+					modemux->muxregs[j].reg = reg;
+		}
+	}
+}
+
+static int spear_pinctrl_get_groups_cnt(struct pinctrl_dev *pctldev)
+{
+	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pmx->machdata->ngroups;
+}
+
+static const char *spear_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+		unsigned group)
+{
+	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pmx->machdata->groups[group]->name;
+}
+
+static int spear_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+		unsigned group, const unsigned **pins, unsigned *num_pins)
+{
+	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins = pmx->machdata->groups[group]->pins;
+	*num_pins = pmx->machdata->groups[group]->npins;
+
+	return 0;
+}
+
+static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+		struct seq_file *s, unsigned offset)
+{
+	seq_printf(s, " " DRIVER_NAME);
+}
+
+int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+				 struct device_node *np_config,
+				 struct pinctrl_map **map, unsigned *num_maps)
+{
+	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	struct device_node *np;
+	struct property *prop;
+	const char *function, *group;
+	int ret, index = 0, count = 0;
+
+	/* calculate number of maps required */
+	for_each_child_of_node(np_config, np) {
+		ret = of_property_read_string(np, "st,function", &function);
+		if (ret < 0)
+			return ret;
+
+		ret = of_property_count_strings(np, "st,pins");
+		if (ret < 0)
+			return ret;
+
+		count += ret;
+	}
+
+	if (!count) {
+		dev_err(pmx->dev, "No child nodes passed via DT\n");
+		return -ENODEV;
+	}
+
+	*map = kzalloc(sizeof(**map) * count, GFP_KERNEL);
+	if (!*map)
+		return -ENOMEM;
+
+	for_each_child_of_node(np_config, np) {
+		of_property_read_string(np, "st,function", &function);
+		of_property_for_each_string(np, "st,pins", prop, group) {
+			(*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
+			(*map)[index].data.mux.group = group;
+			(*map)[index].data.mux.function = function;
+			index++;
+		}
+	}
+
+	*num_maps = count;
+
+	return 0;
+}
+
+void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+		struct pinctrl_map *map, unsigned num_maps)
+{
+	kfree(map);
+}
+
+static struct pinctrl_ops spear_pinctrl_ops = {
+	.get_groups_count = spear_pinctrl_get_groups_cnt,
+	.get_group_name = spear_pinctrl_get_group_name,
+	.get_group_pins = spear_pinctrl_get_group_pins,
+	.pin_dbg_show = spear_pinctrl_pin_dbg_show,
+	.dt_node_to_map = spear_pinctrl_dt_node_to_map,
+	.dt_free_map = spear_pinctrl_dt_free_map,
+};
+
+static int spear_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pmx->machdata->nfunctions;
+}
+
+static const char *spear_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+		unsigned function)
+{
+	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pmx->machdata->functions[function]->name;
+}
+
+static int spear_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+		unsigned function, const char *const **groups,
+		unsigned * const ngroups)
+{
+	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = pmx->machdata->functions[function]->groups;
+	*ngroups = pmx->machdata->functions[function]->ngroups;
+
+	return 0;
+}
+
+static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
+		unsigned function, unsigned group, bool enable)
+{
+	struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct spear_pingroup *pgroup;
+	const struct spear_modemux *modemux;
+	struct spear_muxreg *muxreg;
+	u32 val, temp;
+	int i, j;
+	bool found = false;
+
+	pgroup = pmx->machdata->groups[group];
+
+	for (i = 0; i < pgroup->nmodemuxs; i++) {
+		modemux = &pgroup->modemuxs[i];
+
+		/* SoC have any modes */
+		if (pmx->machdata->modes_supported) {
+			if (!(pmx->machdata->mode & modemux->modes))
+				continue;
+		}
+
+		found = true;
+		for (j = 0; j < modemux->nmuxregs; j++) {
+			muxreg = &modemux->muxregs[j];
+
+			val = pmx_readl(pmx, muxreg->reg);
+			val &= ~muxreg->mask;
+
+			if (enable)
+				temp = muxreg->val;
+			else
+				temp = ~muxreg->val;
+
+			val |= temp;
+			pmx_writel(pmx, val, muxreg->reg);
+		}
+	}
+
+	if (!found) {
+		dev_err(pmx->dev, "pinmux group: %s not supported\n",
+				pgroup->name);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
+		unsigned group)
+{
+	return spear_pinctrl_endisable(pctldev, function, group, true);
+}
+
+static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
+		unsigned function, unsigned group)
+{
+	spear_pinctrl_endisable(pctldev, function, group, false);
+}
+
+static struct pinmux_ops spear_pinmux_ops = {
+	.get_functions_count = spear_pinctrl_get_funcs_count,
+	.get_function_name = spear_pinctrl_get_func_name,
+	.get_function_groups = spear_pinctrl_get_func_groups,
+	.enable = spear_pinctrl_enable,
+	.disable = spear_pinctrl_disable,
+};
+
+static struct pinctrl_desc spear_pinctrl_desc = {
+	.name = DRIVER_NAME,
+	.pctlops = &spear_pinctrl_ops,
+	.pmxops = &spear_pinmux_ops,
+	.owner = THIS_MODULE,
+};
+
+int __devinit spear_pinctrl_probe(struct platform_device *pdev,
+		struct spear_pinctrl_machdata *machdata)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res;
+	struct spear_pmx *pmx;
+
+	if (!machdata)
+		return -ENODEV;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -EINVAL;
+
+	pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
+	if (!pmx) {
+		dev_err(&pdev->dev, "Can't alloc spear_pmx\n");
+		return -ENOMEM;
+	}
+
+	pmx->vbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!pmx->vbase) {
+		dev_err(&pdev->dev, "Couldn't ioremap at index 0\n");
+		return -ENODEV;
+	}
+
+	pmx->dev = &pdev->dev;
+	pmx->machdata = machdata;
+
+	/* configure mode, if supported by SoC */
+	if (machdata->modes_supported) {
+		int mode = 0;
+
+		if (of_property_read_u32(np, "st,pinmux-mode", &mode)) {
+			dev_err(&pdev->dev, "OF: pinmux mode not passed\n");
+			return -EINVAL;
+		}
+
+		if (set_mode(pmx, mode)) {
+			dev_err(&pdev->dev, "OF: Couldn't configure mode: %x\n",
+					mode);
+			return -EINVAL;
+		}
+	}
+
+	platform_set_drvdata(pdev, pmx);
+
+	spear_pinctrl_desc.pins = machdata->pins;
+	spear_pinctrl_desc.npins = machdata->npins;
+
+	pmx->pctl = pinctrl_register(&spear_pinctrl_desc, &pdev->dev, pmx);
+	if (IS_ERR(pmx->pctl)) {
+		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+		return PTR_ERR(pmx->pctl);
+	}
+
+	return 0;
+}
+
+int __devexit spear_pinctrl_remove(struct platform_device *pdev)
+{
+	struct spear_pmx *pmx = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(pmx->pctl);
+
+	return 0;
+}
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h
new file mode 100644
index 0000000..47a6b5b
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear.h
@@ -0,0 +1,142 @@
+/*
+ * Driver header file for the ST Microelectronics SPEAr pinmux
+ *
+ * Copyright (C) 2012 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 __PINMUX_SPEAR_H__
+#define __PINMUX_SPEAR_H__
+
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/types.h>
+
+struct platform_device;
+struct device;
+
+/**
+ * struct spear_pmx_mode - SPEAr pmx mode
+ * @name: name of pmx mode
+ * @mode: mode id
+ * @reg: register for configuring this mode
+ * @mask: mask of this mode in reg
+ * @val: val to be configured at reg after doing (val & mask)
+ */
+struct spear_pmx_mode {
+	const char *const name;
+	u16 mode;
+	u16 reg;
+	u16 mask;
+	u32 val;
+};
+
+/**
+ * struct spear_muxreg - SPEAr mux reg configuration
+ * @reg: register offset
+ * @mask: mask bits
+ * @val: val to be written on mask bits
+ */
+struct spear_muxreg {
+	u16 reg;
+	u32 mask;
+	u32 val;
+};
+
+/**
+ * struct spear_modemux - SPEAr mode mux configuration
+ * @modes: mode ids supported by this group of muxregs
+ * @nmuxregs: number of muxreg configurations to be done for modes
+ * @muxregs: array of muxreg configurations to be done for modes
+ */
+struct spear_modemux {
+	u16 modes;
+	u8 nmuxregs;
+	struct spear_muxreg *muxregs;
+};
+
+/**
+ * struct spear_pingroup - SPEAr pin group configurations
+ * @name: name of pin group
+ * @pins: array containing pin numbers
+ * @npins: size of pins array
+ * @modemuxs: array of modemux configurations for this pin group
+ * @nmodemuxs: size of array modemuxs
+ *
+ * A representation of a group of pins in the SPEAr pin controller. Each group
+ * allows some parameter or parameters to be configured.
+ */
+struct spear_pingroup {
+	const char *name;
+	const unsigned *pins;
+	unsigned npins;
+	struct spear_modemux *modemuxs;
+	unsigned nmodemuxs;
+};
+
+/**
+ * struct spear_function - SPEAr pinctrl mux function
+ * @name: The name of the function, exported to pinctrl core.
+ * @groups: An array of pin groups that may select this function.
+ * @ngroups: The number of entries in @groups.
+ */
+struct spear_function {
+	const char *name;
+	const char *const *groups;
+	unsigned ngroups;
+};
+
+/**
+ * struct spear_pinctrl_machdata - SPEAr pin controller machine driver
+ *	configuration
+ * @pins: An array describing all pins the pin controller affects.
+ *	All pins which are also GPIOs must be listed first within the *array,
+ *	and be numbered identically to the GPIO controller's *numbering.
+ * @npins: The numbmer of entries in @pins.
+ * @functions: An array describing all mux functions the SoC supports.
+ * @nfunctions: The numbmer of entries in @functions.
+ * @groups: An array describing all pin groups the pin SoC supports.
+ * @ngroups: The numbmer of entries in @groups.
+ *
+ * @modes_supported: Does SoC support modes
+ * @mode: mode configured from probe
+ * @pmx_modes: array of modes supported by SoC
+ * @npmx_modes: number of entries in pmx_modes.
+ */
+struct spear_pinctrl_machdata {
+	const struct pinctrl_pin_desc *pins;
+	unsigned npins;
+	struct spear_function **functions;
+	unsigned nfunctions;
+	struct spear_pingroup **groups;
+	unsigned ngroups;
+
+	bool modes_supported;
+	u16 mode;
+	struct spear_pmx_mode **pmx_modes;
+	unsigned npmx_modes;
+};
+
+/**
+ * struct spear_pmx - SPEAr pinctrl mux
+ * @dev: pointer to struct dev of platform_device registered
+ * @pctl: pointer to struct pinctrl_dev
+ * @machdata: pointer to SoC or machine specific structure
+ * @vbase: virtual base address of pinmux controller
+ */
+struct spear_pmx {
+	struct device *dev;
+	struct pinctrl_dev *pctl;
+	struct spear_pinctrl_machdata *machdata;
+	void __iomem *vbase;
+};
+
+/* exported routines */
+void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg);
+int __devinit spear_pinctrl_probe(struct platform_device *pdev,
+		struct spear_pinctrl_machdata *machdata);
+int __devexit spear_pinctrl_remove(struct platform_device *pdev);
+#endif /* __PINMUX_SPEAR_H__ */
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c
new file mode 100644
index 0000000..9c82a35
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear300.c
@@ -0,0 +1,708 @@
+/*
+ * Driver for the ST Microelectronics SPEAr300 pinmux
+ *
+ * Copyright (C) 2012 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/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear300-pinmux"
+
+/* addresses */
+#define PMX_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)
+
+static struct spear_pmx_mode pmx_mode_nand = {
+	.name = "nand",
+	.mode = NAND_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x00,
+};
+
+static struct spear_pmx_mode pmx_mode_nor = {
+	.name = "nor",
+	.mode = NOR_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x01,
+};
+
+static struct spear_pmx_mode pmx_mode_photo_frame = {
+	.name = "photo frame mode",
+	.mode = PHOTO_FRAME_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x02,
+};
+
+static struct spear_pmx_mode pmx_mode_lend_ip_phone = {
+	.name = "lend ip phone mode",
+	.mode = LEND_IP_PHONE_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x03,
+};
+
+static struct spear_pmx_mode pmx_mode_hend_ip_phone = {
+	.name = "hend ip phone mode",
+	.mode = HEND_IP_PHONE_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x04,
+};
+
+static struct spear_pmx_mode pmx_mode_lend_wifi_phone = {
+	.name = "lend wifi phone mode",
+	.mode = LEND_WIFI_PHONE_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x05,
+};
+
+static struct spear_pmx_mode pmx_mode_hend_wifi_phone = {
+	.name = "hend wifi phone mode",
+	.mode = HEND_WIFI_PHONE_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x06,
+};
+
+static struct spear_pmx_mode pmx_mode_ata_pabx_wi2s = {
+	.name = "ata pabx wi2s mode",
+	.mode = ATA_PABX_WI2S_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x07,
+};
+
+static struct spear_pmx_mode pmx_mode_ata_pabx_i2s = {
+	.name = "ata pabx i2s mode",
+	.mode = ATA_PABX_I2S_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x08,
+};
+
+static struct spear_pmx_mode pmx_mode_caml_lcdw = {
+	.name = "caml lcdw mode",
+	.mode = CAML_LCDW_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x0C,
+};
+
+static struct spear_pmx_mode pmx_mode_camu_lcd = {
+	.name = "camu lcd mode",
+	.mode = CAMU_LCD_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x0D,
+};
+
+static struct spear_pmx_mode pmx_mode_camu_wlcd = {
+	.name = "camu wlcd mode",
+	.mode = CAMU_WLCD_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0xE,
+};
+
+static struct spear_pmx_mode pmx_mode_caml_lcd = {
+	.name = "caml lcd mode",
+	.mode = CAML_LCD_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x0000000F,
+	.val = 0x0F,
+};
+
+static struct spear_pmx_mode *spear300_pmx_modes[] = {
+	&pmx_mode_nand,
+	&pmx_mode_nor,
+	&pmx_mode_photo_frame,
+	&pmx_mode_lend_ip_phone,
+	&pmx_mode_hend_ip_phone,
+	&pmx_mode_lend_wifi_phone,
+	&pmx_mode_hend_wifi_phone,
+	&pmx_mode_ata_pabx_wi2s,
+	&pmx_mode_ata_pabx_i2s,
+	&pmx_mode_caml_lcdw,
+	&pmx_mode_camu_lcd,
+	&pmx_mode_camu_wlcd,
+	&pmx_mode_caml_lcd,
+};
+
+/* fsmc_2chips_pins */
+static const unsigned fsmc_2chips_pins[] = { 1, 97 };
+static struct spear_muxreg fsmc_2chips_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_FIRDA_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux fsmc_2chips_modemux[] = {
+	{
+		.modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+			ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+		.muxregs = fsmc_2chips_muxreg,
+		.nmuxregs = ARRAY_SIZE(fsmc_2chips_muxreg),
+	},
+};
+
+static struct spear_pingroup fsmc_2chips_pingroup = {
+	.name = "fsmc_2chips_grp",
+	.pins = fsmc_2chips_pins,
+	.npins = ARRAY_SIZE(fsmc_2chips_pins),
+	.modemuxs = fsmc_2chips_modemux,
+	.nmodemuxs = ARRAY_SIZE(fsmc_2chips_modemux),
+};
+
+/* fsmc_4chips_pins */
+static const unsigned fsmc_4chips_pins[] = { 1, 2, 3, 97 };
+static struct spear_muxreg fsmc_4chips_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux fsmc_4chips_modemux[] = {
+	{
+		.modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+			ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+		.muxregs = fsmc_4chips_muxreg,
+		.nmuxregs = ARRAY_SIZE(fsmc_4chips_muxreg),
+	},
+};
+
+static struct spear_pingroup fsmc_4chips_pingroup = {
+	.name = "fsmc_4chips_grp",
+	.pins = fsmc_4chips_pins,
+	.npins = ARRAY_SIZE(fsmc_4chips_pins),
+	.modemuxs = fsmc_4chips_modemux,
+	.nmodemuxs = ARRAY_SIZE(fsmc_4chips_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_2chips_grp", "fsmc_4chips_grp"
+};
+static struct spear_function fsmc_function = {
+	.name = "fsmc",
+	.groups = fsmc_grps,
+	.ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* clcd_lcdmode_pins */
+static const unsigned clcd_lcdmode_pins[] = { 49, 50 };
+static struct spear_muxreg clcd_lcdmode_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux clcd_lcdmode_modemux[] = {
+	{
+		.modes = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+			CAMU_LCD_MODE | CAML_LCD_MODE,
+		.muxregs = clcd_lcdmode_muxreg,
+		.nmuxregs = ARRAY_SIZE(clcd_lcdmode_muxreg),
+	},
+};
+
+static struct spear_pingroup clcd_lcdmode_pingroup = {
+	.name = "clcd_lcdmode_grp",
+	.pins = clcd_lcdmode_pins,
+	.npins = ARRAY_SIZE(clcd_lcdmode_pins),
+	.modemuxs = clcd_lcdmode_modemux,
+	.nmodemuxs = ARRAY_SIZE(clcd_lcdmode_modemux),
+};
+
+/* clcd_pfmode_pins */
+static const unsigned clcd_pfmode_pins[] = { 47, 48, 49, 50 };
+static struct spear_muxreg clcd_pfmode_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_2_3_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux clcd_pfmode_modemux[] = {
+	{
+		.modes = PHOTO_FRAME_MODE,
+		.muxregs = clcd_pfmode_muxreg,
+		.nmuxregs = ARRAY_SIZE(clcd_pfmode_muxreg),
+	},
+};
+
+static struct spear_pingroup clcd_pfmode_pingroup = {
+	.name = "clcd_pfmode_grp",
+	.pins = clcd_pfmode_pins,
+	.npins = ARRAY_SIZE(clcd_pfmode_pins),
+	.modemuxs = clcd_pfmode_modemux,
+	.nmodemuxs = ARRAY_SIZE(clcd_pfmode_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_lcdmode_grp", "clcd_pfmode_grp"
+};
+static struct spear_function clcd_function = {
+	.name = "clcd",
+	.groups = clcd_grps,
+	.ngroups = ARRAY_SIZE(clcd_grps),
+};
+
+/* tdm_pins */
+static const unsigned tdm_pins[] = { 34, 35, 36, 37, 38 };
+static struct spear_muxreg tdm_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux tdm_modemux[] = {
+	{
+		.modes = 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,
+		.muxregs = tdm_muxreg,
+		.nmuxregs = ARRAY_SIZE(tdm_muxreg),
+	},
+};
+
+static struct spear_pingroup tdm_pingroup = {
+	.name = "tdm_grp",
+	.pins = tdm_pins,
+	.npins = ARRAY_SIZE(tdm_pins),
+	.modemuxs = tdm_modemux,
+	.nmodemuxs = ARRAY_SIZE(tdm_modemux),
+};
+
+static const char *const tdm_grps[] = { "tdm_grp" };
+static struct spear_function tdm_function = {
+	.name = "tdm",
+	.groups = tdm_grps,
+	.ngroups = ARRAY_SIZE(tdm_grps),
+};
+
+/* i2c_clk_pins */
+static const unsigned i2c_clk_pins[] = { 45, 46, 47, 48 };
+static struct spear_muxreg i2c_clk_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux i2c_clk_modemux[] = {
+	{
+		.modes = 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,
+		.muxregs = i2c_clk_muxreg,
+		.nmuxregs = ARRAY_SIZE(i2c_clk_muxreg),
+	},
+};
+
+static struct spear_pingroup i2c_clk_pingroup = {
+	.name = "i2c_clk_grp_grp",
+	.pins = i2c_clk_pins,
+	.npins = ARRAY_SIZE(i2c_clk_pins),
+	.modemuxs = i2c_clk_modemux,
+	.nmodemuxs = ARRAY_SIZE(i2c_clk_modemux),
+};
+
+static const char *const i2c_grps[] = { "i2c_clk_grp" };
+static struct spear_function i2c_function = {
+	.name = "i2c1",
+	.groups = i2c_grps,
+	.ngroups = ARRAY_SIZE(i2c_grps),
+};
+
+/* caml_pins */
+static const unsigned caml_pins[] = { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
+static struct spear_muxreg caml_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux caml_modemux[] = {
+	{
+		.modes = CAML_LCDW_MODE | CAML_LCD_MODE,
+		.muxregs = caml_muxreg,
+		.nmuxregs = ARRAY_SIZE(caml_muxreg),
+	},
+};
+
+static struct spear_pingroup caml_pingroup = {
+	.name = "caml_grp",
+	.pins = caml_pins,
+	.npins = ARRAY_SIZE(caml_pins),
+	.modemuxs = caml_modemux,
+	.nmodemuxs = ARRAY_SIZE(caml_modemux),
+};
+
+/* camu_pins */
+static const unsigned camu_pins[] = { 16, 17, 18, 19, 20, 21, 45, 46, 47, 48 };
+static struct spear_muxreg camu_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK | PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux camu_modemux[] = {
+	{
+		.modes = CAMU_LCD_MODE | CAMU_WLCD_MODE,
+		.muxregs = camu_muxreg,
+		.nmuxregs = ARRAY_SIZE(camu_muxreg),
+	},
+};
+
+static struct spear_pingroup camu_pingroup = {
+	.name = "camu_grp",
+	.pins = camu_pins,
+	.npins = ARRAY_SIZE(camu_pins),
+	.modemuxs = camu_modemux,
+	.nmodemuxs = ARRAY_SIZE(camu_modemux),
+};
+
+static const char *const cam_grps[] = { "caml_grp", "camu_grp" };
+static struct spear_function cam_function = {
+	.name = "cam",
+	.groups = cam_grps,
+	.ngroups = ARRAY_SIZE(cam_grps),
+};
+
+/* dac_pins */
+static const unsigned dac_pins[] = { 43, 44 };
+static struct spear_muxreg dac_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux dac_modemux[] = {
+	{
+		.modes = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+			| CAMU_WLCD_MODE | CAML_LCD_MODE,
+		.muxregs = dac_muxreg,
+		.nmuxregs = ARRAY_SIZE(dac_muxreg),
+	},
+};
+
+static struct spear_pingroup dac_pingroup = {
+	.name = "dac_grp",
+	.pins = dac_pins,
+	.npins = ARRAY_SIZE(dac_pins),
+	.modemuxs = dac_modemux,
+	.nmodemuxs = ARRAY_SIZE(dac_modemux),
+};
+
+static const char *const dac_grps[] = { "dac_grp" };
+static struct spear_function dac_function = {
+	.name = "dac",
+	.groups = dac_grps,
+	.ngroups = ARRAY_SIZE(dac_grps),
+};
+
+/* i2s_pins */
+static const unsigned i2s_pins[] = { 39, 40, 41, 42 };
+static struct spear_muxreg i2s_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux i2s_modemux[] = {
+	{
+		.modes = 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,
+		.muxregs = i2s_muxreg,
+		.nmuxregs = ARRAY_SIZE(i2s_muxreg),
+	},
+};
+
+static struct spear_pingroup i2s_pingroup = {
+	.name = "i2s_grp",
+	.pins = i2s_pins,
+	.npins = ARRAY_SIZE(i2s_pins),
+	.modemuxs = i2s_modemux,
+	.nmodemuxs = ARRAY_SIZE(i2s_modemux),
+};
+
+static const char *const i2s_grps[] = { "i2s_grp" };
+static struct spear_function i2s_function = {
+	.name = "i2s",
+	.groups = i2s_grps,
+	.ngroups = ARRAY_SIZE(i2s_grps),
+};
+
+/* sdhci_4bit_pins */
+static const unsigned sdhci_4bit_pins[] = { 28, 29, 30, 31, 32, 33 };
+static struct spear_muxreg sdhci_4bit_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.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,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux sdhci_4bit_modemux[] = {
+	{
+		.modes = 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,
+		.muxregs = sdhci_4bit_muxreg,
+		.nmuxregs = ARRAY_SIZE(sdhci_4bit_muxreg),
+	},
+};
+
+static struct spear_pingroup sdhci_4bit_pingroup = {
+	.name = "sdhci_4bit_grp",
+	.pins = sdhci_4bit_pins,
+	.npins = ARRAY_SIZE(sdhci_4bit_pins),
+	.modemuxs = sdhci_4bit_modemux,
+	.nmodemuxs = ARRAY_SIZE(sdhci_4bit_modemux),
+};
+
+/* sdhci_8bit_pins */
+static const unsigned sdhci_8bit_pins[] = { 24, 25, 26, 27, 28, 29, 30, 31, 32,
+	33 };
+static struct spear_muxreg sdhci_8bit_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.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,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux sdhci_8bit_modemux[] = {
+	{
+		.modes = 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,
+		.muxregs = sdhci_8bit_muxreg,
+		.nmuxregs = ARRAY_SIZE(sdhci_8bit_muxreg),
+	},
+};
+
+static struct spear_pingroup sdhci_8bit_pingroup = {
+	.name = "sdhci_8bit_grp",
+	.pins = sdhci_8bit_pins,
+	.npins = ARRAY_SIZE(sdhci_8bit_pins),
+	.modemuxs = sdhci_8bit_modemux,
+	.nmodemuxs = ARRAY_SIZE(sdhci_8bit_modemux),
+};
+
+static const char *const sdhci_grps[] = { "sdhci_4bit_grp", "sdhci_8bit_grp" };
+static struct spear_function sdhci_function = {
+	.name = "sdhci",
+	.groups = sdhci_grps,
+	.ngroups = ARRAY_SIZE(sdhci_grps),
+};
+
+/* gpio1_0_to_3_pins */
+static const unsigned gpio1_0_to_3_pins[] = { 39, 40, 41, 42 };
+static struct spear_muxreg gpio1_0_to_3_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux gpio1_0_to_3_modemux[] = {
+	{
+		.modes = PHOTO_FRAME_MODE,
+		.muxregs = gpio1_0_to_3_muxreg,
+		.nmuxregs = ARRAY_SIZE(gpio1_0_to_3_muxreg),
+	},
+};
+
+static struct spear_pingroup gpio1_0_to_3_pingroup = {
+	.name = "gpio1_0_to_3_grp",
+	.pins = gpio1_0_to_3_pins,
+	.npins = ARRAY_SIZE(gpio1_0_to_3_pins),
+	.modemuxs = gpio1_0_to_3_modemux,
+	.nmodemuxs = ARRAY_SIZE(gpio1_0_to_3_modemux),
+};
+
+/* gpio1_4_to_7_pins */
+static const unsigned gpio1_4_to_7_pins[] = { 43, 44, 45, 46 };
+
+static struct spear_muxreg gpio1_4_to_7_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux gpio1_4_to_7_modemux[] = {
+	{
+		.modes = PHOTO_FRAME_MODE,
+		.muxregs = gpio1_4_to_7_muxreg,
+		.nmuxregs = ARRAY_SIZE(gpio1_4_to_7_muxreg),
+	},
+};
+
+static struct spear_pingroup gpio1_4_to_7_pingroup = {
+	.name = "gpio1_4_to_7_grp",
+	.pins = gpio1_4_to_7_pins,
+	.npins = ARRAY_SIZE(gpio1_4_to_7_pins),
+	.modemuxs = gpio1_4_to_7_modemux,
+	.nmodemuxs = ARRAY_SIZE(gpio1_4_to_7_modemux),
+};
+
+static const char *const gpio1_grps[] = { "gpio1_0_to_3_grp", "gpio1_4_to_7_grp"
+};
+static struct spear_function gpio1_function = {
+	.name = "gpio1",
+	.groups = gpio1_grps,
+	.ngroups = ARRAY_SIZE(gpio1_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear300_pingroups[] = {
+	SPEAR3XX_COMMON_PINGROUPS,
+	&fsmc_2chips_pingroup,
+	&fsmc_4chips_pingroup,
+	&clcd_lcdmode_pingroup,
+	&clcd_pfmode_pingroup,
+	&tdm_pingroup,
+	&i2c_clk_pingroup,
+	&caml_pingroup,
+	&camu_pingroup,
+	&dac_pingroup,
+	&i2s_pingroup,
+	&sdhci_4bit_pingroup,
+	&sdhci_8bit_pingroup,
+	&gpio1_0_to_3_pingroup,
+	&gpio1_4_to_7_pingroup,
+};
+
+/* functions */
+static struct spear_function *spear300_functions[] = {
+	SPEAR3XX_COMMON_FUNCTIONS,
+	&fsmc_function,
+	&clcd_function,
+	&tdm_function,
+	&i2c_function,
+	&cam_function,
+	&dac_function,
+	&i2s_function,
+	&sdhci_function,
+	&gpio1_function,
+};
+
+static struct of_device_id spear300_pinctrl_of_match[] __devinitdata = {
+	{
+		.compatible = "st,spear300-pinmux",
+	},
+	{},
+};
+
+static int __devinit spear300_pinctrl_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	spear3xx_machdata.groups = spear300_pingroups;
+	spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups);
+	spear3xx_machdata.functions = spear300_functions;
+	spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions);
+
+	spear3xx_machdata.modes_supported = true;
+	spear3xx_machdata.pmx_modes = spear300_pmx_modes;
+	spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear300_pmx_modes);
+
+	pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+	ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int __devexit spear300_pinctrl_remove(struct platform_device *pdev)
+{
+	return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear300_pinctrl_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = spear300_pinctrl_of_match,
+	},
+	.probe = spear300_pinctrl_probe,
+	.remove = __devexit_p(spear300_pinctrl_remove),
+};
+
+static int __init spear300_pinctrl_init(void)
+{
+	return platform_driver_register(&spear300_pinctrl_driver);
+}
+arch_initcall(spear300_pinctrl_init);
+
+static void __exit spear300_pinctrl_exit(void)
+{
+	platform_driver_unregister(&spear300_pinctrl_driver);
+}
+module_exit(spear300_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c
new file mode 100644
index 0000000..1a97076
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear310.c
@@ -0,0 +1,431 @@
+/*
+ * Driver for the ST Microelectronics SPEAr310 pinmux
+ *
+ * Copyright (C) 2012 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/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear310-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG			0x08
+
+/* emi_cs_0_to_5_pins */
+static const unsigned emi_cs_0_to_5_pins[] = { 45, 46, 47, 48, 49, 50 };
+static struct spear_muxreg emi_cs_0_to_5_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux emi_cs_0_to_5_modemux[] = {
+	{
+		.muxregs = emi_cs_0_to_5_muxreg,
+		.nmuxregs = ARRAY_SIZE(emi_cs_0_to_5_muxreg),
+	},
+};
+
+static struct spear_pingroup emi_cs_0_to_5_pingroup = {
+	.name = "emi_cs_0_to_5_grp",
+	.pins = emi_cs_0_to_5_pins,
+	.npins = ARRAY_SIZE(emi_cs_0_to_5_pins),
+	.modemuxs = emi_cs_0_to_5_modemux,
+	.nmodemuxs = ARRAY_SIZE(emi_cs_0_to_5_modemux),
+};
+
+static const char *const emi_cs_0_to_5_grps[] = { "emi_cs_0_to_5_grp" };
+static struct spear_function emi_cs_0_to_5_function = {
+	.name = "emi",
+	.groups = emi_cs_0_to_5_grps,
+	.ngroups = ARRAY_SIZE(emi_cs_0_to_5_grps),
+};
+
+/* uart1_pins */
+static const unsigned uart1_pins[] = { 0, 1 };
+static struct spear_muxreg uart1_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_FIRDA_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux uart1_modemux[] = {
+	{
+		.muxregs = uart1_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart1_muxreg),
+	},
+};
+
+static struct spear_pingroup uart1_pingroup = {
+	.name = "uart1_grp",
+	.pins = uart1_pins,
+	.npins = ARRAY_SIZE(uart1_pins),
+	.modemuxs = uart1_modemux,
+	.nmodemuxs = ARRAY_SIZE(uart1_modemux),
+};
+
+static const char *const uart1_grps[] = { "uart1_grp" };
+static struct spear_function uart1_function = {
+	.name = "uart1",
+	.groups = uart1_grps,
+	.ngroups = ARRAY_SIZE(uart1_grps),
+};
+
+/* uart2_pins */
+static const unsigned uart2_pins[] = { 43, 44 };
+static struct spear_muxreg uart2_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux uart2_modemux[] = {
+	{
+		.muxregs = uart2_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart2_muxreg),
+	},
+};
+
+static struct spear_pingroup uart2_pingroup = {
+	.name = "uart2_grp",
+	.pins = uart2_pins,
+	.npins = ARRAY_SIZE(uart2_pins),
+	.modemuxs = uart2_modemux,
+	.nmodemuxs = ARRAY_SIZE(uart2_modemux),
+};
+
+static const char *const uart2_grps[] = { "uart2_grp" };
+static struct spear_function uart2_function = {
+	.name = "uart2",
+	.groups = uart2_grps,
+	.ngroups = ARRAY_SIZE(uart2_grps),
+};
+
+/* uart3_pins */
+static const unsigned uart3_pins[] = { 37, 38 };
+static struct spear_muxreg uart3_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux uart3_modemux[] = {
+	{
+		.muxregs = uart3_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart3_muxreg),
+	},
+};
+
+static struct spear_pingroup uart3_pingroup = {
+	.name = "uart3_grp",
+	.pins = uart3_pins,
+	.npins = ARRAY_SIZE(uart3_pins),
+	.modemuxs = uart3_modemux,
+	.nmodemuxs = ARRAY_SIZE(uart3_modemux),
+};
+
+static const char *const uart3_grps[] = { "uart3_grp" };
+static struct spear_function uart3_function = {
+	.name = "uart3",
+	.groups = uart3_grps,
+	.ngroups = ARRAY_SIZE(uart3_grps),
+};
+
+/* uart4_pins */
+static const unsigned uart4_pins[] = { 39, 40 };
+static struct spear_muxreg uart4_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux uart4_modemux[] = {
+	{
+		.muxregs = uart4_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart4_muxreg),
+	},
+};
+
+static struct spear_pingroup uart4_pingroup = {
+	.name = "uart4_grp",
+	.pins = uart4_pins,
+	.npins = ARRAY_SIZE(uart4_pins),
+	.modemuxs = uart4_modemux,
+	.nmodemuxs = ARRAY_SIZE(uart4_modemux),
+};
+
+static const char *const uart4_grps[] = { "uart4_grp" };
+static struct spear_function uart4_function = {
+	.name = "uart4",
+	.groups = uart4_grps,
+	.ngroups = ARRAY_SIZE(uart4_grps),
+};
+
+/* uart5_pins */
+static const unsigned uart5_pins[] = { 41, 42 };
+static struct spear_muxreg uart5_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux uart5_modemux[] = {
+	{
+		.muxregs = uart5_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart5_muxreg),
+	},
+};
+
+static struct spear_pingroup uart5_pingroup = {
+	.name = "uart5_grp",
+	.pins = uart5_pins,
+	.npins = ARRAY_SIZE(uart5_pins),
+	.modemuxs = uart5_modemux,
+	.nmodemuxs = ARRAY_SIZE(uart5_modemux),
+};
+
+static const char *const uart5_grps[] = { "uart5_grp" };
+static struct spear_function uart5_function = {
+	.name = "uart5",
+	.groups = uart5_grps,
+	.ngroups = ARRAY_SIZE(uart5_grps),
+};
+
+/* fsmc_pins */
+static const unsigned fsmc_pins[] = { 34, 35, 36 };
+static struct spear_muxreg fsmc_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_CS_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux fsmc_modemux[] = {
+	{
+		.muxregs = fsmc_muxreg,
+		.nmuxregs = ARRAY_SIZE(fsmc_muxreg),
+	},
+};
+
+static struct spear_pingroup fsmc_pingroup = {
+	.name = "fsmc_grp",
+	.pins = fsmc_pins,
+	.npins = ARRAY_SIZE(fsmc_pins),
+	.modemuxs = fsmc_modemux,
+	.nmodemuxs = ARRAY_SIZE(fsmc_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_grp" };
+static struct spear_function fsmc_function = {
+	.name = "fsmc",
+	.groups = fsmc_grps,
+	.ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* rs485_0_pins */
+static const unsigned rs485_0_pins[] = { 19, 20, 21, 22, 23 };
+static struct spear_muxreg rs485_0_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux rs485_0_modemux[] = {
+	{
+		.muxregs = rs485_0_muxreg,
+		.nmuxregs = ARRAY_SIZE(rs485_0_muxreg),
+	},
+};
+
+static struct spear_pingroup rs485_0_pingroup = {
+	.name = "rs485_0_grp",
+	.pins = rs485_0_pins,
+	.npins = ARRAY_SIZE(rs485_0_pins),
+	.modemuxs = rs485_0_modemux,
+	.nmodemuxs = ARRAY_SIZE(rs485_0_modemux),
+};
+
+static const char *const rs485_0_grps[] = { "rs485_0" };
+static struct spear_function rs485_0_function = {
+	.name = "rs485_0",
+	.groups = rs485_0_grps,
+	.ngroups = ARRAY_SIZE(rs485_0_grps),
+};
+
+/* rs485_1_pins */
+static const unsigned rs485_1_pins[] = { 14, 15, 16, 17, 18 };
+static struct spear_muxreg rs485_1_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux rs485_1_modemux[] = {
+	{
+		.muxregs = rs485_1_muxreg,
+		.nmuxregs = ARRAY_SIZE(rs485_1_muxreg),
+	},
+};
+
+static struct spear_pingroup rs485_1_pingroup = {
+	.name = "rs485_1_grp",
+	.pins = rs485_1_pins,
+	.npins = ARRAY_SIZE(rs485_1_pins),
+	.modemuxs = rs485_1_modemux,
+	.nmodemuxs = ARRAY_SIZE(rs485_1_modemux),
+};
+
+static const char *const rs485_1_grps[] = { "rs485_1" };
+static struct spear_function rs485_1_function = {
+	.name = "rs485_1",
+	.groups = rs485_1_grps,
+	.ngroups = ARRAY_SIZE(rs485_1_grps),
+};
+
+/* tdm_pins */
+static const unsigned tdm_pins[] = { 10, 11, 12, 13 };
+static struct spear_muxreg tdm_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_modemux tdm_modemux[] = {
+	{
+		.muxregs = tdm_muxreg,
+		.nmuxregs = ARRAY_SIZE(tdm_muxreg),
+	},
+};
+
+static struct spear_pingroup tdm_pingroup = {
+	.name = "tdm_grp",
+	.pins = tdm_pins,
+	.npins = ARRAY_SIZE(tdm_pins),
+	.modemuxs = tdm_modemux,
+	.nmodemuxs = ARRAY_SIZE(tdm_modemux),
+};
+
+static const char *const tdm_grps[] = { "tdm_grp" };
+static struct spear_function tdm_function = {
+	.name = "tdm",
+	.groups = tdm_grps,
+	.ngroups = ARRAY_SIZE(tdm_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear310_pingroups[] = {
+	SPEAR3XX_COMMON_PINGROUPS,
+	&emi_cs_0_to_5_pingroup,
+	&uart1_pingroup,
+	&uart2_pingroup,
+	&uart3_pingroup,
+	&uart4_pingroup,
+	&uart5_pingroup,
+	&fsmc_pingroup,
+	&rs485_0_pingroup,
+	&rs485_1_pingroup,
+	&tdm_pingroup,
+};
+
+/* functions */
+static struct spear_function *spear310_functions[] = {
+	SPEAR3XX_COMMON_FUNCTIONS,
+	&emi_cs_0_to_5_function,
+	&uart1_function,
+	&uart2_function,
+	&uart3_function,
+	&uart4_function,
+	&uart5_function,
+	&fsmc_function,
+	&rs485_0_function,
+	&rs485_1_function,
+	&tdm_function,
+};
+
+static struct of_device_id spear310_pinctrl_of_match[] __devinitdata = {
+	{
+		.compatible = "st,spear310-pinmux",
+	},
+	{},
+};
+
+static int __devinit spear310_pinctrl_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	spear3xx_machdata.groups = spear310_pingroups;
+	spear3xx_machdata.ngroups = ARRAY_SIZE(spear310_pingroups);
+	spear3xx_machdata.functions = spear310_functions;
+	spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions);
+
+	pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+	spear3xx_machdata.modes_supported = false;
+
+	ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int __devexit spear310_pinctrl_remove(struct platform_device *pdev)
+{
+	return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear310_pinctrl_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = spear310_pinctrl_of_match,
+	},
+	.probe = spear310_pinctrl_probe,
+	.remove = __devexit_p(spear310_pinctrl_remove),
+};
+
+static int __init spear310_pinctrl_init(void)
+{
+	return platform_driver_register(&spear310_pinctrl_driver);
+}
+arch_initcall(spear310_pinctrl_init);
+
+static void __exit spear310_pinctrl_exit(void)
+{
+	platform_driver_unregister(&spear310_pinctrl_driver);
+}
+module_exit(spear310_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, SPEAr310_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c
new file mode 100644
index 0000000..de726e6
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear320.c
@@ -0,0 +1,3468 @@
+/*
+ * Driver for the ST Microelectronics SPEAr320 pinmux
+ *
+ * Copyright (C) 2012 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/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear320-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG			0x0C
+#define MODE_CONFIG_REG			0x10
+#define MODE_EXT_CONFIG_REG		0x18
+
+/* 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 EXTENDED_MODE		(1 << 4)
+
+static struct spear_pmx_mode pmx_mode_auto_net_smii = {
+	.name = "Automation Networking SMII mode",
+	.mode = AUTO_NET_SMII_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x00000007,
+	.val = 0x0,
+};
+
+static struct spear_pmx_mode pmx_mode_auto_net_mii = {
+	.name = "Automation Networking MII mode",
+	.mode = AUTO_NET_MII_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x00000007,
+	.val = 0x1,
+};
+
+static struct spear_pmx_mode pmx_mode_auto_exp = {
+	.name = "Automation Expanded mode",
+	.mode = AUTO_EXP_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x00000007,
+	.val = 0x2,
+};
+
+static struct spear_pmx_mode pmx_mode_small_printers = {
+	.name = "Small Printers mode",
+	.mode = SMALL_PRINTERS_MODE,
+	.reg = MODE_CONFIG_REG,
+	.mask = 0x00000007,
+	.val = 0x3,
+};
+
+static struct spear_pmx_mode pmx_mode_extended = {
+	.name = "extended mode",
+	.mode = EXTENDED_MODE,
+	.reg = MODE_EXT_CONFIG_REG,
+	.mask = 0x00000001,
+	.val = 0x1,
+};
+
+static struct spear_pmx_mode *spear320_pmx_modes[] = {
+	&pmx_mode_auto_net_smii,
+	&pmx_mode_auto_net_mii,
+	&pmx_mode_auto_exp,
+	&pmx_mode_small_printers,
+	&pmx_mode_extended,
+};
+
+/* Extended mode registers and their offsets */
+#define EXT_CTRL_REG				0x0018
+	#define MII_MDIO_MASK			(1 << 4)
+	#define MII_MDIO_10_11_VAL		0
+	#define MII_MDIO_81_VAL			(1 << 4)
+	#define EMI_FSMC_DYNAMIC_MUX_MASK	(1 << 5)
+	#define MAC_MODE_MII			0
+	#define MAC_MODE_RMII			1
+	#define MAC_MODE_SMII			2
+	#define MAC_MODE_SS_SMII		3
+	#define MAC_MODE_MASK			0x3
+	#define MAC1_MODE_SHIFT			16
+	#define MAC2_MODE_SHIFT			18
+
+#define IP_SEL_PAD_0_9_REG			0x00A4
+	#define PMX_PL_0_1_MASK			(0x3F << 0)
+	#define PMX_UART2_PL_0_1_VAL		0x0
+	#define PMX_I2C2_PL_0_1_VAL		(0x4 | (0x4 << 3))
+
+	#define PMX_PL_2_3_MASK			(0x3F << 6)
+	#define PMX_I2C2_PL_2_3_VAL		0x0
+	#define PMX_UART6_PL_2_3_VAL		((0x1 << 6) | (0x1 << 9))
+	#define PMX_UART1_ENH_PL_2_3_VAL	((0x4 << 6) | (0x4 << 9))
+
+	#define PMX_PL_4_5_MASK			(0x3F << 12)
+	#define PMX_UART5_PL_4_5_VAL		((0x1 << 12) | (0x1 << 15))
+	#define PMX_UART1_ENH_PL_4_5_VAL	((0x4 << 12) | (0x4 << 15))
+	#define PMX_PL_5_MASK			(0x7 << 15)
+	#define PMX_TOUCH_Y_PL_5_VAL		0x0
+
+	#define PMX_PL_6_7_MASK			(0x3F << 18)
+	#define PMX_PL_6_MASK			(0x7 << 18)
+	#define PMX_PL_7_MASK			(0x7 << 21)
+	#define PMX_UART4_PL_6_7_VAL		((0x1 << 18) | (0x1 << 21))
+	#define PMX_PWM_3_PL_6_VAL		(0x2 << 18)
+	#define PMX_PWM_2_PL_7_VAL		(0x2 << 21)
+	#define PMX_UART1_ENH_PL_6_7_VAL	((0x4 << 18) | (0x4 << 21))
+
+	#define PMX_PL_8_9_MASK			(0x3F << 24)
+	#define PMX_UART3_PL_8_9_VAL		((0x1 << 24) | (0x1 << 27))
+	#define PMX_PWM_0_1_PL_8_9_VAL		((0x2 << 24) | (0x2 << 27))
+	#define PMX_I2C1_PL_8_9_VAL		((0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_10_19_REG			0x00A8
+	#define PMX_PL_10_11_MASK		(0x3F << 0)
+	#define PMX_SMII_PL_10_11_VAL		0
+	#define PMX_RMII_PL_10_11_VAL		((0x4 << 0) | (0x4 << 3))
+
+	#define PMX_PL_12_MASK			(0x7 << 6)
+	#define PMX_PWM3_PL_12_VAL		0
+	#define PMX_SDHCI_CD_PL_12_VAL		(0x4 << 6)
+
+	#define PMX_PL_13_14_MASK		(0x3F << 9)
+	#define PMX_PL_13_MASK			(0x7 << 9)
+	#define PMX_PL_14_MASK			(0x7 << 12)
+	#define PMX_SSP2_PL_13_14_15_16_VAL	0
+	#define PMX_UART4_PL_13_14_VAL		((0x1 << 9) | (0x1 << 12))
+	#define PMX_RMII_PL_13_14_VAL		((0x4 << 9) | (0x4 << 12))
+	#define PMX_PWM2_PL_13_VAL		(0x2 << 9)
+	#define PMX_PWM1_PL_14_VAL		(0x2 << 12)
+
+	#define PMX_PL_15_MASK			(0x7 << 15)
+	#define PMX_PWM0_PL_15_VAL		(0x2 << 15)
+	#define PMX_PL_15_16_MASK		(0x3F << 15)
+	#define PMX_UART3_PL_15_16_VAL		((0x1 << 15) | (0x1 << 18))
+	#define PMX_RMII_PL_15_16_VAL		((0x4 << 15) | (0x4 << 18))
+
+	#define PMX_PL_17_18_MASK		(0x3F << 21)
+	#define PMX_SSP1_PL_17_18_19_20_VAL	0
+	#define PMX_RMII_PL_17_18_VAL		((0x4 << 21) | (0x4 << 24))
+
+	#define PMX_PL_19_MASK			(0x7 << 27)
+	#define PMX_I2C2_PL_19_VAL		(0x1 << 27)
+	#define PMX_RMII_PL_19_VAL		(0x4 << 27)
+
+#define IP_SEL_PAD_20_29_REG			0x00AC
+	#define PMX_PL_20_MASK			(0x7 << 0)
+	#define PMX_I2C2_PL_20_VAL		(0x1 << 0)
+	#define PMX_RMII_PL_20_VAL		(0x4 << 0)
+
+	#define PMX_PL_21_TO_27_MASK		(0x1FFFFF << 3)
+	#define PMX_SMII_PL_21_TO_27_VAL	0
+	#define PMX_RMII_PL_21_TO_27_VAL	((0x4 << 3) | (0x4 << 6) | (0x4 << 9) | (0x4 << 12) | (0x4 << 15) | (0x4 << 18) | (0x4 << 21))
+
+	#define PMX_PL_28_29_MASK		(0x3F << 24)
+	#define PMX_PL_28_MASK			(0x7 << 24)
+	#define PMX_PL_29_MASK			(0x7 << 27)
+	#define PMX_UART1_PL_28_29_VAL		0
+	#define PMX_PWM_3_PL_28_VAL		(0x4 << 24)
+	#define PMX_PWM_2_PL_29_VAL		(0x4 << 27)
+
+#define IP_SEL_PAD_30_39_REG			0x00B0
+	#define PMX_PL_30_31_MASK		(0x3F << 0)
+	#define PMX_CAN1_PL_30_31_VAL		(0)
+	#define PMX_PL_30_MASK			(0x7 << 0)
+	#define PMX_PL_31_MASK			(0x7 << 3)
+	#define PMX_PWM1_EXT_PL_30_VAL		(0x4 << 0)
+	#define PMX_PWM0_EXT_PL_31_VAL		(0x4 << 3)
+	#define PMX_UART1_ENH_PL_31_VAL		(0x3 << 3)
+
+	#define PMX_PL_32_33_MASK		(0x3F << 6)
+	#define PMX_CAN0_PL_32_33_VAL		0
+	#define PMX_UART1_ENH_PL_32_33_VAL	((0x3 << 6) | (0x3 << 9))
+	#define PMX_SSP2_PL_32_33_VAL		((0x4 << 6) | (0x4 << 9))
+
+	#define PMX_PL_34_MASK			(0x7 << 12)
+	#define PMX_PWM2_PL_34_VAL		0
+	#define PMX_UART1_ENH_PL_34_VAL		(0x2 << 12)
+	#define PMX_SSP2_PL_34_VAL		(0x4 << 12)
+
+	#define PMX_PL_35_MASK			(0x7 << 15)
+	#define PMX_I2S_REF_CLK_PL_35_VAL	0
+	#define PMX_UART1_ENH_PL_35_VAL		(0x2 << 15)
+	#define PMX_SSP2_PL_35_VAL		(0x4 << 15)
+
+	#define PMX_PL_36_MASK			(0x7 << 18)
+	#define PMX_TOUCH_X_PL_36_VAL		0
+	#define PMX_UART1_ENH_PL_36_VAL		(0x2 << 18)
+	#define PMX_SSP1_PL_36_VAL		(0x4 << 18)
+
+	#define PMX_PL_37_38_MASK		(0x3F << 21)
+	#define PMX_PWM0_1_PL_37_38_VAL		0
+	#define PMX_UART5_PL_37_38_VAL		((0x2 << 21) | (0x2 << 24))
+	#define PMX_SSP1_PL_37_38_VAL		((0x4 << 21) | (0x4 << 24))
+
+	#define PMX_PL_39_MASK			(0x7 << 27)
+	#define PMX_I2S_PL_39_VAL		0
+	#define PMX_UART4_PL_39_VAL		(0x2 << 27)
+	#define PMX_SSP1_PL_39_VAL		(0x4 << 27)
+
+#define IP_SEL_PAD_40_49_REG			0x00B4
+	#define PMX_PL_40_MASK			(0x7 << 0)
+	#define PMX_I2S_PL_40_VAL		0
+	#define PMX_UART4_PL_40_VAL		(0x2 << 0)
+	#define PMX_PWM3_PL_40_VAL		(0x4 << 0)
+
+	#define PMX_PL_41_42_MASK		(0x3F << 3)
+	#define PMX_PL_41_MASK			(0x7 << 3)
+	#define PMX_PL_42_MASK			(0x7 << 6)
+	#define PMX_I2S_PL_41_42_VAL		0
+	#define PMX_UART3_PL_41_42_VAL		((0x2 << 3) | (0x2 << 6))
+	#define PMX_PWM2_PL_41_VAL		(0x4 << 3)
+	#define PMX_PWM1_PL_42_VAL		(0x4 << 6)
+
+	#define PMX_PL_43_MASK			(0x7 << 9)
+	#define PMX_SDHCI_PL_43_VAL		0
+	#define PMX_UART1_ENH_PL_43_VAL		(0x2 << 9)
+	#define PMX_PWM0_PL_43_VAL		(0x4 << 9)
+
+	#define PMX_PL_44_45_MASK		(0x3F << 12)
+	#define PMX_SDHCI_PL_44_45_VAL	0
+	#define PMX_UART1_ENH_PL_44_45_VAL	((0x2 << 12) | (0x2 << 15))
+	#define PMX_SSP2_PL_44_45_VAL		((0x4 << 12) | (0x4 << 15))
+
+	#define PMX_PL_46_47_MASK		(0x3F << 18)
+	#define PMX_SDHCI_PL_46_47_VAL	0
+	#define PMX_FSMC_EMI_PL_46_47_VAL	((0x2 << 18) | (0x2 << 21))
+	#define PMX_SSP2_PL_46_47_VAL		((0x4 << 18) | (0x4 << 21))
+
+	#define PMX_PL_48_49_MASK		(0x3F << 24)
+	#define PMX_SDHCI_PL_48_49_VAL	0
+	#define PMX_FSMC_EMI_PL_48_49_VAL	((0x2 << 24) | (0x2 << 27))
+	#define PMX_SSP1_PL_48_49_VAL		((0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_50_59_REG			0x00B8
+	#define PMX_PL_50_51_MASK		(0x3F << 0)
+	#define PMX_EMI_PL_50_51_VAL		((0x2 << 0) | (0x2 << 3))
+	#define PMX_SSP1_PL_50_51_VAL		((0x4 << 0) | (0x4 << 3))
+	#define PMX_PL_50_MASK			(0x7 << 0)
+	#define PMX_PL_51_MASK			(0x7 << 3)
+	#define PMX_SDHCI_PL_50_VAL		0
+	#define PMX_SDHCI_CD_PL_51_VAL		0
+
+	#define PMX_PL_52_53_MASK		(0x3F << 6)
+	#define PMX_FSMC_PL_52_53_VAL		0
+	#define PMX_EMI_PL_52_53_VAL		((0x2 << 6) | (0x2 << 9))
+	#define PMX_UART3_PL_52_53_VAL		((0x4 << 6) | (0x4 << 9))
+
+	#define PMX_PL_54_55_56_MASK		(0x1FF << 12)
+	#define PMX_FSMC_EMI_PL_54_55_56_VAL	((0x2 << 12) | (0x2 << 15) | (0x2 << 18))
+
+	#define PMX_PL_57_MASK			(0x7 << 21)
+	#define PMX_FSMC_PL_57_VAL		0
+	#define PMX_PWM3_PL_57_VAL		(0x4 << 21)
+
+	#define PMX_PL_58_59_MASK		(0x3F << 24)
+	#define PMX_PL_58_MASK			(0x7 << 24)
+	#define PMX_PL_59_MASK			(0x7 << 27)
+	#define PMX_FSMC_EMI_PL_58_59_VAL	((0x2 << 24) | (0x2 << 27))
+	#define PMX_PWM2_PL_58_VAL		(0x4 << 24)
+	#define PMX_PWM1_PL_59_VAL		(0x4 << 27)
+
+#define IP_SEL_PAD_60_69_REG			0x00BC
+	#define PMX_PL_60_MASK			(0x7 << 0)
+	#define PMX_FSMC_PL_60_VAL		0
+	#define PMX_PWM0_PL_60_VAL		(0x4 << 0)
+
+	#define PMX_PL_61_TO_64_MASK		(0xFFF << 3)
+	#define PMX_FSMC_PL_61_TO_64_VAL	((0x2 << 3) | (0x2 << 6) | (0x2 << 9) | (0x2 << 12))
+	#define PMX_SSP2_PL_61_TO_64_VAL	((0x4 << 3) | (0x4 << 6) | (0x4 << 9) | (0x4 << 12))
+
+	#define PMX_PL_65_TO_68_MASK		(0xFFF << 15)
+	#define PMX_FSMC_PL_65_TO_68_VAL	((0x2 << 15) | (0x2 << 18) | (0x2 << 21) | (0x2 << 24))
+	#define PMX_SSP1_PL_65_TO_68_VAL	((0x4 << 15) | (0x4 << 18) | (0x4 << 21) | (0x4 << 24))
+
+	#define PMX_PL_69_MASK			(0x7 << 27)
+	#define PMX_CLCD_PL_69_VAL		(0)
+	#define PMX_EMI_PL_69_VAL		(0x2 << 27)
+	#define PMX_SPP_PL_69_VAL		(0x3 << 27)
+	#define PMX_UART5_PL_69_VAL		(0x4 << 27)
+
+#define IP_SEL_PAD_70_79_REG			0x00C0
+	#define PMX_PL_70_MASK			(0x7 << 0)
+	#define PMX_CLCD_PL_70_VAL		(0)
+	#define PMX_FSMC_EMI_PL_70_VAL		(0x2 << 0)
+	#define PMX_SPP_PL_70_VAL		(0x3 << 0)
+	#define PMX_UART5_PL_70_VAL		(0x4 << 0)
+
+	#define PMX_PL_71_72_MASK		(0x3F << 3)
+	#define PMX_CLCD_PL_71_72_VAL		(0)
+	#define PMX_FSMC_EMI_PL_71_72_VAL	((0x2 << 3) | (0x2 << 6))
+	#define PMX_SPP_PL_71_72_VAL		((0x3 << 3) | (0x3 << 6))
+	#define PMX_UART4_PL_71_72_VAL		((0x4 << 3) | (0x4 << 6))
+
+	#define PMX_PL_73_MASK			(0x7 << 9)
+	#define PMX_CLCD_PL_73_VAL		(0)
+	#define PMX_FSMC_EMI_PL_73_VAL		(0x2 << 9)
+	#define PMX_SPP_PL_73_VAL		(0x3 << 9)
+	#define PMX_UART3_PL_73_VAL		(0x4 << 9)
+
+	#define PMX_PL_74_MASK			(0x7 << 12)
+	#define PMX_CLCD_PL_74_VAL		(0)
+	#define PMX_EMI_PL_74_VAL		(0x2 << 12)
+	#define PMX_SPP_PL_74_VAL		(0x3 << 12)
+	#define PMX_UART3_PL_74_VAL		(0x4 << 12)
+
+	#define PMX_PL_75_76_MASK		(0x3F << 15)
+	#define PMX_CLCD_PL_75_76_VAL		(0)
+	#define PMX_EMI_PL_75_76_VAL		((0x2 << 15) | (0x2 << 18))
+	#define PMX_SPP_PL_75_76_VAL		((0x3 << 15) | (0x3 << 18))
+	#define PMX_I2C2_PL_75_76_VAL		((0x4 << 15) | (0x4 << 18))
+
+	#define PMX_PL_77_78_79_MASK		(0x1FF << 21)
+	#define PMX_CLCD_PL_77_78_79_VAL	(0)
+	#define PMX_EMI_PL_77_78_79_VAL		((0x2 << 21) | (0x2 << 24) | (0x2 << 27))
+	#define PMX_SPP_PL_77_78_79_VAL		((0x3 << 21) | (0x3 << 24) | (0x3 << 27))
+	#define PMX_RS485_PL_77_78_79_VAL	((0x4 << 21) | (0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_80_89_REG			0x00C4
+	#define PMX_PL_80_TO_85_MASK		(0x3FFFF << 0)
+	#define PMX_CLCD_PL_80_TO_85_VAL	0
+	#define PMX_MII2_PL_80_TO_85_VAL	((0x1 << 0) | (0x1 << 3) | (0x1 << 6) | (0x1 << 9) | (0x1 << 12) | (0x1 << 15))
+	#define PMX_EMI_PL_80_TO_85_VAL		((0x2 << 0) | (0x2 << 3) | (0x2 << 6) | (0x2 << 9) | (0x2 << 12) | (0x2 << 15))
+	#define PMX_SPP_PL_80_TO_85_VAL		((0x3 << 0) | (0x3 << 3) | (0x3 << 6) | (0x3 << 9) | (0x3 << 12) | (0x3 << 15))
+	#define PMX_UART1_ENH_PL_80_TO_85_VAL	((0x4 << 0) | (0x4 << 3) | (0x4 << 6) | (0x4 << 9) | (0x4 << 12) | (0x4 << 15))
+
+	#define PMX_PL_86_87_MASK		(0x3F << 18)
+	#define PMX_PL_86_MASK			(0x7 << 18)
+	#define PMX_PL_87_MASK			(0x7 << 21)
+	#define PMX_CLCD_PL_86_87_VAL		0
+	#define PMX_MII2_PL_86_87_VAL		((0x1 << 18) | (0x1 << 21))
+	#define PMX_EMI_PL_86_87_VAL		((0x2 << 18) | (0x2 << 21))
+	#define PMX_PWM3_PL_86_VAL		(0x4 << 18)
+	#define PMX_PWM2_PL_87_VAL		(0x4 << 21)
+
+	#define PMX_PL_88_89_MASK		(0x3F << 24)
+	#define PMX_CLCD_PL_88_89_VAL		0
+	#define PMX_MII2_PL_88_89_VAL		((0x1 << 24) | (0x1 << 27))
+	#define PMX_EMI_PL_88_89_VAL		((0x2 << 24) | (0x2 << 27))
+	#define PMX_UART6_PL_88_89_VAL		((0x3 << 24) | (0x3 << 27))
+	#define PMX_PWM0_1_PL_88_89_VAL		((0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_90_99_REG			0x00C8
+	#define PMX_PL_90_91_MASK		(0x3F << 0)
+	#define PMX_CLCD_PL_90_91_VAL		0
+	#define PMX_MII2_PL_90_91_VAL		((0x1 << 0) | (0x1 << 3))
+	#define PMX_EMI1_PL_90_91_VAL		((0x2 << 0) | (0x2 << 3))
+	#define PMX_UART5_PL_90_91_VAL		((0x3 << 0) | (0x3 << 3))
+	#define PMX_SSP2_PL_90_91_VAL		((0x4 << 0) | (0x4 << 3))
+
+	#define PMX_PL_92_93_MASK		(0x3F << 6)
+	#define PMX_CLCD_PL_92_93_VAL		0
+	#define PMX_MII2_PL_92_93_VAL		((0x1 << 6) | (0x1 << 9))
+	#define PMX_EMI1_PL_92_93_VAL		((0x2 << 6) | (0x2 << 9))
+	#define PMX_UART4_PL_92_93_VAL		((0x3 << 6) | (0x3 << 9))
+	#define PMX_SSP2_PL_92_93_VAL		((0x4 << 6) | (0x4 << 9))
+
+	#define PMX_PL_94_95_MASK		(0x3F << 12)
+	#define PMX_CLCD_PL_94_95_VAL		0
+	#define PMX_MII2_PL_94_95_VAL		((0x1 << 12) | (0x1 << 15))
+	#define PMX_EMI1_PL_94_95_VAL		((0x2 << 12) | (0x2 << 15))
+	#define PMX_UART3_PL_94_95_VAL		((0x3 << 12) | (0x3 << 15))
+	#define PMX_SSP1_PL_94_95_VAL		((0x4 << 12) | (0x4 << 15))
+
+	#define PMX_PL_96_97_MASK		(0x3F << 18)
+	#define PMX_CLCD_PL_96_97_VAL		0
+	#define PMX_MII2_PL_96_97_VAL		((0x1 << 18) | (0x1 << 21))
+	#define PMX_EMI1_PL_96_97_VAL		((0x2 << 18) | (0x2 << 21))
+	#define PMX_I2C2_PL_96_97_VAL		((0x3 << 18) | (0x3 << 21))
+	#define PMX_SSP1_PL_96_97_VAL		((0x4 << 18) | (0x4 << 21))
+
+	#define PMX_PL_98_MASK			(0x7 << 24)
+	#define PMX_CLCD_PL_98_VAL		0
+	#define PMX_I2C1_PL_98_VAL		(0x2 << 24)
+	#define PMX_UART3_PL_98_VAL		(0x4 << 24)
+
+	#define PMX_PL_99_MASK			(0x7 << 27)
+	#define PMX_SDHCI_PL_99_VAL		0
+	#define PMX_I2C1_PL_99_VAL		(0x2 << 27)
+	#define PMX_UART3_PL_99_VAL		(0x4 << 27)
+
+#define IP_SEL_MIX_PAD_REG			0x00CC
+	#define PMX_PL_100_101_MASK		(0x3F << 0)
+	#define PMX_SDHCI_PL_100_101_VAL	0
+	#define PMX_UART4_PL_100_101_VAL	((0x4 << 0) | (0x4 << 3))
+
+	#define PMX_SSP1_PORT_SEL_MASK		(0x7 << 8)
+	#define PMX_SSP1_PORT_94_TO_97_VAL	0
+	#define PMX_SSP1_PORT_65_TO_68_VAL	(0x1 << 8)
+	#define PMX_SSP1_PORT_48_TO_51_VAL	(0x2 << 8)
+	#define PMX_SSP1_PORT_36_TO_39_VAL	(0x3 << 8)
+	#define PMX_SSP1_PORT_17_TO_20_VAL	(0x4 << 8)
+
+	#define PMX_SSP2_PORT_SEL_MASK		(0x7 << 11)
+	#define PMX_SSP2_PORT_90_TO_93_VAL	0
+	#define PMX_SSP2_PORT_61_TO_64_VAL	(0x1 << 11)
+	#define PMX_SSP2_PORT_44_TO_47_VAL	(0x2 << 11)
+	#define PMX_SSP2_PORT_32_TO_35_VAL	(0x3 << 11)
+	#define PMX_SSP2_PORT_13_TO_16_VAL	(0x4 << 11)
+
+	#define PMX_UART1_ENH_PORT_SEL_MASK		(0x3 << 14)
+	#define PMX_UART1_ENH_PORT_81_TO_85_VAL		0
+	#define PMX_UART1_ENH_PORT_44_45_34_36_VAL	(0x1 << 14)
+	#define PMX_UART1_ENH_PORT_32_TO_34_36_VAL	(0x2 << 14)
+	#define PMX_UART1_ENH_PORT_3_TO_5_7_VAL		(0x3 << 14)
+
+	#define PMX_UART3_PORT_SEL_MASK		(0x7 << 16)
+	#define PMX_UART3_PORT_94_VAL		0
+	#define PMX_UART3_PORT_73_VAL		(0x1 << 16)
+	#define PMX_UART3_PORT_52_VAL		(0x2 << 16)
+	#define PMX_UART3_PORT_41_VAL		(0x3 << 16)
+	#define PMX_UART3_PORT_15_VAL		(0x4 << 16)
+	#define PMX_UART3_PORT_8_VAL		(0x5 << 16)
+	#define PMX_UART3_PORT_99_VAL		(0x6 << 16)
+
+	#define PMX_UART4_PORT_SEL_MASK		(0x7 << 19)
+	#define PMX_UART4_PORT_92_VAL		0
+	#define PMX_UART4_PORT_71_VAL		(0x1 << 19)
+	#define PMX_UART4_PORT_39_VAL		(0x2 << 19)
+	#define PMX_UART4_PORT_13_VAL		(0x3 << 19)
+	#define PMX_UART4_PORT_6_VAL		(0x4 << 19)
+	#define PMX_UART4_PORT_101_VAL		(0x5 << 19)
+
+	#define PMX_UART5_PORT_SEL_MASK		(0x3 << 22)
+	#define PMX_UART5_PORT_90_VAL		0
+	#define PMX_UART5_PORT_69_VAL		(0x1 << 22)
+	#define PMX_UART5_PORT_37_VAL		(0x2 << 22)
+	#define PMX_UART5_PORT_4_VAL		(0x3 << 22)
+
+	#define PMX_UART6_PORT_SEL_MASK		(0x1 << 24)
+	#define PMX_UART6_PORT_88_VAL		0
+	#define PMX_UART6_PORT_2_VAL		(0x1 << 24)
+
+	#define PMX_I2C1_PORT_SEL_MASK		(0x1 << 25)
+	#define PMX_I2C1_PORT_8_9_VAL		0
+	#define PMX_I2C1_PORT_98_99_VAL		(0x1 << 25)
+
+	#define PMX_I2C2_PORT_SEL_MASK		(0x3 << 26)
+	#define PMX_I2C2_PORT_96_97_VAL		0
+	#define PMX_I2C2_PORT_75_76_VAL		(0x1 << 26)
+	#define PMX_I2C2_PORT_19_20_VAL		(0x2 << 26)
+	#define PMX_I2C2_PORT_2_3_VAL		(0x3 << 26)
+	#define PMX_I2C2_PORT_0_1_VAL		(0x4 << 26)
+
+	#define PMX_SDHCI_CD_PORT_SEL_MASK	(0x1 << 29)
+	#define PMX_SDHCI_CD_PORT_12_VAL	0
+	#define PMX_SDHCI_CD_PORT_51_VAL	(0x1 << 29)
+
+/* Pad multiplexing for CLCD device */
+static const unsigned clcd_pins[] = { 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+	79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+	97 };
+static struct spear_muxreg clcd_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_60_69_REG,
+		.mask = PMX_PL_69_MASK,
+		.val = PMX_CLCD_PL_69_VAL,
+	}, {
+		.reg = IP_SEL_PAD_70_79_REG,
+		.mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK |
+			PMX_PL_74_MASK | PMX_PL_75_76_MASK |
+			PMX_PL_77_78_79_MASK,
+		.val = PMX_CLCD_PL_70_VAL | PMX_CLCD_PL_71_72_VAL |
+			PMX_CLCD_PL_73_VAL | PMX_CLCD_PL_74_VAL |
+			PMX_CLCD_PL_75_76_VAL | PMX_CLCD_PL_77_78_79_VAL,
+	}, {
+		.reg = IP_SEL_PAD_80_89_REG,
+		.mask = PMX_PL_80_TO_85_MASK | PMX_PL_86_87_MASK |
+			PMX_PL_88_89_MASK,
+		.val = PMX_CLCD_PL_80_TO_85_VAL | PMX_CLCD_PL_86_87_VAL |
+			PMX_CLCD_PL_88_89_VAL,
+	}, {
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK |
+			PMX_PL_94_95_MASK | PMX_PL_96_97_MASK | PMX_PL_98_MASK,
+		.val = PMX_CLCD_PL_90_91_VAL | PMX_CLCD_PL_92_93_VAL |
+			PMX_CLCD_PL_94_95_VAL | PMX_CLCD_PL_96_97_VAL |
+			PMX_CLCD_PL_98_VAL,
+	},
+};
+
+static struct spear_modemux clcd_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = clcd_muxreg,
+		.nmuxregs = ARRAY_SIZE(clcd_muxreg),
+	},
+};
+
+static struct spear_pingroup clcd_pingroup = {
+	.name = "clcd_grp",
+	.pins = clcd_pins,
+	.npins = ARRAY_SIZE(clcd_pins),
+	.modemuxs = clcd_modemux,
+	.nmodemuxs = ARRAY_SIZE(clcd_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_grp" };
+static struct spear_function clcd_function = {
+	.name = "clcd",
+	.groups = clcd_grps,
+	.ngroups = ARRAY_SIZE(clcd_grps),
+};
+
+/* Pad multiplexing for EMI (Parallel NOR flash) device */
+static const unsigned emi_pins[] = { 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+	57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+	75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
+	93, 94, 95, 96, 97 };
+static struct spear_muxreg emi_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg emi_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_46_47_MASK | PMX_PL_48_49_MASK,
+		.val = PMX_FSMC_EMI_PL_46_47_VAL | PMX_FSMC_EMI_PL_48_49_VAL,
+	}, {
+		.reg = IP_SEL_PAD_50_59_REG,
+		.mask = PMX_PL_50_51_MASK | PMX_PL_52_53_MASK |
+			PMX_PL_54_55_56_MASK | PMX_PL_58_59_MASK,
+		.val = PMX_EMI_PL_50_51_VAL | PMX_EMI_PL_52_53_VAL |
+			PMX_FSMC_EMI_PL_54_55_56_VAL |
+			PMX_FSMC_EMI_PL_58_59_VAL,
+	}, {
+		.reg = IP_SEL_PAD_60_69_REG,
+		.mask = PMX_PL_69_MASK,
+		.val = PMX_EMI_PL_69_VAL,
+	}, {
+		.reg = IP_SEL_PAD_70_79_REG,
+		.mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK |
+			PMX_PL_74_MASK | PMX_PL_75_76_MASK |
+			PMX_PL_77_78_79_MASK,
+		.val = PMX_FSMC_EMI_PL_70_VAL | PMX_FSMC_EMI_PL_71_72_VAL |
+			PMX_FSMC_EMI_PL_73_VAL | PMX_EMI_PL_74_VAL |
+			PMX_EMI_PL_75_76_VAL | PMX_EMI_PL_77_78_79_VAL,
+	}, {
+		.reg = IP_SEL_PAD_80_89_REG,
+		.mask = PMX_PL_80_TO_85_MASK | PMX_PL_86_87_MASK |
+			PMX_PL_88_89_MASK,
+		.val = PMX_EMI_PL_80_TO_85_VAL | PMX_EMI_PL_86_87_VAL |
+			PMX_EMI_PL_88_89_VAL,
+	}, {
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK |
+			PMX_PL_94_95_MASK | PMX_PL_96_97_MASK,
+		.val = PMX_EMI1_PL_90_91_VAL | PMX_EMI1_PL_92_93_VAL |
+			PMX_EMI1_PL_94_95_VAL | PMX_EMI1_PL_96_97_VAL,
+	}, {
+		.reg = EXT_CTRL_REG,
+		.mask = EMI_FSMC_DYNAMIC_MUX_MASK,
+		.val = EMI_FSMC_DYNAMIC_MUX_MASK,
+	},
+};
+
+static struct spear_modemux emi_modemux[] = {
+	{
+		.modes = AUTO_EXP_MODE | EXTENDED_MODE,
+		.muxregs = emi_muxreg,
+		.nmuxregs = ARRAY_SIZE(emi_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = emi_ext_muxreg,
+		.nmuxregs = ARRAY_SIZE(emi_ext_muxreg),
+	},
+};
+
+static struct spear_pingroup emi_pingroup = {
+	.name = "emi_grp",
+	.pins = emi_pins,
+	.npins = ARRAY_SIZE(emi_pins),
+	.modemuxs = emi_modemux,
+	.nmodemuxs = ARRAY_SIZE(emi_modemux),
+};
+
+static const char *const emi_grps[] = { "emi_grp" };
+static struct spear_function emi_function = {
+	.name = "emi",
+	.groups = emi_grps,
+	.ngroups = ARRAY_SIZE(emi_grps),
+};
+
+/* Pad multiplexing for FSMC (NAND flash) device */
+static const unsigned fsmc_8bit_pins[] = { 52, 53, 54, 55, 56, 57, 58, 59, 60,
+	61, 62, 63, 64, 65, 66, 67, 68 };
+static struct spear_muxreg fsmc_8bit_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_50_59_REG,
+		.mask = PMX_PL_52_53_MASK | PMX_PL_54_55_56_MASK |
+			PMX_PL_57_MASK | PMX_PL_58_59_MASK,
+		.val = PMX_FSMC_PL_52_53_VAL | PMX_FSMC_EMI_PL_54_55_56_VAL |
+			PMX_FSMC_PL_57_VAL | PMX_FSMC_EMI_PL_58_59_VAL,
+	}, {
+		.reg = IP_SEL_PAD_60_69_REG,
+		.mask = PMX_PL_60_MASK | PMX_PL_61_TO_64_MASK |
+			PMX_PL_65_TO_68_MASK,
+		.val = PMX_FSMC_PL_60_VAL | PMX_FSMC_PL_61_TO_64_VAL |
+			PMX_FSMC_PL_65_TO_68_VAL,
+	}, {
+		.reg = EXT_CTRL_REG,
+		.mask = EMI_FSMC_DYNAMIC_MUX_MASK,
+		.val = EMI_FSMC_DYNAMIC_MUX_MASK,
+	},
+};
+
+static struct spear_modemux fsmc_8bit_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = fsmc_8bit_muxreg,
+		.nmuxregs = ARRAY_SIZE(fsmc_8bit_muxreg),
+	},
+};
+
+static struct spear_pingroup fsmc_8bit_pingroup = {
+	.name = "fsmc_8bit_grp",
+	.pins = fsmc_8bit_pins,
+	.npins = ARRAY_SIZE(fsmc_8bit_pins),
+	.modemuxs = fsmc_8bit_modemux,
+	.nmodemuxs = ARRAY_SIZE(fsmc_8bit_modemux),
+};
+
+static const unsigned fsmc_16bit_pins[] = { 46, 47, 48, 49, 52, 53, 54, 55, 56,
+	57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73 };
+static struct spear_muxreg fsmc_16bit_autoexp_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg fsmc_16bit_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_46_47_MASK | PMX_PL_48_49_MASK,
+		.val = PMX_FSMC_EMI_PL_46_47_VAL | PMX_FSMC_EMI_PL_48_49_VAL,
+	}, {
+		.reg = IP_SEL_PAD_70_79_REG,
+		.mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK,
+		.val = PMX_FSMC_EMI_PL_70_VAL | PMX_FSMC_EMI_PL_71_72_VAL |
+			PMX_FSMC_EMI_PL_73_VAL,
+	}
+};
+
+static struct spear_modemux fsmc_16bit_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = fsmc_8bit_muxreg,
+		.nmuxregs = ARRAY_SIZE(fsmc_8bit_muxreg),
+	}, {
+		.modes = AUTO_EXP_MODE | EXTENDED_MODE,
+		.muxregs = fsmc_16bit_autoexp_muxreg,
+		.nmuxregs = ARRAY_SIZE(fsmc_16bit_autoexp_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = fsmc_16bit_muxreg,
+		.nmuxregs = ARRAY_SIZE(fsmc_16bit_muxreg),
+	},
+};
+
+static struct spear_pingroup fsmc_16bit_pingroup = {
+	.name = "fsmc_16bit_grp",
+	.pins = fsmc_16bit_pins,
+	.npins = ARRAY_SIZE(fsmc_16bit_pins),
+	.modemuxs = fsmc_16bit_modemux,
+	.nmodemuxs = ARRAY_SIZE(fsmc_16bit_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_8bit_grp", "fsmc_16bit_grp" };
+static struct spear_function fsmc_function = {
+	.name = "fsmc",
+	.groups = fsmc_grps,
+	.ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* Pad multiplexing for SPP device */
+static const unsigned spp_pins[] = { 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+	80, 81, 82, 83, 84, 85 };
+static struct spear_muxreg spp_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_60_69_REG,
+		.mask = PMX_PL_69_MASK,
+		.val = PMX_SPP_PL_69_VAL,
+	}, {
+		.reg = IP_SEL_PAD_70_79_REG,
+		.mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK |
+			PMX_PL_74_MASK | PMX_PL_75_76_MASK |
+			PMX_PL_77_78_79_MASK,
+		.val = PMX_SPP_PL_70_VAL | PMX_SPP_PL_71_72_VAL |
+			PMX_SPP_PL_73_VAL | PMX_SPP_PL_74_VAL |
+			PMX_SPP_PL_75_76_VAL | PMX_SPP_PL_77_78_79_VAL,
+	}, {
+		.reg = IP_SEL_PAD_80_89_REG,
+		.mask = PMX_PL_80_TO_85_MASK,
+		.val = PMX_SPP_PL_80_TO_85_VAL,
+	},
+};
+
+static struct spear_modemux spp_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = spp_muxreg,
+		.nmuxregs = ARRAY_SIZE(spp_muxreg),
+	},
+};
+
+static struct spear_pingroup spp_pingroup = {
+	.name = "spp_grp",
+	.pins = spp_pins,
+	.npins = ARRAY_SIZE(spp_pins),
+	.modemuxs = spp_modemux,
+	.nmodemuxs = ARRAY_SIZE(spp_modemux),
+};
+
+static const char *const spp_grps[] = { "spp_grp" };
+static struct spear_function spp_function = {
+	.name = "spp",
+	.groups = spp_grps,
+	.ngroups = ARRAY_SIZE(spp_grps),
+};
+
+/* Pad multiplexing for SDHCI device */
+static const unsigned sdhci_led_pins[] = { 34 };
+static struct spear_muxreg sdhci_led_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_CS_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg sdhci_led_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_34_MASK,
+		.val = PMX_PWM2_PL_34_VAL,
+	},
+};
+
+static struct spear_modemux sdhci_led_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+		.muxregs = sdhci_led_muxreg,
+		.nmuxregs = ARRAY_SIZE(sdhci_led_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = sdhci_led_ext_muxreg,
+		.nmuxregs = ARRAY_SIZE(sdhci_led_ext_muxreg),
+	},
+};
+
+static struct spear_pingroup sdhci_led_pingroup = {
+	.name = "sdhci_led_grp",
+	.pins = sdhci_led_pins,
+	.npins = ARRAY_SIZE(sdhci_led_pins),
+	.modemuxs = sdhci_led_modemux,
+	.nmodemuxs = ARRAY_SIZE(sdhci_led_modemux),
+};
+
+static const unsigned sdhci_cd_12_pins[] = { 12, 43, 44, 45, 46, 47, 48, 49,
+	50};
+static const unsigned sdhci_cd_51_pins[] = { 43, 44, 45, 46, 47, 48, 49, 50, 51
+};
+static struct spear_muxreg sdhci_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg sdhci_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_43_MASK | PMX_PL_44_45_MASK | PMX_PL_46_47_MASK |
+			PMX_PL_48_49_MASK,
+		.val = PMX_SDHCI_PL_43_VAL | PMX_SDHCI_PL_44_45_VAL |
+			PMX_SDHCI_PL_46_47_VAL | PMX_SDHCI_PL_48_49_VAL,
+	}, {
+		.reg = IP_SEL_PAD_50_59_REG,
+		.mask = PMX_PL_50_MASK,
+		.val = PMX_SDHCI_PL_50_VAL,
+	}, {
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_99_MASK,
+		.val = PMX_SDHCI_PL_99_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_PL_100_101_MASK,
+		.val = PMX_SDHCI_PL_100_101_VAL,
+	},
+};
+
+static struct spear_muxreg sdhci_cd_12_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_12_MASK,
+		.val = PMX_SDHCI_CD_PL_12_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SDHCI_CD_PORT_SEL_MASK,
+		.val = PMX_SDHCI_CD_PORT_12_VAL,
+	},
+};
+
+static struct spear_muxreg sdhci_cd_51_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_50_59_REG,
+		.mask = PMX_PL_51_MASK,
+		.val = PMX_SDHCI_CD_PL_51_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SDHCI_CD_PORT_SEL_MASK,
+		.val = PMX_SDHCI_CD_PORT_51_VAL,
+	},
+};
+
+#define pmx_sdhci_common_modemux					\
+	{								\
+		.modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE |	\
+			SMALL_PRINTERS_MODE | EXTENDED_MODE,		\
+		.muxregs = sdhci_muxreg,				\
+		.nmuxregs = ARRAY_SIZE(sdhci_muxreg),			\
+	}, {								\
+		.modes = EXTENDED_MODE,					\
+		.muxregs = sdhci_ext_muxreg,				\
+		.nmuxregs = ARRAY_SIZE(sdhci_ext_muxreg),		\
+	}
+
+static struct spear_modemux sdhci_modemux[][3] = {
+	{
+		/* select pin 12 for cd */
+		pmx_sdhci_common_modemux,
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = sdhci_cd_12_muxreg,
+			.nmuxregs = ARRAY_SIZE(sdhci_cd_12_muxreg),
+		},
+	}, {
+		/* select pin 51 for cd */
+		pmx_sdhci_common_modemux,
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = sdhci_cd_51_muxreg,
+			.nmuxregs = ARRAY_SIZE(sdhci_cd_51_muxreg),
+		},
+	}
+};
+
+static struct spear_pingroup sdhci_pingroup[] = {
+	{
+		.name = "sdhci_cd_12_grp",
+		.pins = sdhci_cd_12_pins,
+		.npins = ARRAY_SIZE(sdhci_cd_12_pins),
+		.modemuxs = sdhci_modemux[0],
+		.nmodemuxs = ARRAY_SIZE(sdhci_modemux[0]),
+	}, {
+		.name = "sdhci_cd_51_grp",
+		.pins = sdhci_cd_51_pins,
+		.npins = ARRAY_SIZE(sdhci_cd_51_pins),
+		.modemuxs = sdhci_modemux[1],
+		.nmodemuxs = ARRAY_SIZE(sdhci_modemux[1]),
+	},
+};
+
+static const char *const sdhci_grps[] = { "sdhci_cd_12_grp", "sdhci_cd_51_grp",
+	"sdhci_led_grp" };
+
+static struct spear_function sdhci_function = {
+	.name = "sdhci",
+	.groups = sdhci_grps,
+	.ngroups = ARRAY_SIZE(sdhci_grps),
+};
+
+/* Pad multiplexing for I2S device */
+static const unsigned i2s_pins[] = { 35, 39, 40, 41, 42 };
+static struct spear_muxreg i2s_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_CS_MASK,
+		.val = 0,
+	}, {
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg i2s_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_35_MASK | PMX_PL_39_MASK,
+		.val = PMX_I2S_REF_CLK_PL_35_VAL | PMX_I2S_PL_39_VAL,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_40_MASK | PMX_PL_41_42_MASK,
+		.val = PMX_I2S_PL_40_VAL | PMX_I2S_PL_41_42_VAL,
+	},
+};
+
+static struct spear_modemux i2s_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+		.muxregs = i2s_muxreg,
+		.nmuxregs = ARRAY_SIZE(i2s_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = i2s_ext_muxreg,
+		.nmuxregs = ARRAY_SIZE(i2s_ext_muxreg),
+	},
+};
+
+static struct spear_pingroup i2s_pingroup = {
+	.name = "i2s_grp",
+	.pins = i2s_pins,
+	.npins = ARRAY_SIZE(i2s_pins),
+	.modemuxs = i2s_modemux,
+	.nmodemuxs = ARRAY_SIZE(i2s_modemux),
+};
+
+static const char *const i2s_grps[] = { "i2s_grp" };
+static struct spear_function i2s_function = {
+	.name = "i2s",
+	.groups = i2s_grps,
+	.ngroups = ARRAY_SIZE(i2s_grps),
+};
+
+/* Pad multiplexing for UART1 device */
+static const unsigned uart1_pins[] = { 28, 29 };
+static struct spear_muxreg uart1_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg uart1_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_20_29_REG,
+		.mask = PMX_PL_28_29_MASK,
+		.val = PMX_UART1_PL_28_29_VAL,
+	},
+};
+
+static struct spear_modemux uart1_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+			| SMALL_PRINTERS_MODE | EXTENDED_MODE,
+		.muxregs = uart1_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart1_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = uart1_ext_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart1_ext_muxreg),
+	},
+};
+
+static struct spear_pingroup uart1_pingroup = {
+	.name = "uart1_grp",
+	.pins = uart1_pins,
+	.npins = ARRAY_SIZE(uart1_pins),
+	.modemuxs = uart1_modemux,
+	.nmodemuxs = ARRAY_SIZE(uart1_modemux),
+};
+
+static const char *const uart1_grps[] = { "uart1_grp" };
+static struct spear_function uart1_function = {
+	.name = "uart1",
+	.groups = uart1_grps,
+	.ngroups = ARRAY_SIZE(uart1_grps),
+};
+
+/* Pad multiplexing for UART1 Modem device */
+static const unsigned uart1_modem_2_to_7_pins[] = { 2, 3, 4, 5, 6, 7 };
+static const unsigned uart1_modem_31_to_36_pins[] = { 31, 32, 33, 34, 35, 36 };
+static const unsigned uart1_modem_34_to_45_pins[] = { 34, 35, 36, 43, 44, 45 };
+static const unsigned uart1_modem_80_to_85_pins[] = { 80, 81, 82, 83, 84, 85 };
+
+static struct spear_muxreg uart1_modem_ext_2_to_7_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MASK | PMX_I2C_MASK | PMX_SSP_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_2_3_MASK | PMX_PL_6_7_MASK,
+		.val = PMX_UART1_ENH_PL_2_3_VAL | PMX_UART1_ENH_PL_4_5_VAL |
+			PMX_UART1_ENH_PL_6_7_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART1_ENH_PORT_SEL_MASK,
+		.val = PMX_UART1_ENH_PORT_3_TO_5_7_VAL,
+	},
+};
+
+static struct spear_muxreg uart1_modem_31_to_36_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
+			PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg uart1_modem_ext_31_to_36_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_31_MASK | PMX_PL_32_33_MASK | PMX_PL_34_MASK |
+			PMX_PL_35_MASK | PMX_PL_36_MASK,
+		.val = PMX_UART1_ENH_PL_31_VAL | PMX_UART1_ENH_PL_32_33_VAL |
+			PMX_UART1_ENH_PL_34_VAL | PMX_UART1_ENH_PL_35_VAL |
+			PMX_UART1_ENH_PL_36_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART1_ENH_PORT_SEL_MASK,
+		.val = PMX_UART1_ENH_PORT_32_TO_34_36_VAL,
+	},
+};
+
+static struct spear_muxreg uart1_modem_34_to_45_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK |
+			PMX_SSP_CS_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg uart1_modem_ext_34_to_45_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_34_MASK | PMX_PL_35_MASK | PMX_PL_36_MASK,
+		.val = PMX_UART1_ENH_PL_34_VAL | PMX_UART1_ENH_PL_35_VAL |
+			PMX_UART1_ENH_PL_36_VAL,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_43_MASK | PMX_PL_44_45_MASK,
+		.val = PMX_UART1_ENH_PL_43_VAL | PMX_UART1_ENH_PL_44_45_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART1_ENH_PORT_SEL_MASK,
+		.val = PMX_UART1_ENH_PORT_44_45_34_36_VAL,
+	},
+};
+
+static struct spear_muxreg uart1_modem_ext_80_to_85_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_80_89_REG,
+		.mask = PMX_PL_80_TO_85_MASK,
+		.val = PMX_UART1_ENH_PL_80_TO_85_VAL,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_43_MASK | PMX_PL_44_45_MASK,
+		.val = PMX_UART1_ENH_PL_43_VAL | PMX_UART1_ENH_PL_44_45_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART1_ENH_PORT_SEL_MASK,
+		.val = PMX_UART1_ENH_PORT_81_TO_85_VAL,
+	},
+};
+
+static struct spear_modemux uart1_modem_2_to_7_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = uart1_modem_ext_2_to_7_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart1_modem_ext_2_to_7_muxreg),
+	},
+};
+
+static struct spear_modemux uart1_modem_31_to_36_modemux[] = {
+	{
+		.modes = SMALL_PRINTERS_MODE | EXTENDED_MODE,
+		.muxregs = uart1_modem_31_to_36_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart1_modem_31_to_36_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = uart1_modem_ext_31_to_36_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart1_modem_ext_31_to_36_muxreg),
+	},
+};
+
+static struct spear_modemux uart1_modem_34_to_45_modemux[] = {
+	{
+		.modes = AUTO_EXP_MODE | EXTENDED_MODE,
+		.muxregs = uart1_modem_34_to_45_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart1_modem_34_to_45_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = uart1_modem_ext_34_to_45_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart1_modem_ext_34_to_45_muxreg),
+	},
+};
+
+static struct spear_modemux uart1_modem_80_to_85_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = uart1_modem_ext_80_to_85_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart1_modem_ext_80_to_85_muxreg),
+	},
+};
+
+static struct spear_pingroup uart1_modem_pingroup[] = {
+	{
+		.name = "uart1_modem_2_to_7_grp",
+		.pins = uart1_modem_2_to_7_pins,
+		.npins = ARRAY_SIZE(uart1_modem_2_to_7_pins),
+		.modemuxs = uart1_modem_2_to_7_modemux,
+		.nmodemuxs = ARRAY_SIZE(uart1_modem_2_to_7_modemux),
+	}, {
+		.name = "uart1_modem_31_to_36_grp",
+		.pins = uart1_modem_31_to_36_pins,
+		.npins = ARRAY_SIZE(uart1_modem_31_to_36_pins),
+		.modemuxs = uart1_modem_31_to_36_modemux,
+		.nmodemuxs = ARRAY_SIZE(uart1_modem_31_to_36_modemux),
+	}, {
+		.name = "uart1_modem_34_to_45_grp",
+		.pins = uart1_modem_34_to_45_pins,
+		.npins = ARRAY_SIZE(uart1_modem_34_to_45_pins),
+		.modemuxs = uart1_modem_34_to_45_modemux,
+		.nmodemuxs = ARRAY_SIZE(uart1_modem_34_to_45_modemux),
+	}, {
+		.name = "uart1_modem_80_to_85_grp",
+		.pins = uart1_modem_80_to_85_pins,
+		.npins = ARRAY_SIZE(uart1_modem_80_to_85_pins),
+		.modemuxs = uart1_modem_80_to_85_modemux,
+		.nmodemuxs = ARRAY_SIZE(uart1_modem_80_to_85_modemux),
+	},
+};
+
+static const char *const uart1_modem_grps[] = { "uart1_modem_2_to_7_grp",
+	"uart1_modem_31_to_36_grp", "uart1_modem_34_to_45_grp",
+	"uart1_modem_80_to_85_grp" };
+static struct spear_function uart1_modem_function = {
+	.name = "uart1_modem",
+	.groups = uart1_modem_grps,
+	.ngroups = ARRAY_SIZE(uart1_modem_grps),
+};
+
+/* Pad multiplexing for UART2 device */
+static const unsigned uart2_pins[] = { 0, 1 };
+static struct spear_muxreg uart2_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_FIRDA_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg uart2_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_0_1_MASK,
+		.val = PMX_UART2_PL_0_1_VAL,
+	},
+};
+
+static struct spear_modemux uart2_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+			| SMALL_PRINTERS_MODE | EXTENDED_MODE,
+		.muxregs = uart2_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart2_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = uart2_ext_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart2_ext_muxreg),
+	},
+};
+
+static struct spear_pingroup uart2_pingroup = {
+	.name = "uart2_grp",
+	.pins = uart2_pins,
+	.npins = ARRAY_SIZE(uart2_pins),
+	.modemuxs = uart2_modemux,
+	.nmodemuxs = ARRAY_SIZE(uart2_modemux),
+};
+
+static const char *const uart2_grps[] = { "uart2_grp" };
+static struct spear_function uart2_function = {
+	.name = "uart2",
+	.groups = uart2_grps,
+	.ngroups = ARRAY_SIZE(uart2_grps),
+};
+
+/* Pad multiplexing for uart3 device */
+static const unsigned uart3_pins[][2] = { { 8, 9 }, { 15, 16 }, { 41, 42 },
+	{ 52, 53 }, { 73, 74 }, { 94, 95 }, { 98, 99 } };
+
+static struct spear_muxreg uart3_ext_8_9_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_8_9_MASK,
+		.val = PMX_UART3_PL_8_9_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART3_PORT_SEL_MASK,
+		.val = PMX_UART3_PORT_8_VAL,
+	},
+};
+
+static struct spear_muxreg uart3_ext_15_16_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_15_16_MASK,
+		.val = PMX_UART3_PL_15_16_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART3_PORT_SEL_MASK,
+		.val = PMX_UART3_PORT_15_VAL,
+	},
+};
+
+static struct spear_muxreg uart3_ext_41_42_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_41_42_MASK,
+		.val = PMX_UART3_PL_41_42_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART3_PORT_SEL_MASK,
+		.val = PMX_UART3_PORT_41_VAL,
+	},
+};
+
+static struct spear_muxreg uart3_ext_52_53_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_50_59_REG,
+		.mask = PMX_PL_52_53_MASK,
+		.val = PMX_UART3_PL_52_53_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART3_PORT_SEL_MASK,
+		.val = PMX_UART3_PORT_52_VAL,
+	},
+};
+
+static struct spear_muxreg uart3_ext_73_74_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_70_79_REG,
+		.mask = PMX_PL_73_MASK | PMX_PL_74_MASK,
+		.val = PMX_UART3_PL_73_VAL | PMX_UART3_PL_74_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART3_PORT_SEL_MASK,
+		.val = PMX_UART3_PORT_73_VAL,
+	},
+};
+
+static struct spear_muxreg uart3_ext_94_95_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_94_95_MASK,
+		.val = PMX_UART3_PL_94_95_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART3_PORT_SEL_MASK,
+		.val = PMX_UART3_PORT_94_VAL,
+	},
+};
+
+static struct spear_muxreg uart3_ext_98_99_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_98_MASK | PMX_PL_99_MASK,
+		.val = PMX_UART3_PL_98_VAL | PMX_UART3_PL_99_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART3_PORT_SEL_MASK,
+		.val = PMX_UART3_PORT_99_VAL,
+	},
+};
+
+static struct spear_modemux uart3_modemux[][1] = {
+	{
+		/* Select signals on pins 8_9 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart3_ext_8_9_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart3_ext_8_9_muxreg),
+		},
+	}, {
+		/* Select signals on pins 15_16 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart3_ext_15_16_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart3_ext_15_16_muxreg),
+		},
+	}, {
+		/* Select signals on pins 41_42 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart3_ext_41_42_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart3_ext_41_42_muxreg),
+		},
+	}, {
+		/* Select signals on pins 52_53 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart3_ext_52_53_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart3_ext_52_53_muxreg),
+		},
+	}, {
+		/* Select signals on pins 73_74 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart3_ext_73_74_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart3_ext_73_74_muxreg),
+		},
+	}, {
+		/* Select signals on pins 94_95 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart3_ext_94_95_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart3_ext_94_95_muxreg),
+		},
+	}, {
+		/* Select signals on pins 98_99 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart3_ext_98_99_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart3_ext_98_99_muxreg),
+		},
+	},
+};
+
+static struct spear_pingroup uart3_pingroup[] = {
+	{
+		.name = "uart3_8_9_grp",
+		.pins = uart3_pins[0],
+		.npins = ARRAY_SIZE(uart3_pins[0]),
+		.modemuxs = uart3_modemux[0],
+		.nmodemuxs = ARRAY_SIZE(uart3_modemux[0]),
+	}, {
+		.name = "uart3_15_16_grp",
+		.pins = uart3_pins[1],
+		.npins = ARRAY_SIZE(uart3_pins[1]),
+		.modemuxs = uart3_modemux[1],
+		.nmodemuxs = ARRAY_SIZE(uart3_modemux[1]),
+	}, {
+		.name = "uart3_41_42_grp",
+		.pins = uart3_pins[2],
+		.npins = ARRAY_SIZE(uart3_pins[2]),
+		.modemuxs = uart3_modemux[2],
+		.nmodemuxs = ARRAY_SIZE(uart3_modemux[2]),
+	}, {
+		.name = "uart3_52_53_grp",
+		.pins = uart3_pins[3],
+		.npins = ARRAY_SIZE(uart3_pins[3]),
+		.modemuxs = uart3_modemux[3],
+		.nmodemuxs = ARRAY_SIZE(uart3_modemux[3]),
+	}, {
+		.name = "uart3_73_74_grp",
+		.pins = uart3_pins[4],
+		.npins = ARRAY_SIZE(uart3_pins[4]),
+		.modemuxs = uart3_modemux[4],
+		.nmodemuxs = ARRAY_SIZE(uart3_modemux[4]),
+	}, {
+		.name = "uart3_94_95_grp",
+		.pins = uart3_pins[5],
+		.npins = ARRAY_SIZE(uart3_pins[5]),
+		.modemuxs = uart3_modemux[5],
+		.nmodemuxs = ARRAY_SIZE(uart3_modemux[5]),
+	}, {
+		.name = "uart3_98_99_grp",
+		.pins = uart3_pins[6],
+		.npins = ARRAY_SIZE(uart3_pins[6]),
+		.modemuxs = uart3_modemux[6],
+		.nmodemuxs = ARRAY_SIZE(uart3_modemux[6]),
+	},
+};
+
+static const char *const uart3_grps[] = { "uart3_8_9_grp", "uart3_15_16_grp",
+	"uart3_41_42_grp", "uart3_52_53_grp", "uart3_73_74_grp",
+	"uart3_94_95_grp", "uart3_98_99_grp" };
+
+static struct spear_function uart3_function = {
+	.name = "uart3",
+	.groups = uart3_grps,
+	.ngroups = ARRAY_SIZE(uart3_grps),
+};
+
+/* Pad multiplexing for uart4 device */
+static const unsigned uart4_pins[][2] = { { 6, 7 }, { 13, 14 }, { 39, 40 },
+	{ 71, 72 }, { 92, 93 }, { 100, 101 } };
+
+static struct spear_muxreg uart4_ext_6_7_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_6_7_MASK,
+		.val = PMX_UART4_PL_6_7_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART4_PORT_SEL_MASK,
+		.val = PMX_UART4_PORT_6_VAL,
+	},
+};
+
+static struct spear_muxreg uart4_ext_13_14_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_13_14_MASK,
+		.val = PMX_UART4_PL_13_14_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART4_PORT_SEL_MASK,
+		.val = PMX_UART4_PORT_13_VAL,
+	},
+};
+
+static struct spear_muxreg uart4_ext_39_40_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_39_MASK,
+		.val = PMX_UART4_PL_39_VAL,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_40_MASK,
+		.val = PMX_UART4_PL_40_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART4_PORT_SEL_MASK,
+		.val = PMX_UART4_PORT_39_VAL,
+	},
+};
+
+static struct spear_muxreg uart4_ext_71_72_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_70_79_REG,
+		.mask = PMX_PL_71_72_MASK,
+		.val = PMX_UART4_PL_71_72_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART4_PORT_SEL_MASK,
+		.val = PMX_UART4_PORT_71_VAL,
+	},
+};
+
+static struct spear_muxreg uart4_ext_92_93_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_92_93_MASK,
+		.val = PMX_UART4_PL_92_93_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART4_PORT_SEL_MASK,
+		.val = PMX_UART4_PORT_92_VAL,
+	},
+};
+
+static struct spear_muxreg uart4_ext_100_101_muxreg[] = {
+	{
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_PL_100_101_MASK |
+			PMX_UART4_PORT_SEL_MASK,
+		.val = PMX_UART4_PL_100_101_VAL |
+			PMX_UART4_PORT_101_VAL,
+	},
+};
+
+static struct spear_modemux uart4_modemux[][1] = {
+	{
+		/* Select signals on pins 6_7 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart4_ext_6_7_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart4_ext_6_7_muxreg),
+		},
+	}, {
+		/* Select signals on pins 13_14 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart4_ext_13_14_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart4_ext_13_14_muxreg),
+		},
+	}, {
+		/* Select signals on pins 39_40 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart4_ext_39_40_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart4_ext_39_40_muxreg),
+		},
+	}, {
+		/* Select signals on pins 71_72 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart4_ext_71_72_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart4_ext_71_72_muxreg),
+		},
+	}, {
+		/* Select signals on pins 92_93 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart4_ext_92_93_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart4_ext_92_93_muxreg),
+		},
+	}, {
+		/* Select signals on pins 100_101_ */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart4_ext_100_101_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart4_ext_100_101_muxreg),
+		},
+	},
+};
+
+static struct spear_pingroup uart4_pingroup[] = {
+	{
+		.name = "uart4_6_7_grp",
+		.pins = uart4_pins[0],
+		.npins = ARRAY_SIZE(uart4_pins[0]),
+		.modemuxs = uart4_modemux[0],
+		.nmodemuxs = ARRAY_SIZE(uart4_modemux[0]),
+	}, {
+		.name = "uart4_13_14_grp",
+		.pins = uart4_pins[1],
+		.npins = ARRAY_SIZE(uart4_pins[1]),
+		.modemuxs = uart4_modemux[1],
+		.nmodemuxs = ARRAY_SIZE(uart4_modemux[1]),
+	}, {
+		.name = "uart4_39_40_grp",
+		.pins = uart4_pins[2],
+		.npins = ARRAY_SIZE(uart4_pins[2]),
+		.modemuxs = uart4_modemux[2],
+		.nmodemuxs = ARRAY_SIZE(uart4_modemux[2]),
+	}, {
+		.name = "uart4_71_72_grp",
+		.pins = uart4_pins[3],
+		.npins = ARRAY_SIZE(uart4_pins[3]),
+		.modemuxs = uart4_modemux[3],
+		.nmodemuxs = ARRAY_SIZE(uart4_modemux[3]),
+	}, {
+		.name = "uart4_92_93_grp",
+		.pins = uart4_pins[4],
+		.npins = ARRAY_SIZE(uart4_pins[4]),
+		.modemuxs = uart4_modemux[4],
+		.nmodemuxs = ARRAY_SIZE(uart4_modemux[4]),
+	}, {
+		.name = "uart4_100_101_grp",
+		.pins = uart4_pins[5],
+		.npins = ARRAY_SIZE(uart4_pins[5]),
+		.modemuxs = uart4_modemux[5],
+		.nmodemuxs = ARRAY_SIZE(uart4_modemux[5]),
+	},
+};
+
+static const char *const uart4_grps[] = { "uart4_6_7_grp", "uart4_13_14_grp",
+	"uart4_39_40_grp", "uart4_71_72_grp", "uart4_92_93_grp",
+	"uart4_100_101_grp" };
+
+static struct spear_function uart4_function = {
+	.name = "uart4",
+	.groups = uart4_grps,
+	.ngroups = ARRAY_SIZE(uart4_grps),
+};
+
+/* Pad multiplexing for uart5 device */
+static const unsigned uart5_pins[][2] = { { 4, 5 }, { 37, 38 }, { 69, 70 },
+	{ 90, 91 } };
+
+static struct spear_muxreg uart5_ext_4_5_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_I2C_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_4_5_MASK,
+		.val = PMX_UART5_PL_4_5_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART5_PORT_SEL_MASK,
+		.val = PMX_UART5_PORT_4_VAL,
+	},
+};
+
+static struct spear_muxreg uart5_ext_37_38_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_37_38_MASK,
+		.val = PMX_UART5_PL_37_38_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART5_PORT_SEL_MASK,
+		.val = PMX_UART5_PORT_37_VAL,
+	},
+};
+
+static struct spear_muxreg uart5_ext_69_70_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_60_69_REG,
+		.mask = PMX_PL_69_MASK,
+		.val = PMX_UART5_PL_69_VAL,
+	}, {
+		.reg = IP_SEL_PAD_70_79_REG,
+		.mask = PMX_PL_70_MASK,
+		.val = PMX_UART5_PL_70_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART5_PORT_SEL_MASK,
+		.val = PMX_UART5_PORT_69_VAL,
+	},
+};
+
+static struct spear_muxreg uart5_ext_90_91_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_90_91_MASK,
+		.val = PMX_UART5_PL_90_91_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART5_PORT_SEL_MASK,
+		.val = PMX_UART5_PORT_90_VAL,
+	},
+};
+
+static struct spear_modemux uart5_modemux[][1] = {
+	{
+		/* Select signals on pins 4_5 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart5_ext_4_5_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart5_ext_4_5_muxreg),
+		},
+	}, {
+		/* Select signals on pins 37_38 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart5_ext_37_38_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart5_ext_37_38_muxreg),
+		},
+	}, {
+		/* Select signals on pins 69_70 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart5_ext_69_70_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart5_ext_69_70_muxreg),
+		},
+	}, {
+		/* Select signals on pins 90_91 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart5_ext_90_91_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart5_ext_90_91_muxreg),
+		},
+	},
+};
+
+static struct spear_pingroup uart5_pingroup[] = {
+	{
+		.name = "uart5_4_5_grp",
+		.pins = uart5_pins[0],
+		.npins = ARRAY_SIZE(uart5_pins[0]),
+		.modemuxs = uart5_modemux[0],
+		.nmodemuxs = ARRAY_SIZE(uart5_modemux[0]),
+	}, {
+		.name = "uart5_37_38_grp",
+		.pins = uart5_pins[1],
+		.npins = ARRAY_SIZE(uart5_pins[1]),
+		.modemuxs = uart5_modemux[1],
+		.nmodemuxs = ARRAY_SIZE(uart5_modemux[1]),
+	}, {
+		.name = "uart5_69_70_grp",
+		.pins = uart5_pins[2],
+		.npins = ARRAY_SIZE(uart5_pins[2]),
+		.modemuxs = uart5_modemux[2],
+		.nmodemuxs = ARRAY_SIZE(uart5_modemux[2]),
+	}, {
+		.name = "uart5_90_91_grp",
+		.pins = uart5_pins[3],
+		.npins = ARRAY_SIZE(uart5_pins[3]),
+		.modemuxs = uart5_modemux[3],
+		.nmodemuxs = ARRAY_SIZE(uart5_modemux[3]),
+	},
+};
+
+static const char *const uart5_grps[] = { "uart5_4_5_grp", "uart5_37_38_grp",
+	"uart5_69_70_grp", "uart5_90_91_grp" };
+static struct spear_function uart5_function = {
+	.name = "uart5",
+	.groups = uart5_grps,
+	.ngroups = ARRAY_SIZE(uart5_grps),
+};
+
+/* Pad multiplexing for uart6 device */
+static const unsigned uart6_pins[][2] = { { 2, 3 }, { 88, 89 } };
+static struct spear_muxreg uart6_ext_2_3_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_2_3_MASK,
+		.val = PMX_UART6_PL_2_3_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART6_PORT_SEL_MASK,
+		.val = PMX_UART6_PORT_2_VAL,
+	},
+};
+
+static struct spear_muxreg uart6_ext_88_89_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_80_89_REG,
+		.mask = PMX_PL_88_89_MASK,
+		.val = PMX_UART6_PL_88_89_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_UART6_PORT_SEL_MASK,
+		.val = PMX_UART6_PORT_88_VAL,
+	},
+};
+
+static struct spear_modemux uart6_modemux[][1] = {
+	{
+		/* Select signals on pins 2_3 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart6_ext_2_3_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart6_ext_2_3_muxreg),
+		},
+	}, {
+		/* Select signals on pins 88_89 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = uart6_ext_88_89_muxreg,
+			.nmuxregs = ARRAY_SIZE(uart6_ext_88_89_muxreg),
+		},
+	},
+};
+
+static struct spear_pingroup uart6_pingroup[] = {
+	{
+		.name = "uart6_2_3_grp",
+		.pins = uart6_pins[0],
+		.npins = ARRAY_SIZE(uart6_pins[0]),
+		.modemuxs = uart6_modemux[0],
+		.nmodemuxs = ARRAY_SIZE(uart6_modemux[0]),
+	}, {
+		.name = "uart6_88_89_grp",
+		.pins = uart6_pins[1],
+		.npins = ARRAY_SIZE(uart6_pins[1]),
+		.modemuxs = uart6_modemux[1],
+		.nmodemuxs = ARRAY_SIZE(uart6_modemux[1]),
+	},
+};
+
+static const char *const uart6_grps[] = { "uart6_2_3_grp", "uart6_88_89_grp" };
+static struct spear_function uart6_function = {
+	.name = "uart6",
+	.groups = uart6_grps,
+	.ngroups = ARRAY_SIZE(uart6_grps),
+};
+
+/* UART - RS485 pmx */
+static const unsigned rs485_pins[] = { 77, 78, 79 };
+static struct spear_muxreg rs485_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_70_79_REG,
+		.mask = PMX_PL_77_78_79_MASK,
+		.val = PMX_RS485_PL_77_78_79_VAL,
+	},
+};
+
+static struct spear_modemux rs485_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = rs485_muxreg,
+		.nmuxregs = ARRAY_SIZE(rs485_muxreg),
+	},
+};
+
+static struct spear_pingroup rs485_pingroup = {
+	.name = "rs485_grp",
+	.pins = rs485_pins,
+	.npins = ARRAY_SIZE(rs485_pins),
+	.modemuxs = rs485_modemux,
+	.nmodemuxs = ARRAY_SIZE(rs485_modemux),
+};
+
+static const char *const rs485_grps[] = { "rs485_grp" };
+static struct spear_function rs485_function = {
+	.name = "rs485",
+	.groups = rs485_grps,
+	.ngroups = ARRAY_SIZE(rs485_grps),
+};
+
+/* Pad multiplexing for Touchscreen device */
+static const unsigned touchscreen_pins[] = { 5, 36 };
+static struct spear_muxreg touchscreen_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_I2C_MASK | PMX_SSP_CS_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg touchscreen_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_5_MASK,
+		.val = PMX_TOUCH_Y_PL_5_VAL,
+	}, {
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_36_MASK,
+		.val = PMX_TOUCH_X_PL_36_VAL,
+	},
+};
+
+static struct spear_modemux touchscreen_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | EXTENDED_MODE,
+		.muxregs = touchscreen_muxreg,
+		.nmuxregs = ARRAY_SIZE(touchscreen_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = touchscreen_ext_muxreg,
+		.nmuxregs = ARRAY_SIZE(touchscreen_ext_muxreg),
+	},
+};
+
+static struct spear_pingroup touchscreen_pingroup = {
+	.name = "touchscreen_grp",
+	.pins = touchscreen_pins,
+	.npins = ARRAY_SIZE(touchscreen_pins),
+	.modemuxs = touchscreen_modemux,
+	.nmodemuxs = ARRAY_SIZE(touchscreen_modemux),
+};
+
+static const char *const touchscreen_grps[] = { "touchscreen_grp" };
+static struct spear_function touchscreen_function = {
+	.name = "touchscreen",
+	.groups = touchscreen_grps,
+	.ngroups = ARRAY_SIZE(touchscreen_grps),
+};
+
+/* Pad multiplexing for CAN device */
+static const unsigned can0_pins[] = { 32, 33 };
+static struct spear_muxreg can0_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg can0_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_32_33_MASK,
+		.val = PMX_CAN0_PL_32_33_VAL,
+	},
+};
+
+static struct spear_modemux can0_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+			| EXTENDED_MODE,
+		.muxregs = can0_muxreg,
+		.nmuxregs = ARRAY_SIZE(can0_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = can0_ext_muxreg,
+		.nmuxregs = ARRAY_SIZE(can0_ext_muxreg),
+	},
+};
+
+static struct spear_pingroup can0_pingroup = {
+	.name = "can0_grp",
+	.pins = can0_pins,
+	.npins = ARRAY_SIZE(can0_pins),
+	.modemuxs = can0_modemux,
+	.nmodemuxs = ARRAY_SIZE(can0_modemux),
+};
+
+static const char *const can0_grps[] = { "can0_grp" };
+static struct spear_function can0_function = {
+	.name = "can0",
+	.groups = can0_grps,
+	.ngroups = ARRAY_SIZE(can0_grps),
+};
+
+static const unsigned can1_pins[] = { 30, 31 };
+static struct spear_muxreg can1_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg can1_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_30_31_MASK,
+		.val = PMX_CAN1_PL_30_31_VAL,
+	},
+};
+
+static struct spear_modemux can1_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+			| EXTENDED_MODE,
+		.muxregs = can1_muxreg,
+		.nmuxregs = ARRAY_SIZE(can1_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = can1_ext_muxreg,
+		.nmuxregs = ARRAY_SIZE(can1_ext_muxreg),
+	},
+};
+
+static struct spear_pingroup can1_pingroup = {
+	.name = "can1_grp",
+	.pins = can1_pins,
+	.npins = ARRAY_SIZE(can1_pins),
+	.modemuxs = can1_modemux,
+	.nmodemuxs = ARRAY_SIZE(can1_modemux),
+};
+
+static const char *const can1_grps[] = { "can1_grp" };
+static struct spear_function can1_function = {
+	.name = "can1",
+	.groups = can1_grps,
+	.ngroups = ARRAY_SIZE(can1_grps),
+};
+
+/* Pad multiplexing for PWM0_1 device */
+static const unsigned pwm0_1_pins[][2] = { { 37, 38 }, { 14, 15 }, { 8, 9 },
+	{ 30, 31 }, { 42, 43 }, { 59, 60 }, { 88, 89 } };
+
+static struct spear_muxreg pwm0_1_pin_8_9_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_8_9_MASK,
+		.val = PMX_PWM_0_1_PL_8_9_VAL,
+	},
+};
+
+static struct spear_muxreg pwm0_1_autoexpsmallpri_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg pwm0_1_pin_14_15_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_14_MASK | PMX_PL_15_MASK,
+		.val = PMX_PWM1_PL_14_VAL | PMX_PWM0_PL_15_VAL,
+	},
+};
+
+static struct spear_muxreg pwm0_1_pin_30_31_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_30_MASK | PMX_PL_31_MASK,
+		.val = PMX_PWM1_EXT_PL_30_VAL | PMX_PWM0_EXT_PL_31_VAL,
+	},
+};
+
+static struct spear_muxreg pwm0_1_net_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg pwm0_1_pin_37_38_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_37_38_MASK,
+		.val = PMX_PWM0_1_PL_37_38_VAL,
+	},
+};
+
+static struct spear_muxreg pwm0_1_pin_42_43_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_0_1_MASK ,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_42_MASK | PMX_PL_43_MASK,
+		.val = PMX_PWM1_PL_42_VAL |
+			PMX_PWM0_PL_43_VAL,
+	},
+};
+
+static struct spear_muxreg pwm0_1_pin_59_60_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_50_59_REG,
+		.mask = PMX_PL_59_MASK,
+		.val = PMX_PWM1_PL_59_VAL,
+	}, {
+		.reg = IP_SEL_PAD_60_69_REG,
+		.mask = PMX_PL_60_MASK,
+		.val = PMX_PWM0_PL_60_VAL,
+	},
+};
+
+static struct spear_muxreg pwm0_1_pin_88_89_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_80_89_REG,
+		.mask = PMX_PL_88_89_MASK,
+		.val = PMX_PWM0_1_PL_88_89_VAL,
+	},
+};
+
+static struct spear_modemux pwm0_1_pin_8_9_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm0_1_pin_8_9_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm0_1_pin_8_9_muxreg),
+	},
+};
+
+static struct spear_modemux pwm0_1_pin_14_15_modemux[] = {
+	{
+		.modes = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+		.muxregs = pwm0_1_autoexpsmallpri_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm0_1_autoexpsmallpri_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm0_1_pin_14_15_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm0_1_pin_14_15_muxreg),
+	},
+};
+
+static struct spear_modemux pwm0_1_pin_30_31_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm0_1_pin_30_31_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm0_1_pin_30_31_muxreg),
+	},
+};
+
+static struct spear_modemux pwm0_1_pin_37_38_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+		.muxregs = pwm0_1_net_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm0_1_net_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm0_1_pin_37_38_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm0_1_pin_37_38_muxreg),
+	},
+};
+
+static struct spear_modemux pwm0_1_pin_42_43_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm0_1_pin_42_43_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm0_1_pin_42_43_muxreg),
+	},
+};
+
+static struct spear_modemux pwm0_1_pin_59_60_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm0_1_pin_59_60_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm0_1_pin_59_60_muxreg),
+	},
+};
+
+static struct spear_modemux pwm0_1_pin_88_89_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm0_1_pin_88_89_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm0_1_pin_88_89_muxreg),
+	},
+};
+
+static struct spear_pingroup pwm0_1_pingroup[] = {
+	{
+		.name = "pwm0_1_pin_8_9_grp",
+		.pins = pwm0_1_pins[0],
+		.npins = ARRAY_SIZE(pwm0_1_pins[0]),
+		.modemuxs = pwm0_1_pin_8_9_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm0_1_pin_8_9_modemux),
+	}, {
+		.name = "pwm0_1_pin_14_15_grp",
+		.pins = pwm0_1_pins[1],
+		.npins = ARRAY_SIZE(pwm0_1_pins[1]),
+		.modemuxs = pwm0_1_pin_14_15_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm0_1_pin_14_15_modemux),
+	}, {
+		.name = "pwm0_1_pin_30_31_grp",
+		.pins = pwm0_1_pins[2],
+		.npins = ARRAY_SIZE(pwm0_1_pins[2]),
+		.modemuxs = pwm0_1_pin_30_31_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm0_1_pin_30_31_modemux),
+	}, {
+		.name = "pwm0_1_pin_37_38_grp",
+		.pins = pwm0_1_pins[3],
+		.npins = ARRAY_SIZE(pwm0_1_pins[3]),
+		.modemuxs = pwm0_1_pin_37_38_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm0_1_pin_37_38_modemux),
+	}, {
+		.name = "pwm0_1_pin_42_43_grp",
+		.pins = pwm0_1_pins[4],
+		.npins = ARRAY_SIZE(pwm0_1_pins[4]),
+		.modemuxs = pwm0_1_pin_42_43_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm0_1_pin_42_43_modemux),
+	}, {
+		.name = "pwm0_1_pin_59_60_grp",
+		.pins = pwm0_1_pins[5],
+		.npins = ARRAY_SIZE(pwm0_1_pins[5]),
+		.modemuxs = pwm0_1_pin_59_60_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm0_1_pin_59_60_modemux),
+	}, {
+		.name = "pwm0_1_pin_88_89_grp",
+		.pins = pwm0_1_pins[6],
+		.npins = ARRAY_SIZE(pwm0_1_pins[6]),
+		.modemuxs = pwm0_1_pin_88_89_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm0_1_pin_88_89_modemux),
+	},
+};
+
+static const char *const pwm0_1_grps[] = { "pwm0_1_pin_8_9_grp",
+	"pwm0_1_pin_14_15_grp", "pwm0_1_pin_30_31_grp", "pwm0_1_pin_37_38_grp",
+	"pwm0_1_pin_42_43_grp", "pwm0_1_pin_59_60_grp", "pwm0_1_pin_88_89_grp"
+};
+
+static struct spear_function pwm0_1_function = {
+	.name = "pwm0_1",
+	.groups = pwm0_1_grps,
+	.ngroups = ARRAY_SIZE(pwm0_1_grps),
+};
+
+/* Pad multiplexing for PWM2 device */
+static const unsigned pwm2_pins[][1] = { { 7 }, { 13 }, { 29 }, { 34 }, { 41 },
+	{ 58 }, { 87 } };
+static struct spear_muxreg pwm2_net_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_CS_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg pwm2_pin_7_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_7_MASK,
+		.val = PMX_PWM_2_PL_7_VAL,
+	},
+};
+
+static struct spear_muxreg pwm2_autoexpsmallpri_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg pwm2_pin_13_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_13_MASK,
+		.val = PMX_PWM2_PL_13_VAL,
+	},
+};
+
+static struct spear_muxreg pwm2_pin_29_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_GPIO_PIN1_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_20_29_REG,
+		.mask = PMX_PL_29_MASK,
+		.val = PMX_PWM_2_PL_29_VAL,
+	},
+};
+
+static struct spear_muxreg pwm2_pin_34_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_CS_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_34_MASK,
+		.val = PMX_PWM2_PL_34_VAL,
+	},
+};
+
+static struct spear_muxreg pwm2_pin_41_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_41_MASK,
+		.val = PMX_PWM2_PL_41_VAL,
+	},
+};
+
+static struct spear_muxreg pwm2_pin_58_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_50_59_REG,
+		.mask = PMX_PL_58_MASK,
+		.val = PMX_PWM2_PL_58_VAL,
+	},
+};
+
+static struct spear_muxreg pwm2_pin_87_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_80_89_REG,
+		.mask = PMX_PL_87_MASK,
+		.val = PMX_PWM2_PL_87_VAL,
+	},
+};
+
+static struct spear_modemux pwm2_pin_7_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+		.muxregs = pwm2_net_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm2_net_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm2_pin_7_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm2_pin_7_muxreg),
+	},
+};
+static struct spear_modemux pwm2_pin_13_modemux[] = {
+	{
+		.modes = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+		.muxregs = pwm2_autoexpsmallpri_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm2_autoexpsmallpri_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm2_pin_13_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm2_pin_13_muxreg),
+	},
+};
+static struct spear_modemux pwm2_pin_29_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm2_pin_29_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm2_pin_29_muxreg),
+	},
+};
+static struct spear_modemux pwm2_pin_34_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm2_pin_34_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm2_pin_34_muxreg),
+	},
+};
+
+static struct spear_modemux pwm2_pin_41_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm2_pin_41_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm2_pin_41_muxreg),
+	},
+};
+
+static struct spear_modemux pwm2_pin_58_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm2_pin_58_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm2_pin_58_muxreg),
+	},
+};
+
+static struct spear_modemux pwm2_pin_87_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm2_pin_87_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm2_pin_87_muxreg),
+	},
+};
+
+static struct spear_pingroup pwm2_pingroup[] = {
+	{
+		.name = "pwm2_pin_7_grp",
+		.pins = pwm2_pins[0],
+		.npins = ARRAY_SIZE(pwm2_pins[0]),
+		.modemuxs = pwm2_pin_7_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm2_pin_7_modemux),
+	}, {
+		.name = "pwm2_pin_13_grp",
+		.pins = pwm2_pins[1],
+		.npins = ARRAY_SIZE(pwm2_pins[1]),
+		.modemuxs = pwm2_pin_13_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm2_pin_13_modemux),
+	}, {
+		.name = "pwm2_pin_29_grp",
+		.pins = pwm2_pins[2],
+		.npins = ARRAY_SIZE(pwm2_pins[2]),
+		.modemuxs = pwm2_pin_29_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm2_pin_29_modemux),
+	}, {
+		.name = "pwm2_pin_34_grp",
+		.pins = pwm2_pins[3],
+		.npins = ARRAY_SIZE(pwm2_pins[3]),
+		.modemuxs = pwm2_pin_34_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm2_pin_34_modemux),
+	}, {
+		.name = "pwm2_pin_41_grp",
+		.pins = pwm2_pins[4],
+		.npins = ARRAY_SIZE(pwm2_pins[4]),
+		.modemuxs = pwm2_pin_41_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm2_pin_41_modemux),
+	}, {
+		.name = "pwm2_pin_58_grp",
+		.pins = pwm2_pins[5],
+		.npins = ARRAY_SIZE(pwm2_pins[5]),
+		.modemuxs = pwm2_pin_58_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm2_pin_58_modemux),
+	}, {
+		.name = "pwm2_pin_87_grp",
+		.pins = pwm2_pins[6],
+		.npins = ARRAY_SIZE(pwm2_pins[6]),
+		.modemuxs = pwm2_pin_87_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm2_pin_87_modemux),
+	},
+};
+
+static const char *const pwm2_grps[] = { "pwm2_pin_7_grp", "pwm2_pin_13_grp",
+	"pwm2_pin_29_grp", "pwm2_pin_34_grp", "pwm2_pin_41_grp",
+	"pwm2_pin_58_grp", "pwm2_pin_87_grp" };
+static struct spear_function pwm2_function = {
+	.name = "pwm2",
+	.groups = pwm2_grps,
+	.ngroups = ARRAY_SIZE(pwm2_grps),
+};
+
+/* Pad multiplexing for PWM3 device */
+static const unsigned pwm3_pins[][1] = { { 6 }, { 12 }, { 28 }, { 40 }, { 57 },
+	{ 86 } };
+static struct spear_muxreg pwm3_pin_6_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_6_MASK,
+		.val = PMX_PWM_3_PL_6_VAL,
+	},
+};
+
+static struct spear_muxreg pwm3_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg pwm3_pin_12_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_12_MASK,
+		.val = PMX_PWM3_PL_12_VAL,
+	},
+};
+
+static struct spear_muxreg pwm3_pin_28_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_GPIO_PIN0_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_20_29_REG,
+		.mask = PMX_PL_28_MASK,
+		.val = PMX_PWM_3_PL_28_VAL,
+	},
+};
+
+static struct spear_muxreg pwm3_pin_40_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_40_MASK,
+		.val = PMX_PWM3_PL_40_VAL,
+	},
+};
+
+static struct spear_muxreg pwm3_pin_57_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_50_59_REG,
+		.mask = PMX_PL_57_MASK,
+		.val = PMX_PWM3_PL_57_VAL,
+	},
+};
+
+static struct spear_muxreg pwm3_pin_86_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_80_89_REG,
+		.mask = PMX_PL_86_MASK,
+		.val = PMX_PWM3_PL_86_VAL,
+	},
+};
+
+static struct spear_modemux pwm3_pin_6_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm3_pin_6_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm3_pin_6_muxreg),
+	},
+};
+
+static struct spear_modemux pwm3_pin_12_modemux[] = {
+	{
+		.modes = AUTO_EXP_MODE | SMALL_PRINTERS_MODE |
+			AUTO_NET_SMII_MODE | EXTENDED_MODE,
+		.muxregs = pwm3_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm3_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm3_pin_12_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm3_pin_12_muxreg),
+	},
+};
+
+static struct spear_modemux pwm3_pin_28_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm3_pin_28_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm3_pin_28_muxreg),
+	},
+};
+
+static struct spear_modemux pwm3_pin_40_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm3_pin_40_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm3_pin_40_muxreg),
+	},
+};
+
+static struct spear_modemux pwm3_pin_57_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm3_pin_57_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm3_pin_57_muxreg),
+	},
+};
+
+static struct spear_modemux pwm3_pin_86_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = pwm3_pin_86_muxreg,
+		.nmuxregs = ARRAY_SIZE(pwm3_pin_86_muxreg),
+	},
+};
+
+static struct spear_pingroup pwm3_pingroup[] = {
+	{
+		.name = "pwm3_pin_6_grp",
+		.pins = pwm3_pins[0],
+		.npins = ARRAY_SIZE(pwm3_pins[0]),
+		.modemuxs = pwm3_pin_6_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm3_pin_6_modemux),
+	}, {
+		.name = "pwm3_pin_12_grp",
+		.pins = pwm3_pins[1],
+		.npins = ARRAY_SIZE(pwm3_pins[1]),
+		.modemuxs = pwm3_pin_12_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm3_pin_12_modemux),
+	}, {
+		.name = "pwm3_pin_28_grp",
+		.pins = pwm3_pins[2],
+		.npins = ARRAY_SIZE(pwm3_pins[2]),
+		.modemuxs = pwm3_pin_28_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm3_pin_28_modemux),
+	}, {
+		.name = "pwm3_pin_40_grp",
+		.pins = pwm3_pins[3],
+		.npins = ARRAY_SIZE(pwm3_pins[3]),
+		.modemuxs = pwm3_pin_40_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm3_pin_40_modemux),
+	}, {
+		.name = "pwm3_pin_57_grp",
+		.pins = pwm3_pins[4],
+		.npins = ARRAY_SIZE(pwm3_pins[4]),
+		.modemuxs = pwm3_pin_57_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm3_pin_57_modemux),
+	}, {
+		.name = "pwm3_pin_86_grp",
+		.pins = pwm3_pins[5],
+		.npins = ARRAY_SIZE(pwm3_pins[5]),
+		.modemuxs = pwm3_pin_86_modemux,
+		.nmodemuxs = ARRAY_SIZE(pwm3_pin_86_modemux),
+	},
+};
+
+static const char *const pwm3_grps[] = { "pwm3_pin_6_grp", "pwm3_pin_12_grp",
+	"pwm3_pin_28_grp", "pwm3_pin_40_grp", "pwm3_pin_57_grp",
+	"pwm3_pin_86_grp" };
+static struct spear_function pwm3_function = {
+	.name = "pwm3",
+	.groups = pwm3_grps,
+	.ngroups = ARRAY_SIZE(pwm3_grps),
+};
+
+/* Pad multiplexing for SSP1 device */
+static const unsigned ssp1_pins[][2] = { { 17, 20 }, { 36, 39 }, { 48, 51 },
+	{ 65, 68 }, { 94, 97 } };
+static struct spear_muxreg ssp1_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg ssp1_ext_17_20_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_17_18_MASK | PMX_PL_19_MASK,
+		.val = PMX_SSP1_PL_17_18_19_20_VAL,
+	}, {
+		.reg = IP_SEL_PAD_20_29_REG,
+		.mask = PMX_PL_20_MASK,
+		.val = PMX_SSP1_PL_17_18_19_20_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP1_PORT_SEL_MASK,
+		.val = PMX_SSP1_PORT_17_TO_20_VAL,
+	},
+};
+
+static struct spear_muxreg ssp1_ext_36_39_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_36_MASK | PMX_PL_37_38_MASK | PMX_PL_39_MASK,
+		.val = PMX_SSP1_PL_36_VAL | PMX_SSP1_PL_37_38_VAL |
+			PMX_SSP1_PL_39_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP1_PORT_SEL_MASK,
+		.val = PMX_SSP1_PORT_36_TO_39_VAL,
+	},
+};
+
+static struct spear_muxreg ssp1_ext_48_51_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_48_49_MASK,
+		.val = PMX_SSP1_PL_48_49_VAL,
+	}, {
+		.reg = IP_SEL_PAD_50_59_REG,
+		.mask = PMX_PL_50_51_MASK,
+		.val = PMX_SSP1_PL_50_51_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP1_PORT_SEL_MASK,
+		.val = PMX_SSP1_PORT_48_TO_51_VAL,
+	},
+};
+
+static struct spear_muxreg ssp1_ext_65_68_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_60_69_REG,
+		.mask = PMX_PL_65_TO_68_MASK,
+		.val = PMX_SSP1_PL_65_TO_68_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP1_PORT_SEL_MASK,
+		.val = PMX_SSP1_PORT_65_TO_68_VAL,
+	},
+};
+
+static struct spear_muxreg ssp1_ext_94_97_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_94_95_MASK | PMX_PL_96_97_MASK,
+		.val = PMX_SSP1_PL_94_95_VAL | PMX_SSP1_PL_96_97_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP1_PORT_SEL_MASK,
+		.val = PMX_SSP1_PORT_94_TO_97_VAL,
+	},
+};
+
+static struct spear_modemux ssp1_17_20_modemux[] = {
+	{
+		.modes = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE |
+			EXTENDED_MODE,
+		.muxregs = ssp1_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp1_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp1_ext_17_20_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp1_ext_17_20_muxreg),
+	},
+};
+
+static struct spear_modemux ssp1_36_39_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp1_ext_36_39_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp1_ext_36_39_muxreg),
+	},
+};
+
+static struct spear_modemux ssp1_48_51_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp1_ext_48_51_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp1_ext_48_51_muxreg),
+	},
+};
+static struct spear_modemux ssp1_65_68_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp1_ext_65_68_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp1_ext_65_68_muxreg),
+	},
+};
+
+static struct spear_modemux ssp1_94_97_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp1_ext_94_97_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp1_ext_94_97_muxreg),
+	},
+};
+
+static struct spear_pingroup ssp1_pingroup[] = {
+	{
+		.name = "ssp1_17_20_grp",
+		.pins = ssp1_pins[0],
+		.npins = ARRAY_SIZE(ssp1_pins[0]),
+		.modemuxs = ssp1_17_20_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp1_17_20_modemux),
+	}, {
+		.name = "ssp1_36_39_grp",
+		.pins = ssp1_pins[1],
+		.npins = ARRAY_SIZE(ssp1_pins[1]),
+		.modemuxs = ssp1_36_39_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp1_36_39_modemux),
+	}, {
+		.name = "ssp1_48_51_grp",
+		.pins = ssp1_pins[2],
+		.npins = ARRAY_SIZE(ssp1_pins[2]),
+		.modemuxs = ssp1_48_51_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp1_48_51_modemux),
+	}, {
+		.name = "ssp1_65_68_grp",
+		.pins = ssp1_pins[3],
+		.npins = ARRAY_SIZE(ssp1_pins[3]),
+		.modemuxs = ssp1_65_68_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp1_65_68_modemux),
+	}, {
+		.name = "ssp1_94_97_grp",
+		.pins = ssp1_pins[4],
+		.npins = ARRAY_SIZE(ssp1_pins[4]),
+		.modemuxs = ssp1_94_97_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp1_94_97_modemux),
+	},
+};
+
+static const char *const ssp1_grps[] = { "ssp1_17_20_grp", "ssp1_36_39_grp",
+	"ssp1_48_51_grp", "ssp1_65_68_grp", "ssp1_94_97_grp"
+};
+static struct spear_function ssp1_function = {
+	.name = "ssp1",
+	.groups = ssp1_grps,
+	.ngroups = ARRAY_SIZE(ssp1_grps),
+};
+
+/* Pad multiplexing for SSP2 device */
+static const unsigned ssp2_pins[][2] = { { 13, 16 }, { 32, 35 }, { 44, 47 },
+	{ 61, 64 }, { 90, 93 } };
+static struct spear_muxreg ssp2_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg ssp2_ext_13_16_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_13_14_MASK | PMX_PL_15_16_MASK,
+		.val = PMX_SSP2_PL_13_14_15_16_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP2_PORT_SEL_MASK,
+		.val = PMX_SSP2_PORT_13_TO_16_VAL,
+	},
+};
+
+static struct spear_muxreg ssp2_ext_32_35_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_CS_MASK | PMX_GPIO_PIN4_MASK |
+			PMX_GPIO_PIN5_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_30_39_REG,
+		.mask = PMX_PL_32_33_MASK | PMX_PL_34_MASK | PMX_PL_35_MASK,
+		.val = PMX_SSP2_PL_32_33_VAL | PMX_SSP2_PL_34_VAL |
+			PMX_SSP2_PL_35_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP2_PORT_SEL_MASK,
+		.val = PMX_SSP2_PORT_32_TO_35_VAL,
+	},
+};
+
+static struct spear_muxreg ssp2_ext_44_47_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_40_49_REG,
+		.mask = PMX_PL_44_45_MASK | PMX_PL_46_47_MASK,
+		.val = PMX_SSP2_PL_44_45_VAL | PMX_SSP2_PL_46_47_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP2_PORT_SEL_MASK,
+		.val = PMX_SSP2_PORT_44_TO_47_VAL,
+	},
+};
+
+static struct spear_muxreg ssp2_ext_61_64_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_60_69_REG,
+		.mask = PMX_PL_61_TO_64_MASK,
+		.val = PMX_SSP2_PL_61_TO_64_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP2_PORT_SEL_MASK,
+		.val = PMX_SSP2_PORT_61_TO_64_VAL,
+	},
+};
+
+static struct spear_muxreg ssp2_ext_90_93_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK,
+		.val = PMX_SSP2_PL_90_91_VAL | PMX_SSP2_PL_92_93_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_SSP2_PORT_SEL_MASK,
+		.val = PMX_SSP2_PORT_90_TO_93_VAL,
+	},
+};
+
+static struct spear_modemux ssp2_13_16_modemux[] = {
+	{
+		.modes = AUTO_NET_SMII_MODE | EXTENDED_MODE,
+		.muxregs = ssp2_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp2_muxreg),
+	}, {
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp2_ext_13_16_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp2_ext_13_16_muxreg),
+	},
+};
+
+static struct spear_modemux ssp2_32_35_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp2_ext_32_35_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp2_ext_32_35_muxreg),
+	},
+};
+
+static struct spear_modemux ssp2_44_47_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp2_ext_44_47_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp2_ext_44_47_muxreg),
+	},
+};
+
+static struct spear_modemux ssp2_61_64_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp2_ext_61_64_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp2_ext_61_64_muxreg),
+	},
+};
+
+static struct spear_modemux ssp2_90_93_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = ssp2_ext_90_93_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp2_ext_90_93_muxreg),
+	},
+};
+
+static struct spear_pingroup ssp2_pingroup[] = {
+	{
+		.name = "ssp2_13_16_grp",
+		.pins = ssp2_pins[0],
+		.npins = ARRAY_SIZE(ssp2_pins[0]),
+		.modemuxs = ssp2_13_16_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp2_13_16_modemux),
+	}, {
+		.name = "ssp2_32_35_grp",
+		.pins = ssp2_pins[1],
+		.npins = ARRAY_SIZE(ssp2_pins[1]),
+		.modemuxs = ssp2_32_35_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp2_32_35_modemux),
+	}, {
+		.name = "ssp2_44_47_grp",
+		.pins = ssp2_pins[2],
+		.npins = ARRAY_SIZE(ssp2_pins[2]),
+		.modemuxs = ssp2_44_47_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp2_44_47_modemux),
+	}, {
+		.name = "ssp2_61_64_grp",
+		.pins = ssp2_pins[3],
+		.npins = ARRAY_SIZE(ssp2_pins[3]),
+		.modemuxs = ssp2_61_64_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp2_61_64_modemux),
+	}, {
+		.name = "ssp2_90_93_grp",
+		.pins = ssp2_pins[4],
+		.npins = ARRAY_SIZE(ssp2_pins[4]),
+		.modemuxs = ssp2_90_93_modemux,
+		.nmodemuxs = ARRAY_SIZE(ssp2_90_93_modemux),
+	},
+};
+
+static const char *const ssp2_grps[] = { "ssp2_13_16_grp", "ssp2_32_35_grp",
+	"ssp2_44_47_grp", "ssp2_61_64_grp", "ssp2_90_93_grp" };
+static struct spear_function ssp2_function = {
+	.name = "ssp2",
+	.groups = ssp2_grps,
+	.ngroups = ARRAY_SIZE(ssp2_grps),
+};
+
+/* Pad multiplexing for cadence mii2 as mii device */
+static const unsigned mii2_pins[] = { 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+	90, 91, 92, 93, 94, 95, 96, 97 };
+static struct spear_muxreg mii2_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_80_89_REG,
+		.mask = PMX_PL_80_TO_85_MASK | PMX_PL_86_87_MASK |
+			PMX_PL_88_89_MASK,
+		.val = PMX_MII2_PL_80_TO_85_VAL | PMX_MII2_PL_86_87_VAL |
+			PMX_MII2_PL_88_89_VAL,
+	}, {
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK |
+			PMX_PL_94_95_MASK | PMX_PL_96_97_MASK,
+		.val = PMX_MII2_PL_90_91_VAL | PMX_MII2_PL_92_93_VAL |
+			PMX_MII2_PL_94_95_VAL | PMX_MII2_PL_96_97_VAL,
+	}, {
+		.reg = EXT_CTRL_REG,
+		.mask = (MAC_MODE_MASK << MAC2_MODE_SHIFT) |
+			(MAC_MODE_MASK << MAC1_MODE_SHIFT) |
+			MII_MDIO_MASK,
+		.val = (MAC_MODE_MII << MAC2_MODE_SHIFT) |
+			(MAC_MODE_MII << MAC1_MODE_SHIFT) |
+			MII_MDIO_81_VAL,
+	},
+};
+
+static struct spear_modemux mii2_modemux[] = {
+	{
+		.modes = EXTENDED_MODE,
+		.muxregs = mii2_muxreg,
+		.nmuxregs = ARRAY_SIZE(mii2_muxreg),
+	},
+};
+
+static struct spear_pingroup mii2_pingroup = {
+	.name = "mii2_grp",
+	.pins = mii2_pins,
+	.npins = ARRAY_SIZE(mii2_pins),
+	.modemuxs = mii2_modemux,
+	.nmodemuxs = ARRAY_SIZE(mii2_modemux),
+};
+
+static const char *const mii2_grps[] = { "mii2_grp" };
+static struct spear_function mii2_function = {
+	.name = "mii2",
+	.groups = mii2_grps,
+	.ngroups = ARRAY_SIZE(mii2_grps),
+};
+
+/* Pad multiplexing for cadence mii 1_2 as smii or rmii device */
+static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20,
+	21, 22, 23, 24, 25, 26, 27 };
+static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 };
+static struct spear_muxreg mii0_1_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	},
+};
+
+static struct spear_muxreg smii0_1_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_10_11_MASK,
+		.val = PMX_SMII_PL_10_11_VAL,
+	}, {
+		.reg = IP_SEL_PAD_20_29_REG,
+		.mask = PMX_PL_21_TO_27_MASK,
+		.val = PMX_SMII_PL_21_TO_27_VAL,
+	}, {
+		.reg = EXT_CTRL_REG,
+		.mask = (MAC_MODE_MASK << MAC2_MODE_SHIFT) |
+			(MAC_MODE_MASK << MAC1_MODE_SHIFT) |
+			MII_MDIO_MASK,
+		.val = (MAC_MODE_SMII << MAC2_MODE_SHIFT)
+			| (MAC_MODE_SMII << MAC1_MODE_SHIFT)
+			| MII_MDIO_10_11_VAL,
+	},
+};
+
+static struct spear_muxreg rmii0_1_ext_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_10_11_MASK | PMX_PL_13_14_MASK |
+			PMX_PL_15_16_MASK | PMX_PL_17_18_MASK | PMX_PL_19_MASK,
+		.val = PMX_RMII_PL_10_11_VAL | PMX_RMII_PL_13_14_VAL |
+			PMX_RMII_PL_15_16_VAL | PMX_RMII_PL_17_18_VAL |
+			PMX_RMII_PL_19_VAL,
+	}, {
+		.reg = IP_SEL_PAD_20_29_REG,
+		.mask = PMX_PL_20_MASK | PMX_PL_21_TO_27_MASK,
+		.val = PMX_RMII_PL_20_VAL | PMX_RMII_PL_21_TO_27_VAL,
+	}, {
+		.reg = EXT_CTRL_REG,
+		.mask = (MAC_MODE_MASK << MAC2_MODE_SHIFT) |
+			(MAC_MODE_MASK << MAC1_MODE_SHIFT) |
+			MII_MDIO_MASK,
+		.val = (MAC_MODE_RMII << MAC2_MODE_SHIFT)
+			| (MAC_MODE_RMII << MAC1_MODE_SHIFT)
+			| MII_MDIO_10_11_VAL,
+	},
+};
+
+static struct spear_modemux mii0_1_modemux[][2] = {
+	{
+		/* configure as smii */
+		{
+			.modes = AUTO_NET_SMII_MODE | AUTO_EXP_MODE |
+				SMALL_PRINTERS_MODE | EXTENDED_MODE,
+			.muxregs = mii0_1_muxreg,
+			.nmuxregs = ARRAY_SIZE(mii0_1_muxreg),
+		}, {
+			.modes = EXTENDED_MODE,
+			.muxregs = smii0_1_ext_muxreg,
+			.nmuxregs = ARRAY_SIZE(smii0_1_ext_muxreg),
+		},
+	}, {
+		/* configure as rmii */
+		{
+			.modes = AUTO_NET_SMII_MODE | AUTO_EXP_MODE |
+				SMALL_PRINTERS_MODE | EXTENDED_MODE,
+			.muxregs = mii0_1_muxreg,
+			.nmuxregs = ARRAY_SIZE(mii0_1_muxreg),
+		}, {
+			.modes = EXTENDED_MODE,
+			.muxregs = rmii0_1_ext_muxreg,
+			.nmuxregs = ARRAY_SIZE(rmii0_1_ext_muxreg),
+		},
+	},
+};
+
+static struct spear_pingroup mii0_1_pingroup[] = {
+	{
+		.name = "smii0_1_grp",
+		.pins = smii0_1_pins,
+		.npins = ARRAY_SIZE(smii0_1_pins),
+		.modemuxs = mii0_1_modemux[0],
+		.nmodemuxs = ARRAY_SIZE(mii0_1_modemux[0]),
+	}, {
+		.name = "rmii0_1_grp",
+		.pins = rmii0_1_pins,
+		.npins = ARRAY_SIZE(rmii0_1_pins),
+		.modemuxs = mii0_1_modemux[1],
+		.nmodemuxs = ARRAY_SIZE(mii0_1_modemux[1]),
+	},
+};
+
+static const char *const mii0_1_grps[] = { "smii0_1_grp", "rmii0_1_grp" };
+static struct spear_function mii0_1_function = {
+	.name = "mii0_1",
+	.groups = mii0_1_grps,
+	.ngroups = ARRAY_SIZE(mii0_1_grps),
+};
+
+/* Pad multiplexing for i2c1 device */
+static const unsigned i2c1_pins[][2] = { { 8, 9 }, { 98, 99 } };
+static struct spear_muxreg i2c1_ext_8_9_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_SSP_CS_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_8_9_MASK,
+		.val = PMX_I2C1_PL_8_9_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_I2C1_PORT_SEL_MASK,
+		.val = PMX_I2C1_PORT_8_9_VAL,
+	},
+};
+
+static struct spear_muxreg i2c1_ext_98_99_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_98_MASK | PMX_PL_99_MASK,
+		.val = PMX_I2C1_PL_98_VAL | PMX_I2C1_PL_99_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_I2C1_PORT_SEL_MASK,
+		.val = PMX_I2C1_PORT_98_99_VAL,
+	},
+};
+
+static struct spear_modemux i2c1_modemux[][1] = {
+	{
+		/* Select signals on pins 8-9 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = i2c1_ext_8_9_muxreg,
+			.nmuxregs = ARRAY_SIZE(i2c1_ext_8_9_muxreg),
+		},
+	}, {
+		/* Select signals on pins 98-99 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = i2c1_ext_98_99_muxreg,
+			.nmuxregs = ARRAY_SIZE(i2c1_ext_98_99_muxreg),
+		},
+	},
+};
+
+static struct spear_pingroup i2c1_pingroup[] = {
+	{
+		.name = "i2c1_8_9_grp",
+		.pins = i2c1_pins[0],
+		.npins = ARRAY_SIZE(i2c1_pins[0]),
+		.modemuxs = i2c1_modemux[0],
+		.nmodemuxs = ARRAY_SIZE(i2c1_modemux[0]),
+	}, {
+		.name = "i2c1_98_99_grp",
+		.pins = i2c1_pins[1],
+		.npins = ARRAY_SIZE(i2c1_pins[1]),
+		.modemuxs = i2c1_modemux[1],
+		.nmodemuxs = ARRAY_SIZE(i2c1_modemux[1]),
+	},
+};
+
+static const char *const i2c1_grps[] = { "i2c1_8_9_grp", "i2c1_98_99_grp" };
+static struct spear_function i2c1_function = {
+	.name = "i2c1",
+	.groups = i2c1_grps,
+	.ngroups = ARRAY_SIZE(i2c1_grps),
+};
+
+/* Pad multiplexing for i2c2 device */
+static const unsigned i2c2_pins[][2] = { { 0, 1 }, { 2, 3 }, { 19, 20 },
+	{ 75, 76 }, { 96, 97 } };
+static struct spear_muxreg i2c2_ext_0_1_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_FIRDA_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_0_1_MASK,
+		.val = PMX_I2C2_PL_0_1_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_I2C2_PORT_SEL_MASK,
+		.val = PMX_I2C2_PORT_0_1_VAL,
+	},
+};
+
+static struct spear_muxreg i2c2_ext_2_3_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_UART0_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_0_9_REG,
+		.mask = PMX_PL_2_3_MASK,
+		.val = PMX_I2C2_PL_2_3_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_I2C2_PORT_SEL_MASK,
+		.val = PMX_I2C2_PORT_2_3_VAL,
+	},
+};
+
+static struct spear_muxreg i2c2_ext_19_20_muxreg[] = {
+	{
+		.reg = PMX_CONFIG_REG,
+		.mask = PMX_MII_MASK,
+		.val = 0,
+	}, {
+		.reg = IP_SEL_PAD_10_19_REG,
+		.mask = PMX_PL_19_MASK,
+		.val = PMX_I2C2_PL_19_VAL,
+	}, {
+		.reg = IP_SEL_PAD_20_29_REG,
+		.mask = PMX_PL_20_MASK,
+		.val = PMX_I2C2_PL_20_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_I2C2_PORT_SEL_MASK,
+		.val = PMX_I2C2_PORT_19_20_VAL,
+	},
+};
+
+static struct spear_muxreg i2c2_ext_75_76_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_70_79_REG,
+		.mask = PMX_PL_75_76_MASK,
+		.val = PMX_I2C2_PL_75_76_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_I2C2_PORT_SEL_MASK,
+		.val = PMX_I2C2_PORT_75_76_VAL,
+	},
+};
+
+static struct spear_muxreg i2c2_ext_96_97_muxreg[] = {
+	{
+		.reg = IP_SEL_PAD_90_99_REG,
+		.mask = PMX_PL_96_97_MASK,
+		.val = PMX_I2C2_PL_96_97_VAL,
+	}, {
+		.reg = IP_SEL_MIX_PAD_REG,
+		.mask = PMX_I2C2_PORT_SEL_MASK,
+		.val = PMX_I2C2_PORT_96_97_VAL,
+	},
+};
+
+static struct spear_modemux i2c2_modemux[][1] = {
+	{
+		/* Select signals on pins 0_1 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = i2c2_ext_0_1_muxreg,
+			.nmuxregs = ARRAY_SIZE(i2c2_ext_0_1_muxreg),
+		},
+	}, {
+		/* Select signals on pins 2_3 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = i2c2_ext_2_3_muxreg,
+			.nmuxregs = ARRAY_SIZE(i2c2_ext_2_3_muxreg),
+		},
+	}, {
+		/* Select signals on pins 19_20 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = i2c2_ext_19_20_muxreg,
+			.nmuxregs = ARRAY_SIZE(i2c2_ext_19_20_muxreg),
+		},
+	}, {
+		/* Select signals on pins 75_76 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = i2c2_ext_75_76_muxreg,
+			.nmuxregs = ARRAY_SIZE(i2c2_ext_75_76_muxreg),
+		},
+	}, {
+		/* Select signals on pins 96_97 */
+		{
+			.modes = EXTENDED_MODE,
+			.muxregs = i2c2_ext_96_97_muxreg,
+			.nmuxregs = ARRAY_SIZE(i2c2_ext_96_97_muxreg),
+		},
+	},
+};
+
+static struct spear_pingroup i2c2_pingroup[] = {
+	{
+		.name = "i2c2_0_1_grp",
+		.pins = i2c2_pins[0],
+		.npins = ARRAY_SIZE(i2c2_pins[0]),
+		.modemuxs = i2c2_modemux[0],
+		.nmodemuxs = ARRAY_SIZE(i2c2_modemux[0]),
+	}, {
+		.name = "i2c2_2_3_grp",
+		.pins = i2c2_pins[1],
+		.npins = ARRAY_SIZE(i2c2_pins[1]),
+		.modemuxs = i2c2_modemux[1],
+		.nmodemuxs = ARRAY_SIZE(i2c2_modemux[1]),
+	}, {
+		.name = "i2c2_19_20_grp",
+		.pins = i2c2_pins[2],
+		.npins = ARRAY_SIZE(i2c2_pins[2]),
+		.modemuxs = i2c2_modemux[2],
+		.nmodemuxs = ARRAY_SIZE(i2c2_modemux[2]),
+	}, {
+		.name = "i2c2_75_76_grp",
+		.pins = i2c2_pins[3],
+		.npins = ARRAY_SIZE(i2c2_pins[3]),
+		.modemuxs = i2c2_modemux[3],
+		.nmodemuxs = ARRAY_SIZE(i2c2_modemux[3]),
+	}, {
+		.name = "i2c2_96_97_grp",
+		.pins = i2c2_pins[4],
+		.npins = ARRAY_SIZE(i2c2_pins[4]),
+		.modemuxs = i2c2_modemux[4],
+		.nmodemuxs = ARRAY_SIZE(i2c2_modemux[4]),
+	},
+};
+
+static const char *const i2c2_grps[] = { "i2c2_0_1_grp", "i2c2_2_3_grp",
+	"i2c2_19_20_grp", "i2c2_75_76_grp", "i2c2_96_97_grp" };
+static struct spear_function i2c2_function = {
+	.name = "i2c2",
+	.groups = i2c2_grps,
+	.ngroups = ARRAY_SIZE(i2c2_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear320_pingroups[] = {
+	SPEAR3XX_COMMON_PINGROUPS,
+	&clcd_pingroup,
+	&emi_pingroup,
+	&fsmc_8bit_pingroup,
+	&fsmc_16bit_pingroup,
+	&spp_pingroup,
+	&sdhci_led_pingroup,
+	&sdhci_pingroup[0],
+	&sdhci_pingroup[1],
+	&i2s_pingroup,
+	&uart1_pingroup,
+	&uart1_modem_pingroup[0],
+	&uart1_modem_pingroup[1],
+	&uart1_modem_pingroup[2],
+	&uart1_modem_pingroup[3],
+	&uart2_pingroup,
+	&uart3_pingroup[0],
+	&uart3_pingroup[1],
+	&uart3_pingroup[2],
+	&uart3_pingroup[3],
+	&uart3_pingroup[4],
+	&uart3_pingroup[5],
+	&uart3_pingroup[6],
+	&uart4_pingroup[0],
+	&uart4_pingroup[1],
+	&uart4_pingroup[2],
+	&uart4_pingroup[3],
+	&uart4_pingroup[4],
+	&uart4_pingroup[5],
+	&uart5_pingroup[0],
+	&uart5_pingroup[1],
+	&uart5_pingroup[2],
+	&uart5_pingroup[3],
+	&uart6_pingroup[0],
+	&uart6_pingroup[1],
+	&rs485_pingroup,
+	&touchscreen_pingroup,
+	&can0_pingroup,
+	&can1_pingroup,
+	&pwm0_1_pingroup[0],
+	&pwm0_1_pingroup[1],
+	&pwm0_1_pingroup[2],
+	&pwm0_1_pingroup[3],
+	&pwm0_1_pingroup[4],
+	&pwm0_1_pingroup[5],
+	&pwm0_1_pingroup[6],
+	&pwm2_pingroup[0],
+	&pwm2_pingroup[1],
+	&pwm2_pingroup[2],
+	&pwm2_pingroup[3],
+	&pwm2_pingroup[4],
+	&pwm2_pingroup[5],
+	&pwm2_pingroup[6],
+	&pwm3_pingroup[0],
+	&pwm3_pingroup[1],
+	&pwm3_pingroup[2],
+	&pwm3_pingroup[3],
+	&pwm3_pingroup[4],
+	&pwm3_pingroup[5],
+	&ssp1_pingroup[0],
+	&ssp1_pingroup[1],
+	&ssp1_pingroup[2],
+	&ssp1_pingroup[3],
+	&ssp1_pingroup[4],
+	&ssp2_pingroup[0],
+	&ssp2_pingroup[1],
+	&ssp2_pingroup[2],
+	&ssp2_pingroup[3],
+	&ssp2_pingroup[4],
+	&mii2_pingroup,
+	&mii0_1_pingroup[0],
+	&mii0_1_pingroup[1],
+	&i2c1_pingroup[0],
+	&i2c1_pingroup[1],
+	&i2c2_pingroup[0],
+	&i2c2_pingroup[1],
+	&i2c2_pingroup[2],
+	&i2c2_pingroup[3],
+	&i2c2_pingroup[4],
+};
+
+/* functions */
+static struct spear_function *spear320_functions[] = {
+	SPEAR3XX_COMMON_FUNCTIONS,
+	&clcd_function,
+	&emi_function,
+	&fsmc_function,
+	&spp_function,
+	&sdhci_function,
+	&i2s_function,
+	&uart1_function,
+	&uart1_modem_function,
+	&uart2_function,
+	&uart3_function,
+	&uart4_function,
+	&uart5_function,
+	&uart6_function,
+	&rs485_function,
+	&touchscreen_function,
+	&can0_function,
+	&can1_function,
+	&pwm0_1_function,
+	&pwm2_function,
+	&pwm3_function,
+	&ssp1_function,
+	&ssp2_function,
+	&mii2_function,
+	&mii0_1_function,
+	&i2c1_function,
+	&i2c2_function,
+};
+
+static struct of_device_id spear320_pinctrl_of_match[] __devinitdata = {
+	{
+		.compatible = "st,spear320-pinmux",
+	},
+	{},
+};
+
+static int __devinit spear320_pinctrl_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	spear3xx_machdata.groups = spear320_pingroups;
+	spear3xx_machdata.ngroups = ARRAY_SIZE(spear320_pingroups);
+	spear3xx_machdata.functions = spear320_functions;
+	spear3xx_machdata.nfunctions = ARRAY_SIZE(spear320_functions);
+
+	spear3xx_machdata.modes_supported = true;
+	spear3xx_machdata.pmx_modes = spear320_pmx_modes;
+	spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes);
+
+	pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+	ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int __devexit spear320_pinctrl_remove(struct platform_device *pdev)
+{
+	return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear320_pinctrl_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = spear320_pinctrl_of_match,
+	},
+	.probe = spear320_pinctrl_probe,
+	.remove = __devexit_p(spear320_pinctrl_remove),
+};
+
+static int __init spear320_pinctrl_init(void)
+{
+	return platform_driver_register(&spear320_pinctrl_driver);
+}
+arch_initcall(spear320_pinctrl_init);
+
+static void __exit spear320_pinctrl_exit(void)
+{
+	platform_driver_unregister(&spear320_pinctrl_driver);
+}
+module_exit(spear320_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c
new file mode 100644
index 0000000..832049a
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c
@@ -0,0 +1,588 @@
+/*
+ * Driver for the ST Microelectronics SPEAr3xx pinmux
+ *
+ * Copyright (C) 2012 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/pinctrl/pinctrl.h>
+
+#include "pinctrl-spear3xx.h"
+
+/* pins */
+static const struct pinctrl_pin_desc spear3xx_pins[] = {
+	PINCTRL_PIN(0, "PLGPIO0"),
+	PINCTRL_PIN(1, "PLGPIO1"),
+	PINCTRL_PIN(2, "PLGPIO2"),
+	PINCTRL_PIN(3, "PLGPIO3"),
+	PINCTRL_PIN(4, "PLGPIO4"),
+	PINCTRL_PIN(5, "PLGPIO5"),
+	PINCTRL_PIN(6, "PLGPIO6"),
+	PINCTRL_PIN(7, "PLGPIO7"),
+	PINCTRL_PIN(8, "PLGPIO8"),
+	PINCTRL_PIN(9, "PLGPIO9"),
+	PINCTRL_PIN(10, "PLGPIO10"),
+	PINCTRL_PIN(11, "PLGPIO11"),
+	PINCTRL_PIN(12, "PLGPIO12"),
+	PINCTRL_PIN(13, "PLGPIO13"),
+	PINCTRL_PIN(14, "PLGPIO14"),
+	PINCTRL_PIN(15, "PLGPIO15"),
+	PINCTRL_PIN(16, "PLGPIO16"),
+	PINCTRL_PIN(17, "PLGPIO17"),
+	PINCTRL_PIN(18, "PLGPIO18"),
+	PINCTRL_PIN(19, "PLGPIO19"),
+	PINCTRL_PIN(20, "PLGPIO20"),
+	PINCTRL_PIN(21, "PLGPIO21"),
+	PINCTRL_PIN(22, "PLGPIO22"),
+	PINCTRL_PIN(23, "PLGPIO23"),
+	PINCTRL_PIN(24, "PLGPIO24"),
+	PINCTRL_PIN(25, "PLGPIO25"),
+	PINCTRL_PIN(26, "PLGPIO26"),
+	PINCTRL_PIN(27, "PLGPIO27"),
+	PINCTRL_PIN(28, "PLGPIO28"),
+	PINCTRL_PIN(29, "PLGPIO29"),
+	PINCTRL_PIN(30, "PLGPIO30"),
+	PINCTRL_PIN(31, "PLGPIO31"),
+	PINCTRL_PIN(32, "PLGPIO32"),
+	PINCTRL_PIN(33, "PLGPIO33"),
+	PINCTRL_PIN(34, "PLGPIO34"),
+	PINCTRL_PIN(35, "PLGPIO35"),
+	PINCTRL_PIN(36, "PLGPIO36"),
+	PINCTRL_PIN(37, "PLGPIO37"),
+	PINCTRL_PIN(38, "PLGPIO38"),
+	PINCTRL_PIN(39, "PLGPIO39"),
+	PINCTRL_PIN(40, "PLGPIO40"),
+	PINCTRL_PIN(41, "PLGPIO41"),
+	PINCTRL_PIN(42, "PLGPIO42"),
+	PINCTRL_PIN(43, "PLGPIO43"),
+	PINCTRL_PIN(44, "PLGPIO44"),
+	PINCTRL_PIN(45, "PLGPIO45"),
+	PINCTRL_PIN(46, "PLGPIO46"),
+	PINCTRL_PIN(47, "PLGPIO47"),
+	PINCTRL_PIN(48, "PLGPIO48"),
+	PINCTRL_PIN(49, "PLGPIO49"),
+	PINCTRL_PIN(50, "PLGPIO50"),
+	PINCTRL_PIN(51, "PLGPIO51"),
+	PINCTRL_PIN(52, "PLGPIO52"),
+	PINCTRL_PIN(53, "PLGPIO53"),
+	PINCTRL_PIN(54, "PLGPIO54"),
+	PINCTRL_PIN(55, "PLGPIO55"),
+	PINCTRL_PIN(56, "PLGPIO56"),
+	PINCTRL_PIN(57, "PLGPIO57"),
+	PINCTRL_PIN(58, "PLGPIO58"),
+	PINCTRL_PIN(59, "PLGPIO59"),
+	PINCTRL_PIN(60, "PLGPIO60"),
+	PINCTRL_PIN(61, "PLGPIO61"),
+	PINCTRL_PIN(62, "PLGPIO62"),
+	PINCTRL_PIN(63, "PLGPIO63"),
+	PINCTRL_PIN(64, "PLGPIO64"),
+	PINCTRL_PIN(65, "PLGPIO65"),
+	PINCTRL_PIN(66, "PLGPIO66"),
+	PINCTRL_PIN(67, "PLGPIO67"),
+	PINCTRL_PIN(68, "PLGPIO68"),
+	PINCTRL_PIN(69, "PLGPIO69"),
+	PINCTRL_PIN(70, "PLGPIO70"),
+	PINCTRL_PIN(71, "PLGPIO71"),
+	PINCTRL_PIN(72, "PLGPIO72"),
+	PINCTRL_PIN(73, "PLGPIO73"),
+	PINCTRL_PIN(74, "PLGPIO74"),
+	PINCTRL_PIN(75, "PLGPIO75"),
+	PINCTRL_PIN(76, "PLGPIO76"),
+	PINCTRL_PIN(77, "PLGPIO77"),
+	PINCTRL_PIN(78, "PLGPIO78"),
+	PINCTRL_PIN(79, "PLGPIO79"),
+	PINCTRL_PIN(80, "PLGPIO80"),
+	PINCTRL_PIN(81, "PLGPIO81"),
+	PINCTRL_PIN(82, "PLGPIO82"),
+	PINCTRL_PIN(83, "PLGPIO83"),
+	PINCTRL_PIN(84, "PLGPIO84"),
+	PINCTRL_PIN(85, "PLGPIO85"),
+	PINCTRL_PIN(86, "PLGPIO86"),
+	PINCTRL_PIN(87, "PLGPIO87"),
+	PINCTRL_PIN(88, "PLGPIO88"),
+	PINCTRL_PIN(89, "PLGPIO89"),
+	PINCTRL_PIN(90, "PLGPIO90"),
+	PINCTRL_PIN(91, "PLGPIO91"),
+	PINCTRL_PIN(92, "PLGPIO92"),
+	PINCTRL_PIN(93, "PLGPIO93"),
+	PINCTRL_PIN(94, "PLGPIO94"),
+	PINCTRL_PIN(95, "PLGPIO95"),
+	PINCTRL_PIN(96, "PLGPIO96"),
+	PINCTRL_PIN(97, "PLGPIO97"),
+	PINCTRL_PIN(98, "PLGPIO98"),
+	PINCTRL_PIN(99, "PLGPIO99"),
+	PINCTRL_PIN(100, "PLGPIO100"),
+	PINCTRL_PIN(101, "PLGPIO101"),
+};
+
+/* firda_pins */
+static const unsigned firda_pins[] = { 0, 1 };
+static struct spear_muxreg firda_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_FIRDA_MASK,
+		.val = PMX_FIRDA_MASK,
+	},
+};
+
+static struct spear_modemux firda_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = firda_muxreg,
+		.nmuxregs = ARRAY_SIZE(firda_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_firda_pingroup = {
+	.name = "firda_grp",
+	.pins = firda_pins,
+	.npins = ARRAY_SIZE(firda_pins),
+	.modemuxs = firda_modemux,
+	.nmodemuxs = ARRAY_SIZE(firda_modemux),
+};
+
+static const char *const firda_grps[] = { "firda_grp" };
+struct spear_function spear3xx_firda_function = {
+	.name = "firda",
+	.groups = firda_grps,
+	.ngroups = ARRAY_SIZE(firda_grps),
+};
+
+/* i2c_pins */
+static const unsigned i2c_pins[] = { 4, 5 };
+static struct spear_muxreg i2c_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_I2C_MASK,
+		.val = PMX_I2C_MASK,
+	},
+};
+
+static struct spear_modemux i2c_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = i2c_muxreg,
+		.nmuxregs = ARRAY_SIZE(i2c_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_i2c_pingroup = {
+	.name = "i2c0_grp",
+	.pins = i2c_pins,
+	.npins = ARRAY_SIZE(i2c_pins),
+	.modemuxs = i2c_modemux,
+	.nmodemuxs = ARRAY_SIZE(i2c_modemux),
+};
+
+static const char *const i2c_grps[] = { "i2c0_grp" };
+struct spear_function spear3xx_i2c_function = {
+	.name = "i2c0",
+	.groups = i2c_grps,
+	.ngroups = ARRAY_SIZE(i2c_grps),
+};
+
+/* ssp_cs_pins */
+static const unsigned ssp_cs_pins[] = { 34, 35, 36 };
+static struct spear_muxreg ssp_cs_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_SSP_CS_MASK,
+		.val = PMX_SSP_CS_MASK,
+	},
+};
+
+static struct spear_modemux ssp_cs_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = ssp_cs_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp_cs_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_ssp_cs_pingroup = {
+	.name = "ssp_cs_grp",
+	.pins = ssp_cs_pins,
+	.npins = ARRAY_SIZE(ssp_cs_pins),
+	.modemuxs = ssp_cs_modemux,
+	.nmodemuxs = ARRAY_SIZE(ssp_cs_modemux),
+};
+
+static const char *const ssp_cs_grps[] = { "ssp_cs_grp" };
+struct spear_function spear3xx_ssp_cs_function = {
+	.name = "ssp_cs",
+	.groups = ssp_cs_grps,
+	.ngroups = ARRAY_SIZE(ssp_cs_grps),
+};
+
+/* ssp_pins */
+static const unsigned ssp_pins[] = { 6, 7, 8, 9 };
+static struct spear_muxreg ssp_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_SSP_MASK,
+		.val = PMX_SSP_MASK,
+	},
+};
+
+static struct spear_modemux ssp_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = ssp_muxreg,
+		.nmuxregs = ARRAY_SIZE(ssp_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_ssp_pingroup = {
+	.name = "ssp0_grp",
+	.pins = ssp_pins,
+	.npins = ARRAY_SIZE(ssp_pins),
+	.modemuxs = ssp_modemux,
+	.nmodemuxs = ARRAY_SIZE(ssp_modemux),
+};
+
+static const char *const ssp_grps[] = { "ssp0_grp" };
+struct spear_function spear3xx_ssp_function = {
+	.name = "ssp0",
+	.groups = ssp_grps,
+	.ngroups = ARRAY_SIZE(ssp_grps),
+};
+
+/* mii_pins */
+static const unsigned mii_pins[] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+	21, 22, 23, 24, 25, 26, 27 };
+static struct spear_muxreg mii_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_MII_MASK,
+		.val = PMX_MII_MASK,
+	},
+};
+
+static struct spear_modemux mii_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = mii_muxreg,
+		.nmuxregs = ARRAY_SIZE(mii_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_mii_pingroup = {
+	.name = "mii0_grp",
+	.pins = mii_pins,
+	.npins = ARRAY_SIZE(mii_pins),
+	.modemuxs = mii_modemux,
+	.nmodemuxs = ARRAY_SIZE(mii_modemux),
+};
+
+static const char *const mii_grps[] = { "mii0_grp" };
+struct spear_function spear3xx_mii_function = {
+	.name = "mii0",
+	.groups = mii_grps,
+	.ngroups = ARRAY_SIZE(mii_grps),
+};
+
+/* gpio0_pin0_pins */
+static const unsigned gpio0_pin0_pins[] = { 28 };
+static struct spear_muxreg gpio0_pin0_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_GPIO_PIN0_MASK,
+		.val = PMX_GPIO_PIN0_MASK,
+	},
+};
+
+static struct spear_modemux gpio0_pin0_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = gpio0_pin0_muxreg,
+		.nmuxregs = ARRAY_SIZE(gpio0_pin0_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_gpio0_pin0_pingroup = {
+	.name = "gpio0_pin0_grp",
+	.pins = gpio0_pin0_pins,
+	.npins = ARRAY_SIZE(gpio0_pin0_pins),
+	.modemuxs = gpio0_pin0_modemux,
+	.nmodemuxs = ARRAY_SIZE(gpio0_pin0_modemux),
+};
+
+/* gpio0_pin1_pins */
+static const unsigned gpio0_pin1_pins[] = { 29 };
+static struct spear_muxreg gpio0_pin1_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_GPIO_PIN1_MASK,
+		.val = PMX_GPIO_PIN1_MASK,
+	},
+};
+
+static struct spear_modemux gpio0_pin1_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = gpio0_pin1_muxreg,
+		.nmuxregs = ARRAY_SIZE(gpio0_pin1_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_gpio0_pin1_pingroup = {
+	.name = "gpio0_pin1_grp",
+	.pins = gpio0_pin1_pins,
+	.npins = ARRAY_SIZE(gpio0_pin1_pins),
+	.modemuxs = gpio0_pin1_modemux,
+	.nmodemuxs = ARRAY_SIZE(gpio0_pin1_modemux),
+};
+
+/* gpio0_pin2_pins */
+static const unsigned gpio0_pin2_pins[] = { 30 };
+static struct spear_muxreg gpio0_pin2_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_GPIO_PIN2_MASK,
+		.val = PMX_GPIO_PIN2_MASK,
+	},
+};
+
+static struct spear_modemux gpio0_pin2_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = gpio0_pin2_muxreg,
+		.nmuxregs = ARRAY_SIZE(gpio0_pin2_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_gpio0_pin2_pingroup = {
+	.name = "gpio0_pin2_grp",
+	.pins = gpio0_pin2_pins,
+	.npins = ARRAY_SIZE(gpio0_pin2_pins),
+	.modemuxs = gpio0_pin2_modemux,
+	.nmodemuxs = ARRAY_SIZE(gpio0_pin2_modemux),
+};
+
+/* gpio0_pin3_pins */
+static const unsigned gpio0_pin3_pins[] = { 31 };
+static struct spear_muxreg gpio0_pin3_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_GPIO_PIN3_MASK,
+		.val = PMX_GPIO_PIN3_MASK,
+	},
+};
+
+static struct spear_modemux gpio0_pin3_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = gpio0_pin3_muxreg,
+		.nmuxregs = ARRAY_SIZE(gpio0_pin3_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_gpio0_pin3_pingroup = {
+	.name = "gpio0_pin3_grp",
+	.pins = gpio0_pin3_pins,
+	.npins = ARRAY_SIZE(gpio0_pin3_pins),
+	.modemuxs = gpio0_pin3_modemux,
+	.nmodemuxs = ARRAY_SIZE(gpio0_pin3_modemux),
+};
+
+/* gpio0_pin4_pins */
+static const unsigned gpio0_pin4_pins[] = { 32 };
+static struct spear_muxreg gpio0_pin4_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_GPIO_PIN4_MASK,
+		.val = PMX_GPIO_PIN4_MASK,
+	},
+};
+
+static struct spear_modemux gpio0_pin4_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = gpio0_pin4_muxreg,
+		.nmuxregs = ARRAY_SIZE(gpio0_pin4_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_gpio0_pin4_pingroup = {
+	.name = "gpio0_pin4_grp",
+	.pins = gpio0_pin4_pins,
+	.npins = ARRAY_SIZE(gpio0_pin4_pins),
+	.modemuxs = gpio0_pin4_modemux,
+	.nmodemuxs = ARRAY_SIZE(gpio0_pin4_modemux),
+};
+
+/* gpio0_pin5_pins */
+static const unsigned gpio0_pin5_pins[] = { 33 };
+static struct spear_muxreg gpio0_pin5_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_GPIO_PIN5_MASK,
+		.val = PMX_GPIO_PIN5_MASK,
+	},
+};
+
+static struct spear_modemux gpio0_pin5_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = gpio0_pin5_muxreg,
+		.nmuxregs = ARRAY_SIZE(gpio0_pin5_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_gpio0_pin5_pingroup = {
+	.name = "gpio0_pin5_grp",
+	.pins = gpio0_pin5_pins,
+	.npins = ARRAY_SIZE(gpio0_pin5_pins),
+	.modemuxs = gpio0_pin5_modemux,
+	.nmodemuxs = ARRAY_SIZE(gpio0_pin5_modemux),
+};
+
+static const char *const gpio0_grps[] = { "gpio0_pin0_grp", "gpio0_pin1_grp",
+	"gpio0_pin2_grp", "gpio0_pin3_grp", "gpio0_pin4_grp", "gpio0_pin5_grp",
+};
+struct spear_function spear3xx_gpio0_function = {
+	.name = "gpio0",
+	.groups = gpio0_grps,
+	.ngroups = ARRAY_SIZE(gpio0_grps),
+};
+
+/* uart0_ext_pins */
+static const unsigned uart0_ext_pins[] = { 37, 38, 39, 40, 41, 42 };
+static struct spear_muxreg uart0_ext_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_UART0_MODEM_MASK,
+		.val = PMX_UART0_MODEM_MASK,
+	},
+};
+
+static struct spear_modemux uart0_ext_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = uart0_ext_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart0_ext_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_uart0_ext_pingroup = {
+	.name = "uart0_ext_grp",
+	.pins = uart0_ext_pins,
+	.npins = ARRAY_SIZE(uart0_ext_pins),
+	.modemuxs = uart0_ext_modemux,
+	.nmodemuxs = ARRAY_SIZE(uart0_ext_modemux),
+};
+
+static const char *const uart0_ext_grps[] = { "uart0_ext_grp" };
+struct spear_function spear3xx_uart0_ext_function = {
+	.name = "uart0_ext",
+	.groups = uart0_ext_grps,
+	.ngroups = ARRAY_SIZE(uart0_ext_grps),
+};
+
+/* uart0_pins */
+static const unsigned uart0_pins[] = { 2, 3 };
+static struct spear_muxreg uart0_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_UART0_MASK,
+		.val = PMX_UART0_MASK,
+	},
+};
+
+static struct spear_modemux uart0_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = uart0_muxreg,
+		.nmuxregs = ARRAY_SIZE(uart0_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_uart0_pingroup = {
+	.name = "uart0_grp",
+	.pins = uart0_pins,
+	.npins = ARRAY_SIZE(uart0_pins),
+	.modemuxs = uart0_modemux,
+	.nmodemuxs = ARRAY_SIZE(uart0_modemux),
+};
+
+static const char *const uart0_grps[] = { "uart0_grp" };
+struct spear_function spear3xx_uart0_function = {
+	.name = "uart0",
+	.groups = uart0_grps,
+	.ngroups = ARRAY_SIZE(uart0_grps),
+};
+
+/* timer_0_1_pins */
+static const unsigned timer_0_1_pins[] = { 43, 44, 47, 48 };
+static struct spear_muxreg timer_0_1_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_TIMER_0_1_MASK,
+		.val = PMX_TIMER_0_1_MASK,
+	},
+};
+
+static struct spear_modemux timer_0_1_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = timer_0_1_muxreg,
+		.nmuxregs = ARRAY_SIZE(timer_0_1_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_timer_0_1_pingroup = {
+	.name = "timer_0_1_grp",
+	.pins = timer_0_1_pins,
+	.npins = ARRAY_SIZE(timer_0_1_pins),
+	.modemuxs = timer_0_1_modemux,
+	.nmodemuxs = ARRAY_SIZE(timer_0_1_modemux),
+};
+
+static const char *const timer_0_1_grps[] = { "timer_0_1_grp" };
+struct spear_function spear3xx_timer_0_1_function = {
+	.name = "timer_0_1",
+	.groups = timer_0_1_grps,
+	.ngroups = ARRAY_SIZE(timer_0_1_grps),
+};
+
+/* timer_2_3_pins */
+static const unsigned timer_2_3_pins[] = { 45, 46, 49, 50 };
+static struct spear_muxreg timer_2_3_muxreg[] = {
+	{
+		.reg = -1,
+		.mask = PMX_TIMER_2_3_MASK,
+		.val = PMX_TIMER_2_3_MASK,
+	},
+};
+
+static struct spear_modemux timer_2_3_modemux[] = {
+	{
+		.modes = ~0,
+		.muxregs = timer_2_3_muxreg,
+		.nmuxregs = ARRAY_SIZE(timer_2_3_muxreg),
+	},
+};
+
+struct spear_pingroup spear3xx_timer_2_3_pingroup = {
+	.name = "timer_2_3_grp",
+	.pins = timer_2_3_pins,
+	.npins = ARRAY_SIZE(timer_2_3_pins),
+	.modemuxs = timer_2_3_modemux,
+	.nmodemuxs = ARRAY_SIZE(timer_2_3_modemux),
+};
+
+static const char *const timer_2_3_grps[] = { "timer_2_3_grp" };
+struct spear_function spear3xx_timer_2_3_function = {
+	.name = "timer_2_3",
+	.groups = timer_2_3_grps,
+	.ngroups = ARRAY_SIZE(timer_2_3_grps),
+};
+
+struct spear_pinctrl_machdata spear3xx_machdata = {
+	.pins = spear3xx_pins,
+	.npins = ARRAY_SIZE(spear3xx_pins),
+};
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h
new file mode 100644
index 0000000..5d5fdd8
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h
@@ -0,0 +1,92 @@
+/*
+ * Header file for the ST Microelectronics SPEAr3xx pinmux
+ *
+ * Copyright (C) 2012 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 __PINMUX_SPEAR3XX_H__
+#define __PINMUX_SPEAR3XX_H__
+
+#include "pinctrl-spear.h"
+
+/* 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_2_3_MASK	(1 << 1)
+#define PMX_TIMER_0_1_MASK	(1 << 0)
+
+extern struct spear_pingroup spear3xx_firda_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin0_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin1_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin2_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin3_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin4_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin5_pingroup;
+extern struct spear_pingroup spear3xx_i2c_pingroup;
+extern struct spear_pingroup spear3xx_mii_pingroup;
+extern struct spear_pingroup spear3xx_ssp_cs_pingroup;
+extern struct spear_pingroup spear3xx_ssp_pingroup;
+extern struct spear_pingroup spear3xx_timer_0_1_pingroup;
+extern struct spear_pingroup spear3xx_timer_2_3_pingroup;
+extern struct spear_pingroup spear3xx_uart0_ext_pingroup;
+extern struct spear_pingroup spear3xx_uart0_pingroup;
+
+#define SPEAR3XX_COMMON_PINGROUPS		\
+	&spear3xx_firda_pingroup,		\
+	&spear3xx_gpio0_pin0_pingroup,		\
+	&spear3xx_gpio0_pin1_pingroup,		\
+	&spear3xx_gpio0_pin2_pingroup,		\
+	&spear3xx_gpio0_pin3_pingroup,		\
+	&spear3xx_gpio0_pin4_pingroup,		\
+	&spear3xx_gpio0_pin5_pingroup,		\
+	&spear3xx_i2c_pingroup,			\
+	&spear3xx_mii_pingroup,			\
+	&spear3xx_ssp_cs_pingroup,		\
+	&spear3xx_ssp_pingroup,			\
+	&spear3xx_timer_0_1_pingroup,		\
+	&spear3xx_timer_2_3_pingroup,		\
+	&spear3xx_uart0_ext_pingroup,		\
+	&spear3xx_uart0_pingroup
+
+extern struct spear_function spear3xx_firda_function;
+extern struct spear_function spear3xx_gpio0_function;
+extern struct spear_function spear3xx_i2c_function;
+extern struct spear_function spear3xx_mii_function;
+extern struct spear_function spear3xx_ssp_cs_function;
+extern struct spear_function spear3xx_ssp_function;
+extern struct spear_function spear3xx_timer_0_1_function;
+extern struct spear_function spear3xx_timer_2_3_function;
+extern struct spear_function spear3xx_uart0_ext_function;
+extern struct spear_function spear3xx_uart0_function;
+
+#define SPEAR3XX_COMMON_FUNCTIONS		\
+	&spear3xx_firda_function,		\
+	&spear3xx_gpio0_function,		\
+	&spear3xx_i2c_function,			\
+	&spear3xx_mii_function,			\
+	&spear3xx_ssp_cs_function,		\
+	&spear3xx_ssp_function,			\
+	&spear3xx_timer_0_1_function,		\
+	&spear3xx_timer_2_3_function,		\
+	&spear3xx_uart0_ext_function,		\
+	&spear3xx_uart0_function
+
+extern struct spear_pinctrl_machdata spear3xx_machdata;
+
+#endif /* __PINMUX_SPEAR3XX_H__ */
diff --git a/include/linux/clk.h b/include/linux/clk.h
index b025272..70cf722 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -101,6 +101,26 @@
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get - lookup and obtain a managed reference to a clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock comsumer ID
+ *
+ * Returns a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno.  The implementation
+ * uses @dev and @id to determine the clock consumer, and thereby
+ * the clock producer.  (IOW, @id may be identical strings, but
+ * clk_get may return different clock producers depending on @dev.)
+ *
+ * Drivers must assume that the clock source is not enabled.
+ *
+ * devm_clk_get should not be called from within interrupt context.
+ *
+ * The clock will automatically be freed when the device is unbound
+ * from the bus.
+ */
+struct clk *devm_clk_get(struct device *dev, const char *id);
+
+/**
  * clk_prepare - prepare a clock source
  * @clk: clock source
  *
@@ -206,6 +226,18 @@
  */
 void clk_put(struct clk *clk);
 
+/**
+ * devm_clk_put	- "free" a managed clock source
+ * @dev: device used to acuqire the clock
+ * @clk: clock source acquired with devm_clk_get()
+ *
+ * Note: drivers must ensure that all clk_enable calls made on this
+ * clock source are balanced by clk_disable calls prior to calling
+ * this function.
+ *
+ * clk_put should not be called from within interrupt context.
+ */
+void devm_clk_put(struct device *dev, struct clk *clk);
 
 /*
  * The remaining APIs are optional for machine class support.
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index d9a4fd0..a6a6f60 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -40,4 +40,7 @@
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, char *, struct device *);
 
+int clk_register_clkdev(struct clk *, const char *, const char *, ...);
+int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
+
 #endif